Package net.thucydides.core.requirements.reports

Source Code of net.thucydides.core.requirements.reports.RequirementsOutcomes

package net.thucydides.core.requirements.reports;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.thucydides.core.ThucydidesSystemProperty;
import net.thucydides.core.issues.IssueTracking;
import net.thucydides.core.model.*;
import net.thucydides.core.releases.ReleaseManager;
import net.thucydides.core.reports.TestOutcomes;
import net.thucydides.core.reports.html.ReportNameProvider;
import net.thucydides.core.requirements.RequirementsTagProvider;
import net.thucydides.core.requirements.model.Requirement;
import net.thucydides.core.util.EnvironmentVariables;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import static ch.lambdaj.Lambda.*;
import static org.hamcrest.Matchers.hasItem;

/**
* A set of test results for a list of high-level requirements.
*/
public class RequirementsOutcomes {
    private final List<RequirementOutcome> requirementOutcomes;
    private final TestOutcomes testOutcomes;
    private final Optional<Requirement> parentRequirement;
    private final EnvironmentVariables environmentVariables;
    private final IssueTracking issueTracking;
    private final List<RequirementsTagProvider> requirementsTagProviders;
    private final ReleaseManager releaseManager;

    public final static Integer DEFAULT_TESTS_PER_REQUIREMENT = 4;

    public RequirementsOutcomes(List<Requirement> requirements,
                                TestOutcomes testOutcomes,
                                IssueTracking issueTracking,
                                EnvironmentVariables environmentVariables,
                                List<RequirementsTagProvider> requirementsTagProviders) {
        this(null, requirements, testOutcomes, issueTracking, environmentVariables, requirementsTagProviders);
    }

    public RequirementsOutcomes(Requirement parentRequirement, List<Requirement> requirements, TestOutcomes testOutcomes,
                                IssueTracking issueTracking, EnvironmentVariables environmentVariables,
                                List<RequirementsTagProvider> requirementsTagProviders) {
        this.testOutcomes = testOutcomes;
        this.parentRequirement = Optional.fromNullable(parentRequirement);
        this.environmentVariables = environmentVariables;
        this.issueTracking = issueTracking;
        this.requirementsTagProviders = requirementsTagProviders;
        this.requirementOutcomes = buildRequirementOutcomes(requirements, requirementsTagProviders);
        this.releaseManager = new ReleaseManager(environmentVariables, new ReportNameProvider());
    }

    private List<RequirementOutcome> buildRequirementOutcomes(List<Requirement> requirements,
                                                              List<RequirementsTagProvider> requirementsTagProviders) {
        List<RequirementOutcome> outcomes = Lists.newArrayList();
        for (Requirement requirement : requirements) {
            buildRequirements(outcomes, requirementsTagProviders, requirement);
        }
        return outcomes;
    }

    public RequirementsOutcomes requirementsOfType(String type) {
        List<Requirement> matchingRequirements = Lists.newArrayList();
        List<TestOutcome> matchingTests = Lists.newArrayList();
        for(RequirementOutcome requirementOutcome : getFlattenedRequirementOutcomes()) {
            if (requirementOutcome.getRequirement().getType().equalsIgnoreCase(type)) {
                matchingRequirements.add(requirementOutcome.getRequirement());
                matchingTests.addAll(requirementOutcome.getTestOutcomes().getOutcomes());
            }
        }

        return new RequirementsOutcomes(matchingRequirements,
                                        TestOutcomes.of(matchingTests),
                                        issueTracking, environmentVariables, requirementsTagProviders);
    }

    private void buildRequirements(List<RequirementOutcome> outcomes, List<RequirementsTagProvider> requirementsTagProviders, Requirement requirement) {
        TestOutcomes outcomesForRequirement = testOutcomes.forRequirement(requirement);

        int requirementsWithoutTests = countRequirementsWithoutTestsIn(requirement);
        int estimatedUnimplementedTests = requirementsWithoutTests * estimatedTestsPerRequirement();
        outcomes.add(new RequirementOutcome(requirement, outcomesForRequirement, requirementsWithoutTests,
                                            estimatedUnimplementedTests, issueTracking));
    }

    private int countRequirementsWithoutTestsIn(Requirement rootRequirement) {
        List<Requirement> flattenedRequirements = getFlattenedRequirements(rootRequirement);

        int requirementsWithoutTests = 0;
        for(Requirement requirement : flattenedRequirements) {
            TestOutcomes matchingOutcomes = testOutcomes.withTag(requirement.asTag());
            if (matchingOutcomes.getTotal() == 0) {
                requirementsWithoutTests++;
            }
        }
        return requirementsWithoutTests;
    }

    public int getFlattenedRequirementCount() {
        int requirementCount = 0;
        for (RequirementOutcome requirement : requirementOutcomes) {
            requirementCount += requirement.getFlattenedRequirementCount();

        }
        return requirementCount;
    }

    private List<Requirement> getFlattenedRequirements(Requirement rootRequirement) {
        List<Requirement> flattenedRequirements = Lists.newArrayList();
        flattenedRequirements.add(rootRequirement);
        flattenedRequirements.addAll(rootRequirement.getNestedChildren());
        return flattenedRequirements;
    }

    public Optional<Requirement> getParentRequirement() {
        return parentRequirement;
    }

    public int getRequirementCount() {
        return requirementOutcomes.size();
    }

    public List<RequirementOutcome> getRequirementOutcomes() {
        return ImmutableList.copyOf(requirementOutcomes);
    }

    public String getType() {
        if (requirementOutcomes.isEmpty()) {
            return "requirement";
        } else {
            return requirementOutcomes.get(0).getRequirement().getType();
        }
    }

    public String getChildrenType() {
        return typeOfFirstChildPresent();
    }

    public List<String> getTypes() {
        List<Requirement> requirements = getAllRequirements();
        List<String> types = Lists.newArrayList();
        for (Requirement requirement : requirements) {
            if (!types.contains(requirement.getType())) {
                types.add(requirement.getType());
            }
        }
        return types;
    }

    private String typeOfFirstChildPresent() {
        for (RequirementOutcome outcome : requirementOutcomes) {
            if (!outcome.getRequirement().getChildren().isEmpty()) {
                Requirement firstChildRequirement = outcome.getRequirement().getChildren().get(0);
                return firstChildRequirement.getType();
            }
        }
        return null;
    }

    public TestOutcomes getTestOutcomes() {
        return testOutcomes;
    }

    @Override
    public String toString() {
        return "RequirementsOutcomes{" +
                "requirementOutcomes=" + requirementOutcomes +
                ", parentRequirement=" + parentRequirement +
                '}';
    }

    public int getCompletedRequirementsCount() {
        int completedRequirements = 0;
        for (RequirementOutcome requirementOutcome : requirementOutcomes) {
            if (requirementOutcome.isComplete()) {
                completedRequirements++;
            }
        }
        return completedRequirements;
    }

    public int getFailingRequirementsCount() {
        int failingRequirements = 0;
        for (RequirementOutcome requirementOutcome : requirementOutcomes) {
            if (requirementOutcome.isFailure() || requirementOutcome.isError()) {
                failingRequirements++;
            }
        }
        return failingRequirements;
    }

    public int getPendingRequirementsCount() {
        int total = 0;
        for (RequirementOutcome requirementOutcome : requirementOutcomes) {
            if (requirementOutcome.isPending()) {
                total++;
            }
        }
        return total;
    }

    public int getIgnoredRequirementsCount() {
        int total = 0;
        for (RequirementOutcome requirementOutcome : requirementOutcomes) {
            if (requirementOutcome.isIgnored()) {
                total++;
            }
        }
        return total;
    }

    public int getRequirementsWithoutTestsCount() {
        int requirementsWithNoTests = 0;
        List<RequirementOutcome> flattenedRequirementOutcomes = getFlattenedRequirementOutcomes();

        for (Requirement requirement : getAllRequirements()) {
            if (!testsRecordedFor(flattenedRequirementOutcomes, requirement)) {
                requirementsWithNoTests++;
            }
        }
        return requirementsWithNoTests;
    }

    private boolean testsRecordedFor(List<RequirementOutcome> outcomes, Requirement requirement) {
        for (RequirementOutcome outcome : outcomes) {
            if (outcome.testsRequirement(requirement) && outcome.getTestCount() > 0) {
                return true;
            }
        }
        return false;
    }

    private List<Requirement> getAllRequirements() {
        List<Requirement> allRequirements = Lists.newArrayList();
        for (RequirementOutcome outcome : requirementOutcomes) {
            addFlattenedRequirements(outcome.getRequirement(), allRequirements);
        }
        return ImmutableList.copyOf(allRequirements);
    }

    public int getTotalRequirements() {
        return getAllRequirements().size();
    }

    private void addFlattenedRequirements(Requirement requirement, List<Requirement> allRequirements) {
        allRequirements.add(requirement);
        for (Requirement child : requirement.getChildren()) {
            addFlattenedRequirements(child, allRequirements);
        }
    }

    List<RequirementOutcome> flattenedRequirementOutcomes = null;

    public List<RequirementOutcome> getFlattenedRequirementOutcomes() {
        if (flattenedRequirementOutcomes == null) {
            flattenedRequirementOutcomes = getFlattenedRequirementOutcomes(requirementOutcomes);
        }
        return flattenedRequirementOutcomes;
    }

    public List<RequirementOutcome> getFlattenedRequirementOutcomes(List<RequirementOutcome> outcomes) {
        Set<RequirementOutcome> flattenedOutcomes = Sets.newHashSet();

        for (RequirementOutcome requirementOutcome : outcomes) {
            flattenedOutcomes.add(requirementOutcome);
            for(Requirement requirement : requirementOutcome.getRequirement().getChildren()) {

//                TestTag requirementTag = TestTag.withName(requirement.getName()).andType(requirement.getType());
//                TestOutcomes testOutcomesForRequirement = requirementOutcome.getTestOutcomes().withTag(requirementTag);

                TestOutcomes testOutcomesForRequirement = requirementOutcome.getTestOutcomes().withTag(requirement.asTag());



                flattenedOutcomes.add(new RequirementOutcome(requirement, testOutcomesForRequirement, issueTracking));

                List<Requirement> childRequirements = requirement.getChildren();
                RequirementsOutcomes childOutcomes =
                        new RequirementsOutcomes(childRequirements, testOutcomesForRequirement, issueTracking,
                                                 environmentVariables, requirementsTagProviders);
                flattenedOutcomes.addAll(getFlattenedRequirementOutcomes(childOutcomes.getRequirementOutcomes()));
            }
        }

        return ImmutableList.copyOf(flattenedOutcomes);
    }

    public OutcomeCounter getTotal() {
        return count(TestType.ANY);
    }

    public OutcomeCounter count(TestType testType) {
        return new OutcomeCounter(testType, getTestOutcomes());
    }

    public OutcomeCounter count(String testType) {
        return count(TestType.valueOf(testType.toUpperCase()));
    }

    public int getTotalTestCount() {
        return testOutcomes.getTotal();
    }

    /**
     * @return Formatted version of the test coverage metrics
     */
    public RequirementsPercentageFormatter getFormattedPercentage() {
        return new RequirementsPercentageFormatter(getProportion());
    }

    public RequirementsPercentageFormatter getFormattedPercentage(String testType) {
        return new RequirementsPercentageFormatter(proportionOf(testType));
    }

    public RequirementsPercentageFormatter getFormattedPercentage(TestType testType) {
        return new RequirementsPercentageFormatter(proportionOf(testType));
    }

    private int totalEstimatedAndImplementedTests() {
        int totalImplementedTests = getTotalTestCount();
        return totalImplementedTests + getEstimatedUnimplementedTests();
    }

    public int getEstimatedUnimplementedTests() {
        return getRequirementsWithoutTestsCount() * estimatedTestsPerRequirement();
    }

    private int estimatedTestsPerRequirement() {
        return environmentVariables.getPropertyAsInteger(ThucydidesSystemProperty.THUCYDIDES_ESTIMATED_TESTS_PER_REQUIREMENT.toString(),
                DEFAULT_TESTS_PER_REQUIREMENT);
    }

    public RequirementsProportionCounter getProportion() {
        return proportionOf(TestType.ANY);
    }

    public RequirementsProportionCounter proportionOf(String testType) {
        return proportionOf(TestType.valueOf(testType.toUpperCase()));
    }

    public RequirementsProportionCounter proportionOf(TestType testType) {
        return new RequirementsProportionCounter(testType, testOutcomes, totalEstimatedAndImplementedTests());
    }

    public RequirementsOutcomes getReleasedRequirementsFor(Release release) {
        List<Requirement> matchingRequirements = Lists.newArrayList();
        List<TestOutcome> matchingTestOutcomes = Lists.newArrayList();

        // Add all test outcomes with a matching release

        List<RequirementOutcome> requirementOutcomes
                = releaseManager.enrichRequirementsOutcomesWithReleaseTags(getRequirementOutcomes());

        for(RequirementOutcome outcome : requirementOutcomes) {
            Collection<String> releaseVersions = outcome.getReleaseVersions();
            if (releaseVersions.contains(release.getName())) {
                List<TestOutcome> outcomesForRelease = outcomesForRelease(outcome.getTestOutcomes().getOutcomes(), release.getName());
                if (!outcomesForRelease.isEmpty()) {
                    matchingTestOutcomes.addAll(outcomesForRelease);
                    matchingRequirements.add(outcome.getRequirement());
                }
            }
        }
        matchingRequirements = removeRequirementsWithoutTestsFrom(matchingRequirements);
        return new RequirementsOutcomes(Lists.newArrayList(matchingRequirements),
                                        TestOutcomes.of(matchingTestOutcomes),
                                        issueTracking,
                                        environmentVariables,
                                        requirementsTagProviders);
    }

    private List<Requirement> removeRequirementsWithoutTestsFrom(List<Requirement> requirements) {
        List<Requirement> prunedRequirements = Lists.newArrayList();
        for(Requirement requirement : requirements) {
            if (testsExistFor(requirement)) {
                List<Requirement> prunedChildren = removeRequirementsWithoutTestsFrom(requirement.getChildren());
                prunedRequirements.add(requirement.withChildren(prunedChildren));
            }
        }
        return ImmutableList.copyOf(prunedRequirements);
    }

    private boolean testsExistFor(Requirement requirement) {
        TestTag requirementTag = TestTag.withName(requirement.getName()).andType(requirement.getType());
        return !getTestOutcomes().withTag(requirementTag).getOutcomes().isEmpty();
        //return !getTestOutcomes().withTag(requirement.asTag()).getOutcomes().isEmpty();
    }

    private List<TestOutcome> outcomesForRelease(List<? extends TestOutcome> outcomes,
                                                 String releaseName) {
        releaseManager.enrichOutcomesWithReleaseTags(outcomes);
        return (List<TestOutcome>) filter(having(on(TestOutcome.class).getVersions(), hasItem(releaseName)), outcomes);
    }
}
TOP

Related Classes of net.thucydides.core.requirements.reports.RequirementsOutcomes

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.