Skip to content
This repository has been archived by the owner on Jan 27, 2025. It is now read-only.

Commit

Permalink
Merge pull request #120 from metafacture/114-extendVacuumFunction
Browse files Browse the repository at this point in the history
Extend `vacuum()` Fix function.
  • Loading branch information
blackwinter authored Feb 1, 2022
2 parents ca2ffb8 + cf2f6da commit 2225a80
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 21 deletions.
32 changes: 24 additions & 8 deletions metafix/src/main/java/org/metafacture/metafix/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,20 @@ private <T> TypeMatcher match(final Type type, final Consumer<T> consumer, final

private abstract static class AbstractValueType {

protected static final Predicate<Value> REMOVE_EMPTY_VALUES = v -> v.extractType((m, c) -> m
.ifArray(a -> {
a.removeEmptyValues();
c.accept(a.isEmpty());
})
.ifHash(h -> {
h.removeEmptyValues();
c.accept(h.isEmpty());
})
// TODO: Catmandu considers whitespace-only strings empty (`$v !~ /\S/`)
.ifString(s -> c.accept(s.isEmpty()))
.orElseThrow()
);

@Override
public abstract boolean equals(Object object);

Expand Down Expand Up @@ -369,6 +383,10 @@ public void add(final Value value) {
}
}

private boolean isEmpty() {
return list.isEmpty();
}

public int size() {
return list.size();
}
Expand All @@ -381,6 +399,10 @@ public Stream<Value> stream() {
return list.stream();
}

private void removeEmptyValues() {
list.removeIf(REMOVE_EMPTY_VALUES);
}

public void forEach(final Consumer<Value> consumer) {
list.forEach(consumer);
}
Expand Down Expand Up @@ -927,16 +949,10 @@ public void retainFields(final Collection<String> fields) {
}

/**
* Removes all field/value pairs from this hash whose value is empty.
* Recursively removes all field/value pairs from this hash whose value is empty.
*/
public void removeEmptyValues() {
// TODO:
//
// - Remove empty arrays/hashes?
// - Remove empty strings(/arrays/hashes) recursively?
//
// => Compare Catmandu behaviour
map.values().removeIf(v -> v.isString() && v.asString().isEmpty());
map.values().removeIf(REMOVE_EMPTY_VALUES);
}

/**
Expand Down
238 changes: 225 additions & 13 deletions metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public MetafixRecordTest() {
@Test
public void entitiesPassThrough() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
"nothing()"),
i -> {
i.startRecord("1");
i.startEntity("deep");
Expand All @@ -67,7 +67,7 @@ public void entitiesPassThrough() {
@Test
public void shouldNotEmitVirtualFieldsByDefault() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
"nothing()"
),
i -> {
i.startRecord("1");
Expand Down Expand Up @@ -134,7 +134,7 @@ public void shouldEmitVirtualFieldsWhenAdded() {
@Test
public void entitiesPassThroughRepeatNestedEntity() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
"nothing()"),
i -> {
i.startRecord("1");
i.startEntity("deep");
Expand Down Expand Up @@ -1527,22 +1527,236 @@ public void retain() {
}

@Test
public void vacuum() {
public void shouldDeleteEmptyArrays() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("1[]");
i.literal("1", "one");
i.endEntity();
i.startEntity("2[]");
i.endEntity();
i.startEntity("3[]");
i.literal("1", "tre");
i.endEntity();
i.startEntity("4[]");
i.endEntity();
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().startEntity("1[]");
o.get().literal("1", "one");
o.get().endEntity();
o.get().startEntity("3[]");
o.get().literal("1", "tre");
o.get().endEntity();
o.get().endRecord();
}
);
}

@Test
public void shouldDeleteEmptyHashes() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("1");
i.literal("1", "one");
i.endEntity();
i.startEntity("2");
i.endEntity();
i.startEntity("3");
i.literal("1", "tre");
i.endEntity();
i.startEntity("4");
i.endEntity();
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().startEntity("1");
o.get().literal("1", "one");
o.get().endEntity();
o.get().startEntity("3");
o.get().literal("1", "tre");
o.get().endEntity();
o.get().endRecord();
}
);
}

@Test
public void shouldDeleteEmptyStrings() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
"vacuum()"
),
i -> {
i.startRecord("1");
i.literal("1", "one");
i.literal("2", "");
i.literal("3", "tre");
i.literal("4", "");
i.endRecord();
}, o -> {
},
o -> {
o.get().startRecord("1");
o.get().literal("1", "one");
o.get().literal("3", "tre");
o.get().endRecord();
});
}
);
}

@Test
public void shouldDeleteEmptyNestedArrays() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("arrays");
i.startEntity("1[]");
i.literal("1", "one");
i.endEntity();
i.startEntity("2[]");
i.endEntity();
i.startEntity("3[]");
i.literal("1", "tre");
i.endEntity();
i.startEntity("4[]");
i.endEntity();
i.endEntity();
i.endRecord();
},
(o, f) -> {
o.get().startRecord("1");
o.get().startEntity("arrays");
o.get().startEntity("1[]");
o.get().literal("1", "one");
o.get().endEntity();
o.get().startEntity("3[]");
o.get().literal("1", "tre");
f.apply(2).endEntity();
o.get().endRecord();
}
);
}

@Test
public void shouldDeleteEmptyNestedHashes() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("hashes");
i.startEntity("1");
i.literal("1", "one");
i.endEntity();
i.startEntity("2");
i.endEntity();
i.startEntity("3");
i.literal("1", "tre");
i.endEntity();
i.startEntity("4");
i.endEntity();
i.endEntity();
i.endRecord();
},
(o, f) -> {
o.get().startRecord("1");
o.get().startEntity("hashes");
o.get().startEntity("1");
o.get().literal("1", "one");
o.get().endEntity();
o.get().startEntity("3");
o.get().literal("1", "tre");
f.apply(2).endEntity();
o.get().endRecord();
}
);
}

@Test
public void shouldDeleteEmptyNestedStrings() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("nested");
i.literal("1", "one");
i.literal("2", "");
i.literal("3", "tre");
i.literal("4", "");
i.endEntity();
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().startEntity("nested");
o.get().literal("1", "one");
o.get().literal("3", "tre");
o.get().endEntity();
o.get().endRecord();
}
);
}

@Test
public void shouldDeleteEmptyDeeplyNestedArrays() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("arrays[]");
i.endEntity();
i.startEntity("hashes");
i.startEntity("foo[]");
i.endEntity();
i.endEntity();
i.literal("me", "1");
i.endRecord();
},
o -> {
o.get().startRecord("1");
o.get().literal("me", "1");
o.get().endRecord();
}
);
}

@Test
public void shouldDeleteEmptyArraysInArrays() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"
),
i -> {
i.startRecord("1");
i.startEntity("arrays[]");
i.startEntity("1[]");
i.endEntity();
i.startEntity("2[]");
i.literal("1", ":-P yuck");
i.endEntity();
i.endEntity();
i.endRecord();
},
(o, f) -> {
o.get().startRecord("1");
o.get().startEntity("arrays[]");
o.get().startEntity("1"); // TODO: Preserve array!? (`1[]`)
o.get().literal("1", ":-P yuck");
f.apply(2).endEntity();
o.get().endRecord();
}
);
}

@Test
Expand All @@ -1566,7 +1780,7 @@ public void nulls() {
@Test
public void repeatToArray() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
"nothing()"),
i -> {
i.startRecord("1");
i.literal("name", "max");
Expand Down Expand Up @@ -1644,7 +1858,7 @@ public void shouldAccessArrayByWildcard() {
@Test
public void repeatToArrayOfObjects() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
"nothing()"),
i -> {
i.startRecord("1");
i.startEntity("author");
Expand Down Expand Up @@ -1697,8 +1911,7 @@ public void accessArrayOfObjectsByIndex() {
// TODO: implement implicit iteration?
public void accessArrayOfObjectsByWildcard() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"upcase('author.*.name')",
"vacuum()"),
"upcase('author.*.name')"),
i -> {
i.startRecord("1");
i.startEntity("author");
Expand Down Expand Up @@ -1726,8 +1939,7 @@ public void accessArrayOfObjectsByDoListBind() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"do list('path':'author','var':'a')",
" upcase('a.name')",
"end",
"vacuum()"),
"end"),
i -> {
i.startRecord("1");
i.startEntity("author");
Expand Down

0 comments on commit 2225a80

Please sign in to comment.