All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.codearte.accurest.util.JsonToJsonPathsConverter.groovy Maven / Gradle / Ivy

package io.codearte.accurest.util

import com.toomuchcoding.jsonassert.JsonAssertion
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import io.codearte.accurest.dsl.internal.ExecutionProperty
import io.codearte.accurest.dsl.internal.OptionalProperty

import java.util.regex.Pattern
/**
 * @author Marcin Grzejszczak
 */
class JsonToJsonPathsConverter {

	private static final Boolean SERVER_SIDE = false
	private static final Boolean CLIENT_SIDE = true

	public static JsonPaths transformToJsonPathWithTestsSideValues(def json) {
		return transformToJsonPathWithValues(json, SERVER_SIDE)
	}

	public static JsonPaths transformToJsonPathWithStubsSideValues(def json) {
		return transformToJsonPathWithValues(json, CLIENT_SIDE)
	}

	private static JsonPaths transformToJsonPathWithValues(def json, boolean clientSide) {
		if(!json) {
			return new JsonPaths()
		}
		JsonPaths pathsAndValues = [] as Set
		Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide)
		Object jsonWithPatterns = ContentUtils.convertDslPropsToTemporaryRegexPatterns(convertedJson)
		MethodBufferingJsonVerifiable methodBufferingJsonPathVerifiable =
				new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(jsonWithPatterns)).withoutThrowingException())
		traverseRecursivelyForKey(jsonWithPatterns, methodBufferingJsonPathVerifiable)
				 { MethodBufferingJsonVerifiable key, Object value ->
			if (value instanceof ExecutionProperty || !(key instanceof FinishedDelegatingJsonVerifiable)) {
				return
			}
			pathsAndValues.add(key)
		}
		return pathsAndValues
	}

	protected static def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) {
		value = ContentUtils.returnParsedObject(value)
		if (value instanceof String && value) {
			try {
				def json = new JsonSlurper().parseText(value)
				if (json instanceof Map) {
					return convertWithKey(parentType, key, json, closure)
				}
			} catch (Exception ignore) {
				return runClosure(closure, key, value)
			}
		} else if (isAnEntryWithNonCollectionLikeValue(value)) {
			return convertWithKey(List, key, value as Map, closure)
		} else if (isAnEntryWithoutNestedStructures(value)) {
			return convertWithKey(List, key, value as Map, closure)
		} else if (value instanceof Map) {
			return convertWithKey(Map, key, value as Map, closure)
		} else if (value instanceof List) {
			MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value)
			value.each { def element ->
				traverseRecursively(List, createAsserterFromListElement(jsonPathVerifiable, element),
						element, closure)
			}
			return value
		} else if (key.isIteratingOverArray()) {
			traverseRecursively(Object, key.arrayField().contains(value), value, closure)
		}
		try {
			return runClosure(closure, key, value)
		} catch (Exception ignore) {
			return value
		}
	}

	private static MethodBufferingJsonVerifiable createAsserterFromList(MethodBufferingJsonVerifiable key, List value) {
		if (key.isIteratingOverNamelessArray()) {
			return key.array()
		} else if (key.isIteratingOverArray() && isAnEntryWithLists(value)) {
			if (!value.every { listContainsOnlyPrimitives(it as List)} ) {
				return key.array()
			} else {
				return key.iterationPassingArray()
			}
		} else if (key.isIteratingOverArray()) {
			return key.iterationPassingArray()
		}
		return key
	}

	private static MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) {
		if (jsonPathVerifiable.isAssertingAValueInArray()) {
			def object = ContentUtils.returnParsedObject(element)
			if (object instanceof Pattern) {
				return jsonPathVerifiable.matches((object as Pattern).pattern())
			}
			return jsonPathVerifiable.contains(object)
		}
		return jsonPathVerifiable
	}

	private static def runClosure(Closure closure, MethodBufferingJsonVerifiable key, def value) {
		if (key.isAssertingAValueInArray()) {
			return closure(valueToAsserter(key, value), value)
		}
		return closure(key, value)
	}

	private static boolean isAnEntryWithNonCollectionLikeValue(def value) {
		if (!(value instanceof Map)) {
			return false
		}
		Map valueAsMap = ((Map) value)
		boolean mapHasOneEntry = valueAsMap.size() == 1
		if (!mapHasOneEntry) {
			return false
		}
		Object valueOfEntry = valueAsMap.entrySet().first().value
		return !(valueOfEntry instanceof Map || valueOfEntry instanceof List)
	}

	private static boolean isAnEntryWithoutNestedStructures(def value) {
		if (!(value instanceof Map)) {
			return false
		}
		Map valueAsMap = ((Map) value)
		return valueAsMap.entrySet().every { Map.Entry entry ->
			[String, Number, Boolean].any { it.isAssignableFrom(entry.value.getClass()) }
		}
	}

	private static boolean listContainsOnlyPrimitives(List list) {
		return list.every { def element ->
			[String, Number, Boolean].any {
				it.isAssignableFrom(element.getClass())
			}
		}
	}
	private static boolean isAnEntryWithLists(def value) {
		if (!(value instanceof Iterable)) {
			return false
		}
		return value.every { def entry ->
			entry instanceof List
		}
	}

	private static Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) {
		return map.collectEntries {
			Object entrykey, value ->
				def convertedValue = ContentUtils.returnParsedObject(value)
				[entrykey, traverseRecursively(parentType,
							convertedValue instanceof List ? listContainsOnlyPrimitives(convertedValue) ?
									parentKey.arrayField(entrykey) :
									parentKey.array(entrykey) :
							convertedValue instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) :
									valueToAsserter(parentKey.field(entrykey), convertedValue)
							, convertedValue, closureToExecute)]
		}
	}

	private static void traverseRecursivelyForKey(def json, MethodBufferingJsonVerifiable rootKey, Closure closure) {
		traverseRecursively(Map, rootKey, json, closure)
	}

	protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) {
		if (key instanceof FinishedDelegatingJsonVerifiable) {
			return key
		}
		if (value instanceof Pattern) {
			return key.matches((value as Pattern).pattern())
		} else if (value instanceof OptionalProperty) {
			return key.matches((value as OptionalProperty).optionalPattern())
		} else if (value instanceof GString) {
			return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(value))
		} else if (ContentUtils.returnParsedObject(value) instanceof  ExecutionProperty) {
			return key
		}
		return key.isEqualTo(value)
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy