TestSuite.java

package com.github.dakusui.jcunitx.testsuite;

import com.github.dakusui.jcunitx.core.AArray;
import com.github.dakusui.jcunitx.utils.TupleUtils;
import com.github.dakusui.jcunitx.factorspace.Constraint;
import com.github.dakusui.jcunitx.metamodel.ParameterSpace;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.Objects.requireNonNull;

/**
 * As a result of tuple suite generation, tuples that are identical if they are
 * converted back to parameter space can be created.
 * <p>
 * This class eliminates those tuples on its construction.
 */
public interface TestSuite extends List<TestCase> {
  /**
   * Returns a parameter space from which this instance is created.
   *
   * @return parameter space
   */
  ParameterSpace getParameterSpace();

  TestScenario getScenario();

  class Builder<T> {
    private final ParameterSpace parameterSpace;
    private final List<TestCase> testCases = new LinkedList<>();
    private final TestScenario   testScenario;

    public Builder(ParameterSpace parameterSpace, TestScenario testScenario) {
      this.parameterSpace = requireNonNull(parameterSpace);
      this.testScenario = testScenario;
    }

    public Builder<T> addAllToSeedTuples(Collection<? extends AArray> collection) {
      collection.stream().map(each -> toTestCase(TestCase.Category.SEED, each)).forEach(testCases::add);
      return this;
    }

    public Builder<T> addAllToRegularTuples(Collection<? extends AArray> collection) {
      collection.stream().map(each -> toTestCase(TestCase.Category.REGULAR, each)).forEach(testCases::add);
      return this;
    }

    public Builder<T> addAllToNegativeTuples(Collection<? extends AArray> collection) {
      collection.stream().map(each -> toTestCase(TestCase.Category.NEGATIVE, each)).forEach(testCases::add);
      return this;
    }

    private TestCase toTestCase(TestCase.Category category, AArray testCaseTuple) {
      AArray tuple = TupleUtils.copy(testCaseTuple);
      return category.createTestCase(
          tuple,
          this.parameterSpace.getConstraints().stream()
              .filter((Constraint constraint) -> !constraint.test(tuple))
              .collect(Collectors.toList()));
    }

    public TestSuite build() {
      class Impl extends AbstractList<TestCase> implements TestSuite {
        private final List<TestCase> testCases;

        private Impl(
        ) {
          this.testCases = new ArrayList<TestCase>(Builder.this.testCases.size()) {{
            Builder.this.testCases.stream()
                .filter(testCase -> stream().noneMatch(registered -> registered.getTestInput().equals(testCase.getTestInput())))
                .forEach(this::add);
          }};
        }

        @Override
        public TestCase get(int index) {
          return this.testCases.get(index);
        }

        @Override
        public int size() {
          return this.testCases.size();
        }

        @Override
        public ParameterSpace getParameterSpace() {
          return parameterSpace;
        }

        @Override
        public TestScenario getScenario() {
          return testScenario;
        }
      }
      return new Impl();
    }
  }
}