Add implements Scalar<T> { @Override public T value(final Field<T> field) { final FieldAddition<T> addition = field.addition(); T result = addition.neutral(); for (final Scalar<T> operand : this.operands()) { result = addition.add(result, operand.value(field)); } return result; } Add(final Iterable<? extends Scalar<T>> operands);  Add(final Scalar<T> first, final Scalar<T> second); Iterable<Scalar<T>> operands(); @Override T value(final Field<T> field);  }
@Test public void addDelegatesToFieldAddition() { final Scalar<Object> first = new Scalar.Default<>(new Object()); final Scalar<Object> second = new Scalar.Default<>(new Object()); final MkAddition<Object> add = new MkAddition<>(new Object()); final SpyField<Object> field = new SpyField<>( new MkField<Object>(new Object(), add) ); final List<Scalar<Object>> operands = Arrays.asList(first, second, first); new Add<>(operands).value(field); MatcherAssert.assertThat( field.calls().additioned(), Matchers.is(true) ); MatcherAssert.assertThat( add.neutraled(), Matchers.is(true) ); MatcherAssert.assertThat( add.added(), Matchers.is(operands.size()) ); }