diff options
15 files changed, 62 insertions, 436 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java index 5b3ce7136d5..2a4e231dee4 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java @@ -26,7 +26,6 @@ public class RankingConstant { public String getName() { return name; } public String getFileName() { return fileName; } public String getFileReference() { return fileRef; } - public TensorType getTensorType() { return tensorType; } public String getType() { return tensorType.toString(); } public void validate() { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java deleted file mode 100644 index 0485750bc16..00000000000 --- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java +++ /dev/null @@ -1,191 +0,0 @@ -package com.yahoo.vespa.model.application.validation; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.google.common.base.Joiner; -import com.yahoo.tensor.TensorType; - -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @author Vegard Sjonfjell - */ -public class ConstantTensorJsonValidator { - static private final JsonFactory jsonFactory = new JsonFactory(); - private TensorType tensorType; - private JsonParser parser; - - public static class InvalidConstantTensor extends RuntimeException { - public InvalidConstantTensor(JsonParser parser, String message) { - super(message + " " + parser.getCurrentLocation().toString()); - } - - public InvalidConstantTensor(JsonParser parser, Exception base) { - super("Failed to parse JSON stream " + parser.getCurrentLocation().toString(), base); - } - } - - @FunctionalInterface - private static interface SubroutineThrowingIOException { - void invoke() throws IOException; - } - - private void wrapIOException(SubroutineThrowingIOException lambda) { - try { - lambda.invoke(); - } catch (IOException e) { - throw new InvalidConstantTensor(parser, e); - } - } - - public ConstantTensorJsonValidator(Reader tensorFile, TensorType tensorType) { - wrapIOException(() -> { - this.parser = jsonFactory.createParser(tensorFile); - this.tensorType = tensorType; - }); - } - - public void validate() { - wrapIOException(() -> { - assertNextTokenIs(JsonToken.START_OBJECT); - assertNextTokenIs(JsonToken.FIELD_NAME); - assertFieldNameIs("cells"); - - assertNextTokenIs(JsonToken.START_ARRAY); - - while (parser.nextToken() != JsonToken.END_ARRAY) { - validateTensorCell(tensorType.dimensions()); - } - - assertNextTokenIs(JsonToken.END_OBJECT); - }); - } - - private void validateTensorCell(Collection<TensorType.Dimension> tensorDimensions) { - wrapIOException(() -> { - assertCurrentTokenIs(JsonToken.START_OBJECT); - - final List<String> fieldNameCandidates = new ArrayList<>(Arrays.asList("address", "value")); - for (int i = 0; i < 2; i++) { - assertNextTokenIs(JsonToken.FIELD_NAME); - final String fieldName = parser.getCurrentName(); - - if (fieldNameCandidates.contains(fieldName)) { - fieldNameCandidates.remove(fieldName); - - if (fieldName.equals("address")) { - validateTensorAddress(tensorDimensions); - } else if (fieldName.equals("value")) { - validateTensorValue(); - } - } else { - throw new InvalidConstantTensor(parser, "Only \"address\" or \"value\" fields are permitted within a cell object"); - } - } - - assertNextTokenIs(JsonToken.END_OBJECT); - }); - } - - private void validateTensorAddress(Collection<TensorType.Dimension> tensorDimensions) throws IOException { - assertNextTokenIs(JsonToken.START_OBJECT); - - final Map<String, TensorType.Dimension> tensorDimensionsMapping = tensorDimensions.stream() - .collect(Collectors.toMap(TensorType.Dimension::name, Function.identity())); - - // Iterate within the address key, value pairs - while ((parser.nextToken() != JsonToken.END_OBJECT)) { - assertCurrentTokenIs(JsonToken.FIELD_NAME); - - final String dimensionName = parser.getCurrentName(); - TensorType.Dimension dimension = tensorDimensionsMapping.get(dimensionName); - if (dimension == null) { - throw new InvalidConstantTensor(parser, String.format("Tensor dimension with name \"%s\" does not exist", parser.getCurrentName())); - } - - tensorDimensionsMapping.remove(dimensionName); - validateTensorCoordinate(dimension); - } - - if (!tensorDimensionsMapping.isEmpty()) { - throw new InvalidConstantTensor(parser, String.format("Tensor address missing dimension(s): %s", Joiner.on(", ").join(tensorDimensionsMapping.keySet()))); - } - } - - /* - * Tensor coordinates are always strings. Coordinates for a mapped dimension can be any string, - * but those for indexed dimensions needs to be able to be interpreted as integers, and, - * additionally, those for indexed bounded dimensions needs to fall within the dimension size. - */ - private void validateTensorCoordinate(TensorType.Dimension dimension) throws IOException { - assertNextTokenIs(JsonToken.VALUE_STRING); - - if (dimension instanceof TensorType.IndexedBoundDimension) { - validateBoundedCoordinate((TensorType.IndexedBoundDimension) dimension); - } else if (dimension instanceof TensorType.IndexedUnboundDimension) { - validateUnboundedCoordinate(dimension); - } - } - - private void validateBoundedCoordinate(TensorType.IndexedBoundDimension dimension) { - wrapIOException(() -> { - try { - final int value = Integer.parseInt(parser.getValueAsString()); - if (value >= dimension.size().get()) { - throwCoordinateOutsideBoundedDimension(parser.getValueAsString(), dimension.name()); - } - } catch (NumberFormatException e) { - throwCoordinateOutsideBoundedDimension(parser.getValueAsString(), dimension.name()); - } - }); - } - - private void throwCoordinateOutsideBoundedDimension(String value, String dimensionName) { - throw new InvalidConstantTensor(parser, String.format("Coordinate \"%s\" not within limits of bounded dimension %s", value, dimensionName)); - } - - private void validateUnboundedCoordinate(TensorType.Dimension dimension) { - wrapIOException(() -> { - try { - Integer.parseInt(parser.getValueAsString()); - } catch (NumberFormatException e) { - throw new InvalidConstantTensor(parser, String.format("Coordinate \"%s\" for dimension %s is not an integer", parser.getValueAsString(), dimension.name())); - } - }); - } - - private void validateTensorValue() throws IOException { - assertNextTokenIs(JsonToken.VALUE_NUMBER_FLOAT); - } - - private void assertCurrentTokenIs(JsonToken wantedToken) { - assertTokenIs(parser.getCurrentToken(), wantedToken); - } - - private void assertNextTokenIs(JsonToken wantedToken) throws IOException { - assertTokenIs(parser.nextToken(), wantedToken); - } - - private void assertTokenIs(JsonToken token, JsonToken wantedToken) { - if (token != wantedToken) { - throw new InvalidConstantTensor(parser, String.format("Expected JSON token %s, but got %s", wantedToken.toString(), token.toString())); - } - } - - private void assertFieldNameIs(String wantedFieldName) throws IOException { - final String actualFieldName = parser.getCurrentName(); - - if (!actualFieldName.equals(wantedFieldName)) { - throw new InvalidConstantTensor(parser, String.format("Expected field name \"%s\", got \"%s\"", wantedFieldName, actualFieldName)); - } - } -} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java deleted file mode 100644 index e43b1597f59..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.yahoo.vespa.model.application.validation; - -import com.yahoo.tensor.TensorType; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.Reader; -import java.io.StringReader; - -import static com.yahoo.test.json.JsonTestHelper.inputJson; -import static com.yahoo.vespa.model.application.validation.ConstantTensorJsonValidator.InvalidConstantTensor; - -public class ConstantTensorJsonValidatorTest { - private static Reader inputJsonToReader(String... lines) { - return new StringReader(inputJson(lines)); - } - - private static void validateTensorJson(TensorType tensorType, Reader jsonTensorReader) { - ConstantTensorJsonValidator validator = new ConstantTensorJsonValidator(jsonTensorReader, tensorType); - validator.validate(); - } - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void ensure_that_unbounded_tensor_works() { - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '99999', 'y': '47' },", - " 'value': 9932.0", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_bounded_tensor_within_limits_works() { - validateTensorJson( - TensorType.fromSpec("tensor(x[5], y[10])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3', 'y': '2' },", - " 'value': 2.0", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_multiple_cells_work() { - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3', 'y': '2' },", - " 'value': 2.0", - " },", - " {", - " 'address': { 'x': '2', 'y': '0' },", - " 'value': 4.5", - " }", - " ]", - "}")); - } - - - @Test - public void ensure_that_no_cells_work() { - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': []", - "}")); - } - - @Test - public void ensure_that_bounded_tensor_outside_limits_is_disallowed() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Coordinate \"9\" not within limits of bounded dimension x"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[5], y[10])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '9', 'y': '2' },", - " 'value': 1e47", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_mapped_tensor_works() { - validateTensorJson( - TensorType.fromSpec("tensor(x{}, y{})"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': 'andrei', 'y': 'bjarne' },", - " 'value': 2.0", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_non_integer_strings_in_address_points_are_disallowed() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Coordinate \"a\" for dimension x is not an integer"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': 'a' },", - " 'value': 47.0", - " }", - " ]", - "}")); - - } - - @Test - public void ensure_that_missing_coordinates_fail() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Tensor address missing dimension(s): y, z"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[], z[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3' },", - " 'value': 99.3", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_extra_dimensions_are_disallowed() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Tensor dimension with name \"z\" does not exist"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3', 'y': '2', 'z': '4' },", - " 'value': 99.3", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_invalid_json_fails() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Failed to parse JSON stream"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " cells': [", - " {", - " 'address': { 'x': '3' 'y': '2' }", - " 'value': 2.0", - " }", - " ", - "}")); - } - - @Test - public void ensure_that_invalid_json_not_in_tensor_format_fails() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Expected field name \"cells\", got \"stats\""); - - validateTensorJson(TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'stats': {", - " 'grandma-surprise': true,", - " 'points': 47", - " }", - "}")); - } -}
\ No newline at end of file diff --git a/config/pom.xml b/config/pom.xml index 3518426a7bd..73c8cd5b5ad 100755 --- a/config/pom.xml +++ b/config/pom.xml @@ -62,6 +62,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>uk.co.datumedge</groupId> + <artifactId>hamcrest-json</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>13.0.1</version> diff --git a/config/src/test/java/com/yahoo/config/subscription/CfgConfigPayloadBuilderTest.java b/config/src/test/java/com/yahoo/config/subscription/CfgConfigPayloadBuilderTest.java index 2bc1a10b729..7ad7144a1c8 100644 --- a/config/src/test/java/com/yahoo/config/subscription/CfgConfigPayloadBuilderTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/CfgConfigPayloadBuilderTest.java @@ -11,8 +11,8 @@ import org.junit.Test; import java.util.Arrays; import java.util.List; -import static com.yahoo.test.json.JsonTestHelper.assertJsonEquals; -import static com.yahoo.test.json.JsonTestHelper.inputJson; +import static com.yahoo.config.subscription.util.JsonHelper.assertJsonEquals; +import static com.yahoo.config.subscription.util.JsonHelper.inputJson; import static org.junit.Assert.assertEquals; /** diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceSerializerTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceSerializerTest.java index 342e50821f4..d3713eaa401 100644 --- a/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceSerializerTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceSerializerTest.java @@ -1,21 +1,22 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription; -import com.yahoo.config.ConfigInstance; import com.yahoo.foo.ArraytypesConfig; -import com.yahoo.foo.MaptypesConfig; +import com.yahoo.config.ConfigInstance; import com.yahoo.foo.SimpletypesConfig; import com.yahoo.foo.SpecialtypesConfig; import com.yahoo.foo.StructtypesConfig; +import com.yahoo.foo.MaptypesConfig; import com.yahoo.slime.JsonFormat; import com.yahoo.slime.Slime; + import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; -import static com.yahoo.test.json.JsonTestHelper.assertJsonEquals; -import static com.yahoo.test.json.JsonTestHelper.inputJson; +import static com.yahoo.config.subscription.util.JsonHelper.assertJsonEquals; +import static com.yahoo.config.subscription.util.JsonHelper.inputJson; import static org.junit.Assert.fail; /** diff --git a/config/src/test/java/com/yahoo/config/subscription/util/JsonHelper.java b/config/src/test/java/com/yahoo/config/subscription/util/JsonHelper.java new file mode 100644 index 00000000000..27ac1a1278c --- /dev/null +++ b/config/src/test/java/com/yahoo/config/subscription/util/JsonHelper.java @@ -0,0 +1,28 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.subscription.util; + +import com.google.common.base.Joiner; + +import static org.hamcrest.MatcherAssert.assertThat; +import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs; + +/** + * @author Vegard Sjonfjell + */ +public class JsonHelper { + /** + * Convenience method to input JSON without escaping double quotes and newlines + * Each parameter represents a line of JSON encoded data + * The lines are joined with newline and single quotes are replaced with double quotes + */ + public static String inputJson(String... lines) { + return Joiner.on("\n").join(lines).replaceAll("'", "\""); + } + + /** + * Structurally compare two JSON encoded strings + */ + public static void assertJsonEquals(String inputJson, String expectedJson) { + assertThat(inputJson, sameJSONAs(expectedJson)); + } +} diff --git a/document/pom.xml b/document/pom.xml index 71713b27050..529107407ca 100644 --- a/document/pom.xml +++ b/document/pom.xml @@ -48,6 +48,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>uk.co.datumedge</groupId> + <artifactId>hamcrest-json</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>com.yahoo.vespa</groupId> <artifactId>config</artifactId> <version>${project.version}</version> @@ -78,12 +83,6 @@ <classifier>no_aop</classifier> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>testutil</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> </dependencies> <build> <plugins> diff --git a/document/src/main/java/com/yahoo/document/json/JsonWriter.java b/document/src/main/java/com/yahoo/document/json/JsonWriter.java index 420a6bb6669..626c97a958a 100644 --- a/document/src/main/java/com/yahoo/document/json/JsonWriter.java +++ b/document/src/main/java/com/yahoo/document/json/JsonWriter.java @@ -112,7 +112,6 @@ public class JsonWriter implements DocumentWriter { Map.Entry<Field, FieldValue> entry = i.next(); entry.getValue().serialize(entry.getKey(), this); } - generator.writeEndObject(); generator.writeEndObject(); generator.flush(); diff --git a/document/src/test/java/com/yahoo/document/json/DocumentUpdateJsonSerializerTest.java b/document/src/test/java/com/yahoo/document/json/DocumentUpdateJsonSerializerTest.java index de483186d6c..b3deae547ab 100644 --- a/document/src/test/java/com/yahoo/document/json/DocumentUpdateJsonSerializerTest.java +++ b/document/src/test/java/com/yahoo/document/json/DocumentUpdateJsonSerializerTest.java @@ -19,8 +19,8 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; -import static com.yahoo.test.json.JsonTestHelper.assertJsonEquals; -import static com.yahoo.test.json.JsonTestHelper.inputJson; +import static com.yahoo.document.json.JsonTestHelper.assertJsonEquals; +import static com.yahoo.document.json.JsonTestHelper.inputJson; /** * @author Vegard Sjonfjell diff --git a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java index 206ab8e30f0..466a915f83f 100644 --- a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java +++ b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java @@ -59,7 +59,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; -import static com.yahoo.test.json.JsonTestHelper.inputJson; +import static com.yahoo.document.json.JsonTestHelper.inputJson; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; diff --git a/testutil/src/main/java/com/yahoo/test/json/JsonTestHelper.java b/document/src/test/java/com/yahoo/document/json/JsonTestHelper.java index a8e8e562b2d..09e6a74e68a 100644 --- a/testutil/src/main/java/com/yahoo/test/json/JsonTestHelper.java +++ b/document/src/test/java/com/yahoo/document/json/JsonTestHelper.java @@ -1,9 +1,8 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.test.json; +package com.yahoo.document.json; import com.google.common.base.Joiner; -import org.hamcrest.MatcherAssert; - +import static org.hamcrest.MatcherAssert.assertThat; import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs; /** @@ -24,6 +23,7 @@ public class JsonTestHelper { * Structurally compare two JSON encoded strings */ public static void assertJsonEquals(String inputJson, String expectedJson) { - MatcherAssert.assertThat(inputJson, sameJSONAs(expectedJson)); + assertThat(inputJson, sameJSONAs(expectedJson)); } + } diff --git a/testutil/pom.xml b/testutil/pom.xml index bd46d2e4c16..0d2aa8a4dbf 100644 --- a/testutil/pom.xml +++ b/testutil/pom.xml @@ -15,11 +15,6 @@ <description>Library of useful Hamcrest matchers.</description> <dependencies> <dependency> - <groupId>com.google.guava</groupId> - <artifactId>guava</artifactId> - <scope>provided</scope> - </dependency> - <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <scope>compile</scope> @@ -30,11 +25,6 @@ <scope>compile</scope> </dependency> <dependency> - <groupId>uk.co.datumedge</groupId> - <artifactId>hamcrest-json</artifactId> - <scope>compile</scope> - </dependency> - <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>compile</scope> diff --git a/vespa-http-client/pom.xml b/vespa-http-client/pom.xml index 563e4406fe9..9e2325e8016 100644 --- a/vespa-http-client/pom.xml +++ b/vespa-http-client/pom.xml @@ -83,12 +83,6 @@ <artifactId>airline</artifactId> <version>0.6</version> </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>testutil</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> </dependencies> <build> <plugins> diff --git a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/runner/JsonReaderTest.java b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/runner/JsonReaderTest.java index eba8791bbb7..ab7dca0d5fb 100644 --- a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/runner/JsonReaderTest.java +++ b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/runner/JsonReaderTest.java @@ -1,6 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.http.client.runner; +import com.google.common.base.Joiner; import com.yahoo.vespa.http.client.FeedClient; import com.yahoo.vespa.http.client.core.JsonReader; import org.junit.Test; @@ -12,7 +13,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import static com.yahoo.test.json.JsonTestHelper.inputJson; import static org.hamcrest.core.Is.is; import static org.junit.Assert.*; @@ -260,4 +260,13 @@ public class JsonReaderTest { assertThat(session.documentIds.size(), is(1)); assertThat(session.documentIds.get(0), is("id:foo:music:doc:foo:bar")); } + + /** + * Convenience method to input JSON without escaping double quotes and newlines + * Each parameter represents a line of JSON encoded data + * The lines are joined with newline and single quotes are replaced with double quotes + */ + static String inputJson(String... lines) { + return Joiner.on("\n").join(lines).replaceAll("'", "\""); + } }
\ No newline at end of file |