All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cthul.matchers.object.CIs Maven / Gradle / Ivy

Go to download

Provides hamcrest.org matchers for strings and exceptions, allows matching code blocks, and provides several utilities for combining matchers.

The newest version!
package org.cthul.matchers.object;

import java.util.Objects;
import org.cthul.matchers.diagnose.nested.NestedResultMatcher;
import org.cthul.matchers.diagnose.result.MatchResult;
import org.hamcrest.*;

public class CIs extends NestedResultMatcher {
    
    @Factory
    public static  CIs is(Matcher matcher) {
        return new CIs<>(matcher, "is", false);
    }
    
    @Factory
    public static  CIs has(Matcher matcher) {
        return new CIs<>(matcher, "has", false);
    }
    
    @Factory
    public static  CIs not(Matcher matcher) {
        return new CIs<>(matcher, null, true);
    }
    
    @Factory
    public static  CIs isNot(Matcher matcher) {
        return new CIs<>(matcher, "is", true);
    }
    
    @Factory
    public static  CIs _is(Matcher matcher) {
        return new CIs<>(matcher, "is", false);
    }
    
    @Factory
    public static  CIs _has(Matcher matcher) {
        return new CIs<>(matcher, "has", false);
    }
    
    @Factory
    public static  CIs _not(Matcher matcher) {
        return new CIs<>(matcher, null, true);
    }
    
    @Factory
    public static  CIs _isNot(Matcher matcher) {
        return new CIs<>(matcher, "is", true);
    }

    private final Matcher nested;
    private final String prefix;
    private final String pastPrefix;
    private final boolean not;

    public CIs(Matcher nested, String prefix, boolean not) {
        this.nested = nested;
        this.prefix = prefix;
        this.pastPrefix = pastPrefix(prefix);
        this.not = not;
    }

    public CIs(Matcher nested, String prefix, String pastPrefix, boolean not) {
        this.nested = nested;
        this.prefix = prefix;
        this.pastPrefix = pastPrefix;
        this.not = not;
    }

    public CIs(Matcher nested) {
        this(nested, "is", false);
    }

    @Override
    public boolean matches(Object o) {
        return not ^ nested.matches(o);
    }
    
    @Override
    public boolean matches(Object o, Description d) {
        if (matches(o)) return true;
        describeMismatch(o, d);
        return false;
    }

    @Override
    public void describeTo(Description description) {
        if (prefix != null) {
            description.appendText(prefix).appendText(" ");
        }
        if (not) {
            description.appendText("not ");
        }
        nestedDescribeTo(nested, description);
    }

    @Override
    public int getDescriptionPrecedence() {
        return not ? P_UNARY : P_UNARY_NO_PAREN;
    }

    @Override
    public  MatchResult matchResult(I item) {
        final MatchResult result = quickMatchResult(nested, item);
        return new NestedResult>(item, this, not ^ result.matched()) {
            @Override
            public void describeMatch(Description d) {
                // in positive mode, nested match will be "was a good thing"
                // in negative mode, nested match will be "was "
                if (!not) {
                    d.appendValue(getValue()).appendText(" ");
//                    appendPastPrefix(d); <-- don't!
                }
                nestedDescribeTo(getMatchPrecedence(), result, d);
            }
            @Override
            public void describeExpected(Description d) {
                if (prefix != null) {
                    d.appendText(prefix).appendText(" ");
                }
                if (not) {
                    d.appendText("not ");
                    nestedDescribeTo(getExpectedPrecedence(), result.getMatcherDescription(), d);
                    //nestedDescribeTo(getExpectedPrecedence(), result, d);
                } else {
                    nestedDescribeTo(getExpectedPrecedence(), result.getMismatch().getExpectedDescription(), d);
                }
            }
            @Override
            public void describeMismatch(Description d) {
                // in positive mode, nested match will be "was "
                // in negative mode, nested match will be "was a good thing"
                if (not) {
                    d.appendValue(getValue()).appendText(" ");
//                    appendPastPrefix(d); <-- don't
                } 
                nestedDescribeTo(getMismatchPrecedence(), result, d);
            }
        };
    }
    
    protected void appendPastPrefix(Description d) {
        if (pastPrefix != null) {
            d.appendText(pastPrefix).appendText(" ");
        }
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + Objects.hashCode(this.nested);
        hash = 29 * hash + Objects.hashCode(this.prefix);
        hash = 29 * hash + Objects.hashCode(this.pastPrefix);
        hash = 29 * hash + (this.not ? 1 : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CIs other = (CIs) obj;
        if (!Objects.equals(this.nested, other.nested)) {
            return false;
        }
        if (!Objects.equals(this.prefix, other.prefix)) {
            return false;
        }
        if (!Objects.equals(this.pastPrefix, other.pastPrefix)) {
            return false;
        }
        if (this.not != other.not) {
            return false;
        }
        return true;
    }

    public static String pastPrefix(String prefix) {
        if (prefix != null) {
//            switch (prefix) {
//                case "is":
//                    return "was";
//                case "has":
//                    return "had";
//                default:
//                    return prefix;
//            }
            if (prefix.equals("is")) {
                return "was";
            }
            if (prefix.equals("has")) {
                return "had";
            }
            return prefix;
        }
        return null;
    }
    
    public static  Matcher wrap(String prefix, boolean not, Matcher matcher) {
        if (prefix == null && !not) {
            return (Matcher) matcher;
        } else {
            return new CIs<>(matcher, prefix, not);
        }
    }
    
}