001/**
002 * Powerunit - A JDK1.8 test framework
003 * Copyright (C) 2014 Mathieu Boretti.
004 *
005 * This file is part of Powerunit
006 *
007 * Powerunit is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation, either version 3 of the License, or
010 * (at your option) any later version.
011 *
012 * Powerunit is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
019 */
020package ch.powerunit.rules;
021
022import java.util.HashMap;
023import java.util.Map;
024import java.util.function.Supplier;
025
026import ch.powerunit.TestRule;
027
028/**
029 * Rule that restore system properties after test.
030 * <p>
031 * This class is exposed by the
032 * {@link ch.powerunit.TestSuite#systemPropertiesRule(String...)
033 * systemPropertiesRule()} method of the {@link ch.powerunit.TestSuite
034 * TestSuite} interface. Direct instantiation of this class should be avoided.
035 * Other methods are also available in the TestSuite interface to set one
036 * property.
037 *
038 * @author borettim
039 *
040 */
041public final class SystemPropertiesRule implements ExternalResource {
042
043    private final String propertiesName[];
044
045    private Map<String, String> values;
046
047    /**
048     * Default constructor.
049     * 
050     * @param propertiesName
051     *            the property names
052     * @see ch.powerunit.TestSuite#systemPropertiesRule(String...) Alternate
053     *      method to have the new construction in favor of a more DSL language.
054     */
055    public SystemPropertiesRule(String... propertiesName) {
056        this.propertiesName = propertiesName;
057    }
058
059    @Override
060    public void before() {
061        values = new HashMap<>();
062        for (String n : propertiesName) {
063            String old = System.getProperty(n);
064            values.put(n, old);
065        }
066    }
067
068    @Override
069    public void after() {
070        for (String n : propertiesName) {
071            String old = values.get(n);
072            if (old == null) {
073                System.clearProperty(n);
074            } else {
075                System.setProperty(n, old);
076            }
077        }
078    }
079
080    /**
081     * Set a system property before a test and ensure the correct restore.
082     * 
083     * @param propertyName
084     *            the property name
085     * @param propertyValue
086     *            the property value
087     * @return the test rule to do so
088     */
089    public static TestRule setSystemPropertyBeforeTestAndRestoreAfter(
090            String propertyName, Supplier<String> propertyValue) {
091        return new SystemPropertiesRule(propertyName).around(TestRule
092                .before(() -> System.setProperty(propertyName,
093                        propertyValue.get())));
094    }
095
096    /**
097     * Set a system property before a test and ensure the correct restore.
098     * 
099     * @param propertyName
100     *            the property name
101     * @param propertyValue
102     *            the property value
103     * @return the test rule to do so
104     */
105    public static TestRule setSystemPropertyBeforeTestAndRestoreAfter(
106            String propertyName, String propertyValue) {
107        return setSystemPropertyBeforeTestAndRestoreAfter(propertyName,
108                () -> propertyValue);
109    }
110
111}