diff --git a/metafix/src/main/java/org/metafacture/metafix/FixMethod.java b/metafix/src/main/java/org/metafacture/metafix/FixMethod.java index 556f5ad8..5e27c83b 100644 --- a/metafix/src/main/java/org/metafacture/metafix/FixMethod.java +++ b/metafix/src/main/java/org/metafacture/metafix/FixMethod.java @@ -164,9 +164,16 @@ public void apply(final Metafix metafix, final Record record, final List public void apply(final Metafix metafix, final Record record, final List params, final Map options) { final String oldName = params.get(0); final String newName = params.get(1); - Value.asList(record.get(oldName), a -> a.forEach(oldValue -> { - record.addNested(newName, oldValue); // we're actually aliasing - })); + + final Value oldValue = record.get(oldName); + if (!Value.isNull(oldValue)) { + oldValue.matchType() + .ifArray(a -> { + record.remove(newName); + a.forEach(v -> record.addNested(newName, v)); + }) + .orElse(v -> record.set(newName, v)); + } } }, format { diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java index 3063a337..88917916 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixBindTest.java @@ -54,6 +54,28 @@ public void doList() { i.literal("name", " A University"); i.literal("name", "Max "); i.endRecord(); + }, o -> { + o.get().startRecord("1"); + o.get().literal("author", "MAX"); + o.get().endRecord(); + }); + } + + @Test + public void doListExplicitAppend() { + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('author')", + "do list('path': 'name', 'var': 'n')", + " upcase('n')", + " trim('n')", + " copy_field('n', 'author.$append')", + "end", + "remove_field('name')"), + i -> { + i.startRecord("1"); + i.literal("name", " A University"); + i.literal("name", "Max "); + i.endRecord(); }, o -> { o.get().startRecord("1"); o.get().literal("author", "A UNIVERSITY"); @@ -180,6 +202,30 @@ public void doListPathWithDots() { i.literal("name", "Max "); i.endEntity(); i.endRecord(); + }, o -> { + o.get().startRecord("1"); + o.get().literal("author", "MAX"); + o.get().endRecord(); + }); + } + + @Test + public void doListPathWithDotsExplicitAppend() { + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('author')", + "do list('path': 'some.name', 'var': 'n')", + " upcase('n')", + " trim('n')", + " copy_field('n', 'author.$append')", + "end", + "remove_field('some')"), + i -> { + i.startRecord("1"); + i.startEntity("some"); + i.literal("name", " A University"); + i.literal("name", "Max "); + i.endEntity(); + i.endRecord(); }, o -> { o.get().startRecord("1"); o.get().literal("author", "A UNIVERSITY"); @@ -239,6 +285,32 @@ public void doListEntitesToLiterals() { i.literal("name", "Max "); i.endEntity(); i.endRecord(); + }, o -> { + o.get().startRecord("1"); + o.get().literal("author", "MAX"); + o.get().endRecord(); + }); + } + + @Test + public void doListEntitesToLiteralsExplicitAppend() { + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('author')", + "do list('path': 'creator', 'var': 'c')", + " upcase('c.name')", + " trim('c.name')", + " copy_field('c.name', 'author.$append')", + "end", + "remove_field('creator')"), + i -> { + i.startRecord("1"); + i.startEntity("creator"); + i.literal("name", " A University"); + i.endEntity(); + i.startEntity("creator"); + i.literal("name", "Max "); + i.endEntity(); + i.endRecord(); }, o -> { o.get().startRecord("1"); o.get().literal("author", "A UNIVERSITY"); @@ -401,6 +473,32 @@ public void doListIndexedArrayOfObjects() { i.endEntity(); i.endEntity(); i.endRecord(); + }, o -> { + o.get().startRecord("1"); + o.get().literal("author", "Max"); + o.get().endRecord(); + }); + } + + @Test + public void doListIndexedArrayOfObjectsExplicitAppend() { + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('author')", + "do list('path': 'name[]', 'var': 'n')", + " copy_field('n.name', 'author.$append')", + "end", + "remove_field('name[]')"), + i -> { + i.startRecord("1"); + i.startEntity("name[]"); + i.startEntity("1"); + i.literal("name", "A University"); + i.endEntity(); + i.startEntity("2"); + i.literal("name", "Max"); + i.endEntity(); + i.endEntity(); + i.endRecord(); }, o -> { o.get().startRecord("1"); o.get().literal("author", "A University"); diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java index 072782b0..4457f572 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java @@ -169,11 +169,30 @@ public void shouldLookupDeduplicatedInternalArrayWithAsterisk() { } @Test - public void shouldLookupCopiedInternalArrayWithAsterisk() { + public void shouldNotLookupCopiedInternalArrayWithAsterisk() { + MetafixTestHelpers.assertExecutionException(IllegalStateException.class, "Expected Array or Hash, got String", () -> + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('data', 'Aloha')", + "set_array('title')", + "copy_field('data', 'title')", + LOOKUP + " Aloha: Alohaeha)" + ), + i -> { + i.startRecord("1"); + i.endRecord(); + }, + o -> { + } + ) + ); + } + + @Test + public void shouldLookupCopiedInternalArrayWithAsteriskExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "set_array('data', 'Aloha')", "set_array('title')", - "copy_field('data', 'title')", + "copy_field('data', 'title.$append')", LOOKUP + " Aloha: Alohaeha)" ), i -> { @@ -190,12 +209,32 @@ public void shouldLookupCopiedInternalArrayWithAsterisk() { } @Test - public void shouldLookupCopiedDeduplicatedInternalArrayWithAsterisk() { + public void shouldNotLookupCopiedDeduplicatedInternalArrayWithAsterisk() { + MetafixTestHelpers.assertExecutionException(IllegalStateException.class, "Expected Array or Hash, got String", () -> + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('data', 'Aloha', 'Aloha')", + "uniq('data')", + "set_array('title')", + "copy_field('data', 'title')", + LOOKUP + " Aloha: Alohaeha)" + ), + i -> { + i.startRecord("1"); + i.endRecord(); + }, + o -> { + } + ) + ); + } + + @Test + public void shouldLookupCopiedDeduplicatedInternalArrayWithAsteriskExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "set_array('data', 'Aloha', 'Aloha')", "uniq('data')", "set_array('title')", - "copy_field('data', 'title')", + "copy_field('data', 'title.$append')", LOOKUP + " Aloha: Alohaeha)" ), i -> { @@ -212,10 +251,10 @@ public void shouldLookupCopiedDeduplicatedInternalArrayWithAsterisk() { } @Test - public void shouldLookupCopiedExternalArrayWithAsterisk() { + public void shouldLookupCopiedExternalArrayWithAsteriskExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "set_array('title')", - "copy_field('data', 'title')", + "copy_field('data', 'title.$append')", LOOKUP + " Aloha: Alohaeha)" ), i -> { @@ -233,11 +272,11 @@ public void shouldLookupCopiedExternalArrayWithAsterisk() { } @Test - public void shouldLookupCopiedDeduplicatedExternalArrayWithAsterisk() { + public void shouldLookupCopiedDeduplicatedExternalArrayWithAsteriskExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "uniq('data')", "set_array('title')", - "copy_field('data', 'title')", + "copy_field('data', 'title.$append')", LOOKUP + " Aloha: Alohaeha)" ), i -> { @@ -256,11 +295,32 @@ public void shouldLookupCopiedDeduplicatedExternalArrayWithAsterisk() { } @Test - public void shouldLookupMovedDeduplicatedExternalArrayWithAsterisk() { + public void shouldNotLookupMovedDeduplicatedExternalArrayWithAsterisk() { + MetafixTestHelpers.assertExecutionException(IllegalStateException.class, "Expected Array or Hash, got String", () -> + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "uniq('data')", + "set_array('title')", + "move_field('data', 'title')", + LOOKUP + " Aloha: Alohaeha)" + ), + i -> { + i.startRecord("1"); + i.literal("data", "Aloha"); + i.literal("data", "Aloha"); + i.endRecord(); + }, + o -> { + } + ) + ); + } + + @Test + public void shouldLookupMovedDeduplicatedExternalArrayWithAsteriskExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "uniq('data')", "set_array('title')", - "move_field('data', 'title')", + "move_field('data', 'title.$append')", LOOKUP + " Aloha: Alohaeha)" ), i -> { @@ -278,10 +338,29 @@ public void shouldLookupMovedDeduplicatedExternalArrayWithAsterisk() { } @Test - public void shouldLookupMovedExternalArrayWithAsterisk() { + public void shouldNotLookupMovedExternalArrayWithAsterisk() { + MetafixTestHelpers.assertExecutionException(IllegalStateException.class, "Expected Array or Hash, got String", () -> + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('title')", + "move_field('data', 'title')", + LOOKUP + " Aloha: Alohaeha)" + ), + i -> { + i.startRecord("1"); + i.literal("data", "Aloha"); + i.endRecord(); + }, + o -> { + } + ) + ); + } + + @Test + public void shouldLookupMovedExternalArrayWithAsteriskExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "set_array('title')", - "move_field('data', 'title')", + "move_field('data', 'title.$append')", LOOKUP + " Aloha: Alohaeha)" ), i -> { diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java index d2233b2a..bf607b95 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java @@ -2250,11 +2250,28 @@ public void multipleReplaceAllWithWildcardAfterCopyFieldWithVarInSourceAndTarget } @Test - @MetafixToDo("Do we actually want implicit append? WDCD? See (passing) copyFieldToSubfieldOfArrayOfStringsWithIndexImplicitAppend") public void copyFieldToSubfieldOfArrayOfObjectsWithIndexImplicitAppend() { + MetafixTestHelpers.assertProcessException(IllegalArgumentException.class, "Can't find: 1 in: null", () -> + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('test[]')", + "copy_field('key', 'test[].1.field')" + ), + i -> { + i.startRecord("1"); + i.literal("key", "value"); + i.endRecord(); + }, + o -> { + } + ) + ); + } + + @Test + public void copyFieldToSubfieldOfArrayOfObjectsWithExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "set_array('test[]')", - "copy_field('key', 'test[].1.field')" + "copy_field('key', 'test[].$append.field')" ), i -> { i.startRecord("1"); @@ -2274,46 +2291,40 @@ public void copyFieldToSubfieldOfArrayOfObjectsWithIndexImplicitAppend() { } @Test - // Do we actually want implicit append? WDCD? See (failing) copyFieldToSubfieldOfArrayOfObjectsWithIndexImplicitAppend public void copyFieldToSubfieldOfArrayOfStringsWithIndexImplicitAppend() { - MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( - "set_array('test[]')", - "copy_field('key', 'test[].1')" - ), - i -> { - i.startRecord("1"); - i.literal("key", "value"); - i.endRecord(); - }, - o -> { - o.get().startRecord("1"); - o.get().literal("key", "value"); - o.get().startEntity("test[]"); - o.get().literal("1", "value"); - o.get().endEntity(); - o.get().endRecord(); - } + MetafixTestHelpers.assertProcessException(IndexOutOfBoundsException.class, "Index: 0, Size: 0", () -> + MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( + "set_array('test[]')", + "copy_field('key', 'test[].1')" + ), + i -> { + i.startRecord("1"); + i.literal("key", "value"); + i.endRecord(); + }, + o -> { + } + ) ); } @Test - public void copyFieldToSubfieldOfArrayOfObjectsWithIndexExplicitAppend() { + public void copyFieldToSubfieldOfArrayOfStringsWithExplicitAppend() { MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList( "set_array('test[]')", - "copy_field('key', 'test[].$append.field')" + "copy_field('key', 'test[].$append')" ), i -> { i.startRecord("1"); i.literal("key", "value"); i.endRecord(); }, - (o, f) -> { + o -> { o.get().startRecord("1"); o.get().literal("key", "value"); o.get().startEntity("test[]"); - o.get().startEntity("1"); - o.get().literal("field", "value"); - f.apply(2).endEntity(); + o.get().literal("1", "value"); + o.get().endEntity(); o.get().endRecord(); } ); diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java index 20bcdc18..f331bc4a 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java @@ -569,9 +569,9 @@ public void simpleCopyWithWildcard() { i.literal("cnimal", "zebra"); i.endRecord(); }, - (o, f) -> { + o -> { o.get().startRecord("1"); - f.apply(2).literal("animal", "dog"); + o.get().literal("animal", "dog"); o.get().endRecord(); o.get().startRecord("2"); o.get().literal("bnimal", "cat"); diff --git a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldArrayOfStringsIntoArrayOfObjectsWithAsteriskWildcard/todo.txt b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldArrayOfStringsIntoArrayOfObjectsWithAsteriskWildcard/todo.txt new file mode 100644 index 00000000..760ffe30 --- /dev/null +++ b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldArrayOfStringsIntoArrayOfObjectsWithAsteriskWildcard/todo.txt @@ -0,0 +1 @@ +See issue #193 diff --git a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldSimpleDestructive/todo.txt b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldSimpleDestructive/todo.txt deleted file mode 100644 index 14e84792..00000000 --- a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldSimpleDestructive/todo.txt +++ /dev/null @@ -1 +0,0 @@ -See issue #116 diff --git a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/expected.err b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/expected.err new file mode 100644 index 00000000..e9f060a1 --- /dev/null +++ b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/expected.err @@ -0,0 +1,2 @@ +^Exception in thread "main" org\.metafacture\.metafix\.FixProcessException: Error while executing Fix expression \(at .*/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/test\.fix, line 2\): copy_field\("key", "test\[\]\.1"\)$ +^Caused by: java\.lang\.IndexOutOfBoundsException: Index: 0, Size: 0$ diff --git a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/expected.json b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/expected.json deleted file mode 100644 index 93ba278e..00000000 --- a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldToArrayOfStringsWithIndex/expected.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "key" : "value", - "key_2" : "value_2", - "key_3" : "value_3", - "test" : [ "value", "value_2", "value_3" ] -} diff --git a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/move_fieldSimpleDestructive/todo.txt b/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/move_fieldSimpleDestructive/todo.txt deleted file mode 100644 index 14e84792..00000000 --- a/metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/move_fieldSimpleDestructive/todo.txt +++ /dev/null @@ -1 +0,0 @@ -See issue #116