Skip to content

Commit c557c16

Browse files
committed
Reuse former processRef in insertInto methods (#92, #171, #205)
Fix issue with testing non-existing refs, update tests
1 parent 57ac842 commit c557c16

File tree

10 files changed

+84
-53
lines changed

10 files changed

+84
-53
lines changed

metafix/src/main/java/org/metafacture/metafix/FixPath.java

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ else if (isReference(currentSegment)) {
102102

103103
private Value findInValue(final Value value, final String[] p) {
104104
// TODO: move impl into enum elements, here call only value.find
105-
return value == null ? null : value.extractType((m, c) -> m
105+
return p.length == 0 ? value : value == null ? null : value.extractType((m, c) -> m
106106
.ifArray(a -> c.accept(new FixPath(p).findIn(a)))
107107
.ifHash(h -> c.accept(new FixPath(p).findIn(h)))
108108
.orElse(c)
@@ -249,20 +249,15 @@ private void removeNestedFrom(final Value value) {
249249
/*package-private*/ private Value insertInto(final Array array, final InsertMode mode, final Value newValue) {
250250
// basic idea: reuse findIn logic here? setIn(findIn(array), newValue)
251251
final String field = path[0];
252-
if (field.equals(ASTERISK)) {
253-
array.forEach(value -> value.matchType()
254-
.ifArray(a -> new FixPath(tail(path)).insertInto(a, mode, newValue))
255-
.ifHash(h -> new FixPath(tail(path)).insertInto(h, mode, newValue))
256-
.orElseThrow());
252+
if (path.length == 1) {
253+
mode.apply(array, field, newValue);
257254
}
258255
else {
259-
if (path.length == 1) {
260-
mode.apply(array, field, newValue);
256+
if (ASTERISK.equals(field)) {
257+
array.forEach(value -> insertInto(value, mode, newValue, field, tail(path)));
261258
}
262-
else {
263-
if (isReference(field)) {
264-
return processRef(getReferencedValue(array, field), mode, newValue, field, tail(path));
265-
}
259+
else if (isReference(field)) {
260+
insertInto(getReferencedValue(array, field), mode, newValue, field, tail(path));
266261
}
267262
}
268263
return new Value(array);
@@ -275,45 +270,34 @@ private void removeNestedFrom(final Value value) {
275270
mode.apply(hash, field, newValue);
276271
}
277272
else {
278-
final String[] tail = tail(path);
279-
if (isReference(field)) {
280-
return processRef(hash.get(field), mode, newValue, field, tail);
281-
}
282273
if (!hash.containsField(field)) {
283274
hash.put(field, Value.newHash());
284275
}
285-
final Value value = hash.get(field);
286-
if (value != null) {
287-
// TODO: move impl into enum elements, here call only value.insert
288-
value.matchType()
289-
.ifArray(a -> new FixPath(tail).insertInto(a, mode, newValue))
290-
.ifHash(h -> new FixPath(tail).insertInto(h, mode, newValue))
291-
.orElseThrow();
292-
}
276+
insertInto(hash.get(field), mode, newValue, field, tail(path));
293277
}
294278

295279
return new Value(hash);
296280
}
297281

298-
private String[] tail(final String[] fields) {
299-
return Arrays.copyOfRange(fields, 1, fields.length);
300-
}
301-
302-
private Value processRef(final Value referencedValue, final InsertMode mode, final Value newValue, final String field,
282+
private Value insertInto(final Value value, final InsertMode mode, final Value newValue, final String field,
303283
final String[] tail) {
304-
if (referencedValue != null) {
284+
if (value != null) {
305285
final FixPath fixPath = new FixPath(tail);
306-
newValue.updatePathAddBase(referencedValue, field);
307-
return referencedValue.extractType((m, c) -> m
308-
.ifArray(a -> c.accept(fixPath.insertInto(referencedValue.asArray(), mode, newValue)))
309-
.ifHash(h -> c.accept(fixPath.insertInto(referencedValue.asHash(), mode, newValue)))
286+
newValue.updatePathAddBase(value, field);
287+
return value.extractType((m, c) -> m
288+
.ifArray(a -> c.accept(fixPath.insertInto(a, mode, newValue)))
289+
.ifHash(h -> c.accept(fixPath.insertInto(h, mode, newValue)))
310290
.orElseThrow());
311291
}
312292
else {
313-
throw new IllegalArgumentException("Using ref, but can't find: " + field + " in: " + referencedValue);
293+
throw new IllegalArgumentException("Using ref, but can't find: " + field + " in: " + value);
314294
}
315295
}
316296

297+
private String[] tail(final String[] fields) {
298+
return Arrays.copyOfRange(fields, 1, fields.length);
299+
}
300+
317301
private enum ReservedField {
318302
$append, $first, $last;
319303

@@ -344,10 +328,10 @@ private Value getReferencedValue(final Array array, final String field) {
344328
if (reservedField != null) {
345329
switch (reservedField) {
346330
case $first:
347-
referencedValue = array.get(0);
331+
referencedValue = getReferencedValue(array, "1");
348332
break;
349333
case $last:
350-
referencedValue = array.get(array.size() - 1);
334+
referencedValue = getReferencedValue(array, String.valueOf(array.size()));
351335
break;
352336
case $append:
353337
referencedValue = Value.newHash(); // TODO: append non-hash?

metafix/src/test/java/org/metafacture/metafix/MetafixMethodTest.java

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,10 +1844,34 @@ public void copyFieldToSubfieldOfArrayOfObjectsWithIndexExplicitAppend() {
18441844
}
18451845

18461846
@Test
1847-
@MetafixToDo("See https://github.com/metafacture/metafacture-fix/pull/205")
1848-
public void addFieldIntoArrayOfObjectsWithLastWildcardImplicitSkip() {
1847+
// We currently fail on unresolved references, see MetafixRecordTests#assertThrowsOnEmptyArray
1848+
public void addFieldIntoArrayOfObjectsWithLastWildcardMissingError() {
1849+
MetafixTestHelpers.assertProcessException(IllegalArgumentException.class, "Using ref, but can't find: $last in: null", () -> {
1850+
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
1851+
"add_field('animals[].$last.key', 'value')"
1852+
),
1853+
i -> {
1854+
i.startRecord("1");
1855+
i.startEntity("animals[]");
1856+
i.endEntity();
1857+
i.endRecord();
1858+
},
1859+
(o, f) -> {
1860+
o.get().startRecord("1");
1861+
o.get().startEntity("animals[]");
1862+
o.get().endEntity();
1863+
o.get().endRecord();
1864+
}
1865+
);
1866+
});
1867+
}
1868+
1869+
@Test
1870+
public void addFieldIntoArrayOfObjectsWithLastWildcardAllEmpty() {
18491871
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
1850-
"add_field('animals[].$last.key', 'value')"
1872+
"if exists('animals[].$last')",
1873+
" add_field('animals[].$last.key', 'value')",
1874+
"end"
18511875
),
18521876
i -> {
18531877
i.startRecord("1");
@@ -1865,8 +1889,7 @@ public void addFieldIntoArrayOfObjectsWithLastWildcardImplicitSkip() {
18651889
}
18661890

18671891
@Test
1868-
@MetafixToDo("See https://github.com/metafacture/metafacture-fix/pull/205")
1869-
public void addFieldIntoArrayOfObjectsWithLastWildcardExplicitSkip() {
1892+
public void addFieldIntoArrayOfObjectsWithLastWildcardLastEmpty() {
18701893
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
18711894
"if exists('animals[].$last')",
18721895
" add_field('animals[].$last.key', 'value')",
@@ -1875,12 +1898,36 @@ public void addFieldIntoArrayOfObjectsWithLastWildcardExplicitSkip() {
18751898
i -> {
18761899
i.startRecord("1");
18771900
i.startEntity("animals[]");
1901+
i.startEntity("1");
1902+
i.literal("name", "Jake");
1903+
i.literal("type", "dog");
1904+
i.endEntity();
1905+
i.startEntity("2");
1906+
i.literal("name", "Blacky");
1907+
i.literal("type", "bird");
1908+
i.endEntity();
1909+
i.endEntity();
1910+
i.endRecord();
1911+
i.startRecord("2");
1912+
i.startEntity("animals[]");
18781913
i.endEntity();
18791914
i.endRecord();
18801915
},
18811916
(o, f) -> {
18821917
o.get().startRecord("1");
18831918
o.get().startEntity("animals[]");
1919+
o.get().startEntity("1");
1920+
o.get().literal("name", "Jake");
1921+
o.get().literal("type", "dog");
1922+
o.get().endEntity();
1923+
o.get().startEntity("2");
1924+
o.get().literal("name", "Blacky");
1925+
o.get().literal("type", "bird");
1926+
o.get().literal("key", "value");
1927+
f.apply(2).endEntity();
1928+
o.get().endRecord();
1929+
o.get().startRecord("2");
1930+
o.get().startEntity("animals[]");
18841931
o.get().endEntity();
18851932
o.get().endRecord();
18861933
}

metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,26 +1098,28 @@ public void addFieldToObjectByIndexInIndexedArray() {
10981098

10991099
@Test
11001100
public void addFieldToFirstObjectMissing() {
1101-
assertThrowsOnEmptyRecord("$first");
1101+
assertThrowsOnEmptyArray("$first");
11021102
}
11031103

11041104
@Test
11051105
public void addFieldToLastObjectMissing() {
1106-
assertThrowsOnEmptyRecord("$last");
1106+
assertThrowsOnEmptyArray("$last");
11071107
}
11081108

11091109
@Test
11101110
public void addFieldToObjectByIndexMissing() {
1111-
assertThrowsOnEmptyRecord("2");
1111+
assertThrowsOnEmptyArray("2");
11121112
}
11131113

1114-
private void assertThrowsOnEmptyRecord(final String index) {
1114+
private void assertThrowsOnEmptyArray(final String index) {
11151115
MetafixTestHelpers.assertProcessException(IllegalArgumentException.class, "Using ref, but can't find: " + index + " in: null", () -> {
11161116
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
11171117
"add_field('animals[]." + index + ".kind','nice')"
11181118
),
11191119
i -> {
11201120
i.startRecord("1");
1121+
i.startEntity("animals[]");
1122+
i.endEntity();
11211123
i.endRecord();
11221124
},
11231125
o -> {
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
add_field("animals[].$last.key", "value")
1+
if exists("animals[].$last")
2+
add_field("animals[].$last.key", "value")
3+
end

metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/add_fieldIntoArrayOfObjectsWithLastWildcard/todo.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/add_fieldSimpleSubsubfield/todo.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldObjectFromArrayOfObjectsWithFirstWildcard/todo.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

metafix/src/test/resources/org/metafacture/metafix/integration/record/fromJson/toJson/copy_fieldObjectFromArrayOfObjectsWithLastWildcard/todo.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
copy_field("test_2", "test[].$append")
1+
copy_field("test_2", "test[].$prepend")
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
copy_field("test_2", "test[].$append")
1+
copy_field("test_2", "test[].$prepend")

0 commit comments

Comments
 (0)