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

org.cthul.matchers.chain.XOrChainMatcher 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.chain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.cthul.matchers.diagnose.nested.Nested;
import org.cthul.matchers.diagnose.result.MatchResult;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;

/**
 * 
 * @param  
 */
public class XOrChainMatcher extends MatcherChainBase {
    
    public XOrChainMatcher(Collection> matchers) {
        super(matchers);
    }

    @SuppressWarnings("unchecked")
    public XOrChainMatcher(Matcher... matchers) {
        super(matchers);
    }

    @Override
    public int getDescriptionPrecedence() {
        return P_OR;
    }

    /** {@inheritDoc} */
    @Override
    public void describeTo(Description description) {
        if (matchers.length == 0) {
            description.appendText("");
        } else {
            Nested.joinDescriptions(getDescriptionPrecedence(), matchersList(), description, " xor ");
        }
    }

    /** {@inheritDoc} */
    @Override
    public boolean matches(Object item) {
        boolean match = false;
        for (Matcher m: matchers) {
            match ^= m.matches(item);
        }
        return match;
    }

    @Override
    public  MatchResult matchResult(I item) {
        List> results = new ArrayList<>(matchers.length);
        boolean match = false;
        for (Matcher m: matchers) {
            MatchResult mr = quickMatchResult(m, item);
            results.add(mr);
            match ^= mr.matched();
        }
        return result(match, item, results);
    }

    private  MatchResult result(boolean match, I item, final List> results) {
        return new NestedResult>(item, this, match) {
            @Override
            public int getDescriptionPrecedence() {
                return P_AND;
            }
            @Override
            public int getMatchPrecedence() {
                return P_AND;
            }
            @Override
            public int getMismatchPrecedence() {
                return P_AND;
            }
            @Override
            public void describeTo(Description d) {
                Nested.joinDescriptions(getDescriptionPrecedence(), results, d, " and ");
            }
            @Override
            public void describeMatch(Description d) {
                describeTo(d);
            }
            @Override
            public void describeMismatch(Description d) {
                describeTo(d);
            }
        };
    }

    @Factory
    @SuppressWarnings("unchecked")
    public static  Matcher xor(Matcher... matchers) {
        return new XOrChainMatcher<>(matchers);
    }
    
    @Factory
    public static  Matcher xor(Collection> matchers) {
        return new XOrChainMatcher<>(matchers);
    }
    
    // no @Factory, use OrChainMatcher.either instead
    public static  OrChainMatcher.Builder either(Matcher m) {
        return new Builder().xor(m);
    }
    
    // no @Factory, use OrChainMatcher.either instead
    public static  OrChainMatcher.Builder either(Matcher... m) {
        return new Builder().xor(m);
    }
    
    public static final ChainFactory FACTORY = new ChainFactoryBase() {
        @Override
        public  Matcher create(Collection> chain) {
            return new XOrChainMatcher<>(chain);
        }
    };
    
    public static class Builder extends OrChainMatcher.Builder {
        public Builder() {
            makeXOR();
        }
    }
}