blob: 1cdb576b05d023636d3dec46320b402c5ef75061 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.test.params;
import org.junit.Assert;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* A set of parameters for one *SINGLE* test method or test class constructor.
*
* For example, <code>new ParameterSet().value("a", "b")</code> is intended for
* a test method/constructor that takes in two string as arguments.
* <code>public void testSimple(String a, String b) {...}</code>
* or
* <code>public MyTestClass(String a, String b) {...}</code>
*
* To parameterize testSimple or MyTestClass's tests, create multiple ParameterSets
* <code>
* static List<ParameterSet> sAllParameterSets = new ArrayList<>();
* static {
* sAllParameterSets.add(new ParameterSet().value("a", "b");
* sAllParameterSets.add(new ParameterSet().value("c", "d");
* }
*/
public class ParameterSet {
private List<Object> mValues;
private String mName;
public ParameterSet() {}
public ParameterSet value(Object firstArg, Object... objects) {
List<Object> parameterList = new ArrayList<Object>();
parameterList.add(firstArg);
parameterList.addAll(Arrays.asList(objects));
Assert.assertTrue(
"Can not create ParameterSet with no parameters", parameterList.size() != 0);
mValues = validateAndCopy(parameterList);
return this;
}
public ParameterSet name(String name) {
mName = name;
return this;
}
@Override
public String toString() {
if (mValues == null) {
return "null";
}
return Arrays.toString(mValues.toArray());
}
private List<Object> validateAndCopy(List<Object> values) {
List<Object> tempValues = new ArrayList<>();
for (Object o : values) {
if (o == null) {
tempValues.add(null);
} else {
if (o.getClass().isPrimitive() || ACCEPTABLE_TYPES.contains(o.getClass())
|| o instanceof Callable) {
tempValues.add(o);
} else {
// TODO(yolandyan): maybe come up with way to support
// complex object while handling immutability at the
// same time
throw new IllegalArgumentException("Type \"%s\" is not supported in"
+ " parameterized testing at this time. Accepted types include"
+ " all primitive types along with "
+ Arrays.toString(ACCEPTABLE_TYPES.toArray(
new String[ACCEPTABLE_TYPES.size()])));
}
}
}
return Collections.unmodifiableList(tempValues);
}
String getName() {
if (mName == null) {
return "";
}
return mName;
}
List<Object> getValues() {
return mValues;
}
int size() {
if (mValues == null) return 0;
return mValues.size();
}
private static final Set<Class<?>> ACCEPTABLE_TYPES = getAcceptableTypes();
/**
* Any immutable class is acceptable.
*/
private static Set<Class<?>> getAcceptableTypes() {
Set<Class<?>> ret = new HashSet<Class<?>>();
ret.add(Boolean.class);
ret.add(Byte.class);
ret.add(Character.class);
ret.add(Class.class);
ret.add(Double.class);
ret.add(File.class);
ret.add(Float.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Short.class);
ret.add(String.class);
ret.add(URI.class);
ret.add(URL.class);
ret.add(Void.class);
return ret;
}
}