package com.codepoetics.octarine.testutils;
import com.codepoetics.octarine.functional.paths.Path;
import com.codepoetics.octarine.records.Record;
import com.codepoetics.octarine.records.Schema;
import com.codepoetics.octarine.records.Validation;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import java.util.Optional;
import static org.hamcrest.CoreMatchers.equalTo;
public class ARecord extends TypeSafeDiagnosingMatcher<Record> {
public static ARecord instance() {
return new ARecord(Optional.<Schema<?>>empty());
}
public static <T> ARecord validAgainst(Schema<T> schema) {
return new ARecord(Optional.of(schema));
}
private final Optional<Schema<?>> schema;
private final AnInstance<Record> instanceMatcher;
private ARecord(Optional<Schema<?>> schema) {
this.schema = schema;
this.instanceMatcher = AnInstance.of(Record.class);
}
private ARecord(Optional<Schema<?>> schema, AnInstance<Record> instanceMatcher) {
this.schema = schema;
this.instanceMatcher = instanceMatcher;
}
public <V> ARecord with(Path<Record, V> path, Matcher<? extends V> matcher) {
return new ARecord(schema, instanceMatcher.with(path, Present.and(matcher)));
}
public <V> ARecord with(Path<Record, V> path, V value) {
return new ARecord(schema, instanceMatcher.with(path, Present.and(equalTo(value))));
}
public <V> ARecord without(Path<Record, V> path) {
return new ARecord(schema, instanceMatcher.with(path, equalTo(Optional.<V>empty())));
}
@Override
protected boolean matchesSafely(Record record, Description description) {
if (schema.isPresent()) {
Validation<?> validation = schema.get().validate(record);
if (!validation.isValid()) {
validation.validationErrors().forEach(e -> description.appendText("\n").appendText(e));
return false;
}
}
return instanceMatcher.matchesSafely(record, description);
}
@Override
public void describeTo(Description description) {
instanceMatcher.describeTo(description);
if (schema.isPresent()) {
description.appendText("\nValid against: ").appendValue(schema.get());
}
}
}