/*
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.junit;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.Properties;
import com.google.gwt.dev.util.Util;
import com.google.gwt.junit.JUnitShell.Strategy;
import com.google.gwt.junit.client.WithProperties;
import com.google.gwt.junit.client.WithProperties.Property;
import junit.framework.TestCase;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
/**
* A {@link JUnitShell.Strategy} that will alter the module the tests are run
* in by defining module properties as requested by annotations on the tests.
*/
public class PropertyDefiningStrategy implements Strategy {
private TestCase testCase;
private Set<Property> properties;
public PropertyDefiningStrategy(TestCase testCase) {
this.testCase = testCase;
}
@Override
public String getSyntheticModuleExtension() {
String extension = "JUnit";
computePropertiesMap();
if (properties.size() > 0) {
StringBuilder sb = new StringBuilder();
for (Property property : properties) {
sb.append(".").append(property.name()).append(
"_").append(property.value());
}
extension += sb.toString();
}
return extension;
}
@Override
public void processModule(ModuleDef module) {
computePropertiesMap();
if (properties.size() > 0) {
Properties props = module.getProperties();
for (Property property : properties) {
BindingProperty binding = props.createBinding(property.name());
if (!binding.isDefinedValue(property.value())) {
binding.addTargetLibraryDefinedValue(binding.getRootCondition(), property.value());
}
binding.setValues(
binding.getRootCondition(), property.value());
}
}
}
private Property checkProperty(Property property) {
String[] tokens = (property.name() + ". ").split("\\.");
for (int i = 0; i < tokens.length - 1; i++) {
if (!Util.isValidJavaIdent(tokens[i])) {
throw new AssertionError(
"Property name invalid: " + property.name());
}
}
if (!Util.isValidJavaIdent(property.value())) {
throw new AssertionError(
"Property value invalid: " + property.value());
}
return property;
}
private void computePropertiesMap() {
if (properties == null) {
Set<Property> props = new TreeSet<Property>(
new Comparator<Property>() {
public int compare(Property p1, Property p2) {
int r = p1.name().compareTo(p2.name());
if (r == 0) {
r = p1.value().compareTo(p2.value());
}
return r;
}
});
try {
String name = testCase.getName();
if (name != null) {
Method testMethod = testCase.getClass().getMethod(testCase.getName());
if (testMethod.isAnnotationPresent(WithProperties.class)) {
WithProperties annotation =
testMethod.getAnnotation(WithProperties.class);
for (Property property : annotation.value()) {
props.add(checkProperty(property));
}
}
}
} catch (SecurityException e) {
// should not happen
e.printStackTrace();
} catch (NoSuchMethodException e) {
// should not happen
e.printStackTrace();
}
properties = props;
}
}
}