com.gtcgroup.jped.test.core.rulechain.JptRuleChain.java Source code

Java tutorial

Introduction

Here is the source code for com.gtcgroup.jped.test.core.rulechain.JptRuleChain.java

Source

/*
 * [Licensed per the Open Source "MIT License".]
 *
 * Copyright (c) 2006 - 2016 by
 * Global Technology Consulting Group, Inc. at
 * http://gtcGroup.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.gtcgroup.jped.test.core.rulechain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.Rule;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.gtcgroup.jped.test.core.base.JptBaseForClassRule;
import com.gtcgroup.jped.test.core.base.JptBaseForSuiteRule;
import com.gtcgroup.jped.test.core.cs.internal.DisplayRuleMessagesCacheHelper;
import com.gtcgroup.jped.test.core.exception.internal.TestingException;
import com.gtcgroup.jped.test.core.rule.internal.InnerRule;
import com.gtcgroup.jped.test.core.rule.internal.OuterRule;

/**
 * This {@link RuleChain} class manages the {@link Rule} life cycle.
 *
 * <p style="font-family:Verdana; font-size:10px; font-style:italic">
 * Copyright (c) 2006 - 2016 by Global Technology Consulting Group, Inc. at
 * <a href="http://gtcGroup.com">gtcGroup.com </a>.
 * </p>
 *
 * @author Marvin Toll
 * @since v3.0
 */
public class JptRuleChain implements TestRule {

    private static final JptRuleChain EMPTY_CHAIN = new JptRuleChain(Collections.<TestRule>emptyList());

    /** Enables determination of prior invocation. */
    protected static List<String> suiteRuleInstanceList = new ArrayList<String>();

    /** Enables determination of prior invocation. */
    protected static List<String> classRuleInstanceList = new ArrayList<String>();

    /** TODO: Field for */
    public static StringBuilder rulesDisplayedInMethodFooter;

    /** TODO: Field for */
    public static AssertionError assertionFailure;

    /** TODO: Field for */
    public static Throwable exceptionError;

    /** TODO: Field for */
    public static Description description;

    /**
     * @return a {@code JptRuleChain} without a {@link TestRule}.
     */
    public static JptRuleChain emptyRuleChain() {
        return JptRuleChain.EMPTY_CHAIN;
    }

    /**
     * @return a {@code JptRuleChain}
     */
    public static JptRuleChain outerRule() {

        JptRuleChain.assertionFailure = null;
        JptRuleChain.exceptionError = null;

        JptRuleChain.rulesDisplayedInMethodFooter = new StringBuilder();

        return JptRuleChain.emptyRuleChain().around(null);
    }

    /**
     * @param testRule
     * @return {@code JptRuleChain}
     */
    public static JptRuleChain outerRule(final TestRule testRule) {

        final JptRuleChain ruleChain = JptRuleChain.outerRule();
        return ruleChain.around(testRule);

    }

    /**
     * @param testRule
     * @return boolean
     */
    protected static boolean isRuleAlreadyInvoked(final TestRule testRule) {

        boolean result = false;

        try {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
            final String testRuleKey = mapper.writeValueAsString(testRule);

            if (testRule instanceof JptBaseForSuiteRule) {

                if (JptRuleChain.suiteRuleInstanceList.contains(testRuleKey)) {

                    result = true;
                }

                JptRuleChain.suiteRuleInstanceList.add(testRuleKey);

            } else if (testRule instanceof JptBaseForClassRule) {

                if (JptRuleChain.classRuleInstanceList.contains(testRuleKey)) {

                    result = true;
                }

                JptRuleChain.suiteRuleInstanceList.add(testRuleKey);
            }
        } catch (final Exception e) {
            throw new TestingException("TODO: message", e);
        }
        return result;

    }

    private final List<TestRule> ruleListStartingWithInnerMost;

    private JptRuleChain(final List<TestRule> rules) {

        this.ruleListStartingWithInnerMost = rules;
    }

    /**
     * @see TestRule#apply(org.junit.runners.model.Statement, org.junit.runner.
     *      Description)
     */
    @Override
    public Statement apply(final Statement base, final Description description) {

        JptRuleChain.description = description;

        Statement statement = base;

        for (final TestRule testRule : this.ruleListStartingWithInnerMost) {

            statement = testRule.apply(statement, description);
        }
        return statement;
    }

    /**
     * Create a new {@code JptRuleChain}.
     *
     * @param testRule
     * @return {@link JptRuleChain}
     */
    public JptRuleChain around(final TestRule testRule) {

        TestRule rule = testRule;

        if (null == rule) {

            rule = new OuterRule();

        } else if (JptRuleChain.isRuleAlreadyInvoked(testRule)) {

            return this;

        } else

        {
            JptRuleChain.rulesDisplayedInMethodFooter
                    .append(DisplayRuleMessagesCacheHelper.formatRuleForMethodFooter(testRule.getClass()));
        }

        if (

        isFirstRuleTheInnerMostRule()) {
            this.ruleListStartingWithInnerMost.remove(0);
        }

        return createRuleChain(rule);
    }

    /**
     * @param enclosedRule
     * @param innerRule
     * @return
     */
    private JptRuleChain createRuleChain(final TestRule enclosedRule) {

        final List<TestRule> rulesOfNewChain = new ArrayList<TestRule>();

        rulesOfNewChain.add(new InnerRule());
        rulesOfNewChain.add(enclosedRule);
        rulesOfNewChain.addAll(this.ruleListStartingWithInnerMost);

        return new JptRuleChain(rulesOfNewChain);
    }

    private boolean isFirstRuleTheInnerMostRule() {

        return !this.ruleListStartingWithInnerMost.isEmpty()
                && InnerRule.equalsStatic(this.ruleListStartingWithInnerMost.get(0));
    }
}