/** * Powerunit - A JDK1.8 test framework * Copyright (C) 2014 Mathieu Boretti. * * This file is part of Powerunit * * Powerunit is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Powerunit is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Powerunit. If not, see <http://www.gnu.org/licenses/>. */ package ch.powerunit.pattern; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.regex.Pattern; import org.hamcrest.Matcher; import ch.powerunit.TestInterface; import ch.powerunit.TestSuite; import ch.powerunit.pattern.impl.PatternTesterImpl; import ch.powerunit.pattern.lang.PatternTester0; import ch.powerunit.pattern.lang.PatternTester1; import ch.powerunit.pattern.lang.PatternTester2; import ch.powerunit.pattern.lang.PatternTester3; import ch.powerunit.pattern.lang.PatternTester4; /** * This is a tester to validate {@link Pattern}. * <p> * This tester will validate that a Pattern accept ( * {@link Pattern#matcher(CharSequence)}) or not a specified string ; In the * first case (accepted), it also provide a way to validate the groups ( * {@link java.util.regex.Matcher#group(int)}). * * @author borettim * @since 0.4.0 */ @TestInterface(PatternTesterImpl.class) public final class PatternTester { private final Pattern underTest; private final List<String> inputs; private final List<Boolean> expectedResult; private final List<List<Integer>> havingGroup; private final List<List<Matcher<String>>> expectedGroup; private PatternTester(Pattern underTest, List<String> inputs, List<Boolean> expectedResult, List<List<Integer>> havingGroup, List<List<Matcher<String>>> expectedGroup) { this.underTest = underTest; this.inputs = inputs; this.expectedResult = expectedResult; this.havingGroup = havingGroup; this.expectedGroup = expectedGroup; } /** * Start the DSL to create a tester of Pattern, based on a String. * <p> * The passed String will be compiled as a Pattern. <br> * For instance : * * <pre> * @TestDelegate * public final PatternTester sample1 = PatternTester.of("a+").receiving("b") * .thenNoMatching().receiving("aa").thenMatching().build(); * </pre> * * @param pattern * the pattern, as a String * @return {@link PatternTester0#receiving(String) The next step of the * DSL.} * @see #of(Pattern) */ public static PatternTester0 of(String pattern) { return of(Pattern.compile(pattern)); } /** * Start the DSL to create a tester of Pattern, based on a String. * <p> * For instance : * * <pre> * @TestDelegate * public final PatternTester sample1 = PatternTester.of(Pattern.compile("a+")) * .receiving("b").thenNoMatching().receiving("aa").thenMatching().build(); * </pre> * * @param pattern * the pattern. * @return {@link PatternTester0#receiving(String) The next step of the * DSL.} */ public static PatternTester0 of(Pattern pattern) { return new PatternTesterDSL(pattern); } private static class PatternTesterDSL implements PatternTester0, PatternTester1, PatternTester2, PatternTester3, PatternTester4 { private final Pattern underTest; private final List<String> inputs = new ArrayList<>(); private final List<Boolean> expectedResult = new ArrayList<>(); private final List<List<Integer>> havingGroup = new ArrayList<>(); private final List<List<Matcher<String>>> expectedGroup = new ArrayList<>(); private List<Integer> currentGroup = null; private List<Matcher<String>> currentExpected = null; private PatternTesterDSL initMatching(boolean expected) { expectedResult.add(expected); currentGroup = new ArrayList<>(); currentExpected = new ArrayList<>(); havingGroup.add(Collections.unmodifiableList(currentGroup)); expectedGroup.add(Collections.unmodifiableList(currentExpected)); return this; } /** * @param underTest */ private PatternTesterDSL(Pattern underTest) { this.underTest = underTest; } @Override public PatternTester2 receiving(String input) { inputs.add(Objects.requireNonNull(input, "input can't be null")); return this; } @Override public PatternTester1 thenNoMatching() { return initMatching(false); } @Override public PatternTester3 thenMatching() { return initMatching(true); } @Override public PatternTester4 havingGroup(int number) { if (number < 0) { throw new IllegalArgumentException("Number can't be <0"); } currentGroup.add(number); return this; } @Override public PatternTester3 matching(Matcher<String> matching) { currentExpected.add(Objects.requireNonNull(matching, "matching can't be null")); return this; } @Override public PatternTester3 equalTo(String equalTo) { return matching(TestSuite.DSL.equalTo(Objects.requireNonNull( equalTo, "equalTo can't be null"))); } @Override public PatternTester build() { return new PatternTester(underTest, inputs, expectedResult, havingGroup, expectedGroup); } } /** * Used by the framework. * * @return the underTest */ public Pattern getUnderTest() { return underTest; } /** * Used by the framework. * * @return the inputs */ public List<String> getInputs() { return Collections.unmodifiableList(inputs); } /** * Used by the framework. * * @return the expectedResult */ public List<Boolean> getExpectedResult() { return Collections.unmodifiableList(expectedResult); } /** * Used by the framework. * * @return the havingGroup */ public List<List<Integer>> getHavingGroup() { return Collections.unmodifiableList(havingGroup); } /** * Used by the framework. * * @return the expectedGroup */ public List<List<Matcher<String>>> getExpectedGroup() { return Collections.unmodifiableList(expectedGroup); } }