aboutsummaryrefslogtreecommitdiff
path: root/rsTester/src
diff options
context:
space:
mode:
authorGravatar Rogan Creswick <creswick@gmail.com>2012-09-02 14:10:01 -0700
committerGravatar Rogan Creswick <creswick@gmail.com>2012-09-02 14:10:01 -0700
commita8664102395dc9c899428ea6e31a64ff6f22046e (patch)
treea1d764b3983ff385d59d2d2fad8c9ccda4e78495 /rsTester/src
parent172992b50a44417ec758ba79b25026c700961e4b (diff)
refactored the java-based apps: testrunner, rstester, batch-executor
Diffstat (limited to 'rsTester/src')
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/BatchRunner.java161
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/Drivers.java100
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java296
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/ResType.java23
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/Result.java67
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/Rule.java130
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/RuleSet.java162
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/RuleSetTester.java90
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/RuleTest.java70
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/URITest.java55
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/Utils.java39
-rw-r--r--rsTester/src/main/resources/javascript/ruleEval.js74
-rwxr-xr-xrsTester/src/main/resources/seleniumDrivers/linux64/chromedriverbin0 -> 16328112 bytes
-rw-r--r--rsTester/src/test/java/com/galois/fiveui/BatchExecutorTest.java38
-rw-r--r--rsTester/src/test/java/com/galois/fiveui/RuleSetTest.java57
-rw-r--r--rsTester/src/test/java/com/galois/fiveui/RunDescriptionTest.java82
-rw-r--r--rsTester/src/test/resources/ruleSets/emptyRuleSet.json4
-rw-r--r--rsTester/src/test/resources/ruleSets/headingGuidelines.json37
-rw-r--r--rsTester/src/test/resources/ruleSets/simpleRuleSet1.json9
-rw-r--r--rsTester/src/test/resources/runDescriptions/headingSample.json13
-rw-r--r--rsTester/src/test/resources/runDescriptions/sample0.json4
-rw-r--r--rsTester/src/test/resources/runDescriptions/sample1.json4
-rw-r--r--rsTester/src/test/resources/runDescriptions/sample2.json10
-rw-r--r--rsTester/src/test/resources/runDescriptions/sample3.json7
-rw-r--r--rsTester/src/test/resources/runDescriptions/sample4.json10
-rw-r--r--rsTester/src/test/resources/runDescriptions/sample5.json13
26 files changed, 1555 insertions, 0 deletions
diff --git a/rsTester/src/main/java/com/galois/fiveui/BatchRunner.java b/rsTester/src/main/java/com/galois/fiveui/BatchRunner.java
new file mode 100644
index 0000000..a6996ab
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/BatchRunner.java
@@ -0,0 +1,161 @@
+/**
+ * Module : BatchRunner.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.WebDriver;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.Lists;
+
+public class BatchRunner {
+
+ private final WebDriver _driver;
+ private final JavascriptExecutor _exe;
+
+ // Relative to the batch directory.
+ private static final String DATA_DIR = "../data/";
+ private static final String J_QUERY_JS = DATA_DIR
+ + "lib/jquery/jquery-1.7.1.min.js";
+ private static final String PRELUDE_JS = DATA_DIR
+ + "fiveui/injected/prelude.js";
+ private static final String SEL_INJECTED_COMPUTE_JS = DATA_DIR +
+ "/fiveui/selenium/selenium-injected-compute.js";
+
+ private static final String INJECTED_COMPUTE_JS = DATA_DIR +
+ "/fiveui/injected/fiveui-injected-compute.js";
+
+ public BatchRunner(WebDriver driver) {
+ _driver = driver;
+ _exe = (JavascriptExecutor) _driver;
+ }
+
+ public ImmutableList<Result> runTests(ImmutableList<RuleTest> build) {
+ Builder<Result> resBuilder = ImmutableList.builder();
+ for (RuleTest test : build) {
+ resBuilder.addAll(runTest(test));
+ }
+ return resBuilder.build();
+ }
+
+ /**
+ * Run a URITest, returning the result (success, failure details, or
+ * indicator of exceptional conditions.)
+ *
+ * @param test
+ */
+ public ImmutableList<Result> runTest(final RuleTest test) {
+ RuleSet rule = test.getRule();
+
+ ImmutableList<Result> rawResults;
+ Builder<Result> builder = ImmutableList.builder();
+ try {
+ _driver.get(test.getUri().toString());
+ rawResults = runRule(rule);
+
+ List<ResType> oracle = Lists.newArrayList(test.getOracle());
+ for (Result result : rawResults) {
+ Result res;
+ if ( oracle.remove(result.getType()) ) {
+ res = Result.pass(_driver,
+ test.getRuleId() + ": Got expected result: "+result.getType());
+ } else {
+ res = Result.error(_driver,
+ test.getRuleId() + ": Unexpected Result: "+result);
+ }
+ builder.add(res);
+ }
+ } catch (Exception e) {
+ String errStr = "Could not run rule: " + rule.getName() + "\n";
+ errStr += e.toString();
+ rawResults = ImmutableList.of(
+ Result.exception(_driver, "Could not run rule: "+errStr));
+
+ e.printStackTrace();
+ }
+
+ return builder.build();
+ }
+
+ private ImmutableList<Result> runRule(final RuleSet ruleSet) throws IOException {
+ String contentScript = wrapRule(ruleSet);
+ Builder<Result> builder = ImmutableList.builder();
+
+ _exe.executeScript(contentScript);
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+
+ Object res = _exe.executeScript("return fiveui.selPort.query()");
+
+ if (res.getClass() == String.class) {
+ // we received an error via the expected mechanisms:
+ System.err.println("Exception running rule: " + res);
+ builder.add(Result.exception(_driver, (String) res));
+ return builder.build();
+ } else {
+
+ try {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ List<Map<String, Map<String, String>>> results = (List) res;
+
+ if (0 == results.size()) {
+ builder.add(Result.pass(_driver, "passed"));
+ }
+
+ for (Map<String, Map<String, String>> r : results) {
+ Map<String, String> problem = r.get("payload");
+
+ builder.add(Result.error(_driver, problem.get("descr")));
+ }
+
+ } catch (ClassCastException e) {
+ // An unexpected error happened:
+ builder.add(Result.exception(_driver, "Unexpected object returned: "
+ + res));
+ e.printStackTrace();
+ }
+ }
+ return builder.build();
+ }
+
+ /**
+ * Build up the complete content script needed to run the rule
+ *
+ * @throws IOException
+ */
+ private String wrapRule(RuleSet ruleSet) throws IOException {
+ String injected = "";
+ injected += Utils.readFile(SEL_INJECTED_COMPUTE_JS);
+ injected += Utils.readFile(J_QUERY_JS);
+ injected += Utils.readFile(PRELUDE_JS);
+ injected += Utils.readFile(INJECTED_COMPUTE_JS);
+
+ injected += "return fiveui.selPort.send('SetRules', " + ruleSet + ");";
+
+ return injected;
+ }
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/Drivers.java b/rsTester/src/main/java/com/galois/fiveui/Drivers.java
new file mode 100644
index 0000000..c965b4c
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/Drivers.java
@@ -0,0 +1,100 @@
+/**
+ * Module : Drivers.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.io.File;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.openqa.selenium.firefox.FirefoxDriver;
+import org.openqa.selenium.firefox.FirefoxProfile;
+
+/**
+ * TODO refactor into a shared package that can be used by the testrunner as w
+ * well as the batch execution apps.
+ *
+ *
+ * @author creswick
+ *
+ */
+public class Drivers {
+ private static final String CD_BINARY_NAME = "chromedriver";
+ private static final String CD_BASE_PATH = mkPath("..", "..", "tools",
+ "seleniumChromeDrivers");
+
+ private static final String CHROME_PROFILE = mkPath("..", "..", "profiles",
+ "chrome");
+
+ private static final String FF_PROFILE = mkPath("..", "..", "profiles",
+ "firefox");
+
+ public static WebDriver buildFFDriver() {
+ // Extracted into a method so we can set up profiles
+
+ File profileDir = new File(FF_PROFILE);
+ FirefoxProfile profile = new FirefoxProfile(profileDir);
+ FirefoxDriver driver = new FirefoxDriver(profile);
+
+ return driver;
+ }
+
+ public static WebDriver buildChromeDriver() {
+ // set the chrome driver path:
+ String chromeDriverPth =
+ mkPath(CD_BASE_PATH, osNameArch(), CD_BINARY_NAME);
+ System.setProperty("webdriver.chrome.driver", chromeDriverPth);
+
+ ChromeOptions options = new ChromeOptions();
+ options.addArguments("--user-data-dir="+CHROME_PROFILE);
+
+ return new ChromeDriver(options);
+ }
+
+ private static String mkPath(String... components) {
+ StringBuilder path = new StringBuilder();
+ int remaining = components.length;
+ for (String c : components) {
+ path.append(c);
+ remaining--;
+ if (remaining != 0) {
+ path.append(File.separator);
+ }
+ }
+
+ return path.toString();
+ }
+
+ /**
+ * Determine the name of the directory that the chromedriver is in, based on
+ * os.name and os.arch.
+ *
+ * @return The name of the directory containing 'chromedriver'
+ */
+ private static String osNameArch() {
+ String rawOsName = System.getProperty("os.name").toLowerCase();
+ String osName = rawOsName.substring(0, 3);
+ boolean is64bit = System.getProperty("os.arch").indexOf("64") >= 0;
+
+ if (osName.equals("lin")) {
+ osName += is64bit ? "64" : "32";
+ }
+ return osName;
+ }
+
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java b/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java
new file mode 100644
index 0000000..a9a3f02
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java
@@ -0,0 +1,296 @@
+package com.galois.fiveui;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+
+/**
+ * RSTestDescriptions represent a set of tests for a specific RuleSet.
+ *
+ * RSTestDescriptions are also GSON-serializiable (and deserializable).
+ *
+ * An example of the JSON is given below:
+ *
+ * <pre>
+ * {@code
+ * { 'ruleSet': '../../exampleData/ruleSets/headingGuidelines.json',
+ * 'tests': [ { 'url': 'http://localhost:8000/exampleData/basic/headings.html',
+ * 'oracle': [ { 'ruleId': 1
+ * , 'results': ['Error', 'Error']
+ * },
+ * { 'ruleId': 2
+ * , 'results': ['Error']
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * }
+ * </pre>
+ *
+ * {@code tests} is as list that may contain a number of urls and sets of
+ * expected Problems for the specified rule set and url combination.
+ *
+ * {@code ruleSet} is a string file path that is relative to the rule set
+ * description json file.
+ *
+ * @author creswick
+ *
+ */
+public class RSTestDescription {
+
+ /**
+ * Parse a JSON file into a RSTestDescription
+ *
+ * @param runDescFileName The file to load.
+ * @return A populated RunDescription object.
+ * @throws FileNotFoundException if runDescFile can't be found.
+ */
+ public static RSTestDescription parse(String runDescFileName)
+ throws FileNotFoundException {
+
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(RSTestDescription.class,
+ new RSTestDescription.Deserializer(runDescFileName));
+ Gson gson = gsonBuilder.create();
+
+ Reader in = new InputStreamReader(new FileInputStream(runDescFileName));
+
+ return gson.fromJson(in, RSTestDescription.class);
+ }
+
+ public static class Deserializer implements JsonDeserializer<RSTestDescription> {
+
+ private final String _descFile;
+
+ public Deserializer(String descFile) {
+ _descFile = descFile;
+ }
+
+ public RSTestDescription deserialize(JsonElement json, Type typeOfT,
+ JsonDeserializationContext context) throws JsonParseException {
+
+ JsonObject obj = json.getAsJsonObject();
+
+ String ruleSet = obj.get("ruleSet").getAsString();
+ JsonArray testArray = obj.get("tests").getAsJsonArray();
+
+ List<URIMap> tests = Lists.newArrayList();
+ for (JsonElement jsonElement : testArray) {
+ tests.add((URIMap)context.deserialize(jsonElement, URIMap.class));
+ }
+
+ String descDir = new File(_descFile).getParent();
+ if (null == descDir) {
+ descDir = ".";
+ }
+
+ // This probably is not portable, because the ruleSet path separator
+ // may not match that of the file system.
+ // TODO if File.separator is not "/", then replace "\" with File.separator.
+ String rsPath = descDir + File.separator + ruleSet;
+
+ String ruleSetStr;
+ try {
+ ruleSetStr = Utils.readFile(rsPath);
+ } catch (IOException e) {
+ throw new JsonParseException("Could not read " + rsPath);
+ }
+ RuleSet parsed = RuleSet.parse(ruleSetStr);
+
+ return new RSTestDescription(rsPath, tests, parsed);
+ }
+ }
+
+ /**
+ * The path to the selected rule set.
+ */
+ private final String _ruleSetLoc;
+
+ /**
+ * A list of urls and oracles that define tests for the specified RuleSet.
+ */
+ private final List<URIMap> _tests;
+
+ private final RuleSet _ruleSet;
+
+ public RSTestDescription(String ruleSetLoc, List<URIMap> tests, RuleSet ruleSet) {
+ _ruleSetLoc = ruleSetLoc;
+ _tests = tests;
+ _ruleSet = ruleSet;
+ }
+
+ public RuleSet getRuleSet() {
+ return _ruleSet;
+ }
+
+ public String getRuleSetLoc() {
+ return _ruleSetLoc;
+ }
+
+ public ImmutableList<RuleTest> getTests() throws IOException {
+ Builder<RuleTest> builder = ImmutableList.builder();
+ for (URIMap uriMap : _tests) {
+ for (RuleMap rMap : uriMap.getOracle()) {
+ builder.add(
+ new RuleTest(uriMap.getUrl(), getRuleSet(), rMap.getRuleId(), rMap.getResults()));
+ }
+ }
+ return builder.build();
+ }
+
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result =
+ prime * result + ((_ruleSet == null) ? 0 : _ruleSet.hashCode());
+ result =
+ prime * result
+ + ((_ruleSetLoc == null) ? 0 : _ruleSetLoc.hashCode());
+ result = prime * result + ((_tests == null) ? 0 : _tests.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RSTestDescription other = (RSTestDescription) obj;
+ if (_ruleSet == null) {
+ if (other._ruleSet != null)
+ return false;
+ } else if (!_ruleSet.equals(other._ruleSet))
+ return false;
+ if (_ruleSetLoc == null) {
+ if (other._ruleSetLoc != null)
+ return false;
+ } else if (!_ruleSetLoc.equals(other._ruleSetLoc))
+ return false;
+ if (_tests == null) {
+ if (other._tests != null)
+ return false;
+ } else if (!_tests.equals(other._tests))
+ return false;
+ return true;
+ }
+
+ public static class URIMap {
+ private URI url;
+ private List<RuleMap> oracle;
+
+ @SuppressWarnings("unused")
+ URIMap(){}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result =
+ prime * result + ((getOracle() == null) ? 0 : getOracle().hashCode());
+ result = prime * result + ((getUrl() == null) ? 0 : getUrl().hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ URIMap other = (URIMap) obj;
+ if (getOracle() == null) {
+ if (other.getOracle() != null)
+ return false;
+ } else if (!getOracle().equals(other.getOracle()))
+ return false;
+ if (getUrl() == null) {
+ if (other.getUrl() != null)
+ return false;
+ } else if (!getUrl().equals(other.getUrl()))
+ return false;
+ return true;
+ }
+
+ public URI getUrl() {
+ return url;
+ }
+
+ public List<RuleMap> getOracle() {
+ return oracle;
+ }
+ }
+
+ public static class RuleMap {
+ private int ruleId;
+ private List<ResType> results;
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result =
+ prime * result
+ + ((getResults() == null) ? 0 : getResults().hashCode());
+ result = prime * result + getRuleId();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RuleMap other = (RuleMap) obj;
+ if (getResults() == null) {
+ if (other.getResults() != null)
+ return false;
+ } else if (!getResults().equals(other.getResults()))
+ return false;
+ if (getRuleId() != other.getRuleId())
+ return false;
+ return true;
+ }
+
+ public int getRuleId() {
+ return ruleId;
+ }
+
+ public List<ResType> getResults() {
+ return results;
+ }
+ }
+
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/ResType.java b/rsTester/src/main/java/com/galois/fiveui/ResType.java
new file mode 100644
index 0000000..671d74c
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/ResType.java
@@ -0,0 +1,23 @@
+/**
+ * Module : ResType.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+public enum ResType {
+ Pass, Error, Warning, Exception
+} \ No newline at end of file
diff --git a/rsTester/src/main/java/com/galois/fiveui/Result.java b/rsTester/src/main/java/com/galois/fiveui/Result.java
new file mode 100644
index 0000000..2f80aca
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/Result.java
@@ -0,0 +1,67 @@
+/**
+ * Module : Result.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import org.openqa.selenium.WebDriver;
+
+public class Result {
+
+ public static Result exception(WebDriver driver, String res) {
+ return new Result(ResType.Exception, driver, res);
+ }
+
+ public static Result pass(WebDriver driver, String res) {
+ return new Result(ResType.Pass, driver, res);
+ }
+
+ public static Result error(WebDriver driver, String res) {
+ return new Result(ResType.Error, driver, res);
+ }
+
+ public static Result warning(WebDriver driver, String res) {
+ return new Result(ResType.Warning, driver, res);
+ }
+
+ private ResType _type;
+ private String _desc;
+ private WebDriver _driver;
+
+ private Result(ResType type, WebDriver driver, String desc) {
+ super();
+ _type = type;
+ _desc = desc;
+ _driver = driver;
+ }
+
+ public ResType getType() {
+ return _type;
+ }
+
+ public String getDesc() {
+ return _desc;
+ }
+
+ public WebDriver getDriver() {
+ return _driver;
+ }
+
+ @Override
+ public String toString() {
+ return getType() + " - " + _driver + ": " + getDesc();
+ }
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/Rule.java b/rsTester/src/main/java/com/galois/fiveui/Rule.java
new file mode 100644
index 0000000..838fafb
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/Rule.java
@@ -0,0 +1,130 @@
+/**
+ * Module : Rule.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.util.HashMap;
+
+import com.google.common.base.Function;
+import com.google.gson.Gson;
+
+public class Rule {
+
+ /**
+ * Function wrapper around `RuleSet.parse` for use in `transform` and other
+ * functional combinators.
+ */
+ public static final Function<HashMap<String, Object>, Rule> PARSE =
+ new Function<HashMap<String, Object>, Rule>() {
+ public Rule apply(final HashMap<String, Object> input) {
+ return Rule.parse(input);
+ }
+ };
+
+ /**
+ * Parse a string representation of a Rule into a Java POJO.
+ *
+ * @param str
+ * @return
+ */
+ public static final Rule parse(final HashMap<String, Object> res) {
+ String name = (String) res.get("name");
+ String desc = (String) res.get("description");
+ String rule = res.get("rule").toString();
+ int id = ((Long)res.get("id")).intValue();
+ return new Rule(name, desc, rule, id);
+ }
+
+ private final String _name;
+ private final String _desc;
+ private final String _rule;
+ private final int _id;
+
+ public Rule(final String name, final String desc, final String rule, final int id) {
+ this._name = name;
+ this._desc = desc;
+ this._rule = rule;
+ this._id = id;
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public String getDescription() {
+ return _desc;
+ }
+
+ public String getRule() {
+ return _rule;
+ }
+
+ public int getId() {
+ return _id;
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+
+ return "{ 'id': " + gson.toJson(getId()) + ",\n " +
+ " 'name': " + gson.toJson(getName()) + ",\n" +
+ " 'description': " + gson.toJson(getDescription()) + ",\n" +
+ " 'ruleStr': " + gson.toJson(getRule()) + "\n" +
+ "}";
+ }
+
+ /**
+ * Equals and hashCode ignore the rule function text when performing comparisons.
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((_desc == null) ? 0 : _desc.hashCode());
+ result = prime * result + _id;
+ result = prime * result + ((_name == null) ? 0 : _name.hashCode());
+ return result;
+ }
+
+ /**
+ * Equals and hashCode ignore the rule function text when performing comparisons.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Rule other = (Rule) obj;
+ if (_desc == null) {
+ if (other._desc != null)
+ return false;
+ } else if (!_desc.equals(other._desc))
+ return false;
+ if (_id != other._id)
+ return false;
+ if (_name == null) {
+ if (other._name != null)
+ return false;
+ } else if (!_name.equals(other._name))
+ return false;
+ return true;
+ }
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/RuleSet.java b/rsTester/src/main/java/com/galois/fiveui/RuleSet.java
new file mode 100644
index 0000000..ee2638c
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/RuleSet.java
@@ -0,0 +1,162 @@
+/**
+ * Module : RuleSet.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.openqa.selenium.htmlunit.HtmlUnitDriver;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+
+public class RuleSet {
+
+ /**
+ * Function wrapper around `RuleSet.parse` for use in `transform` and other
+ * functional combinators.
+ */
+ public static final Function<String, RuleSet> PARSE =
+ new Function<String, RuleSet>() {
+ public RuleSet apply(String input) {
+ return RuleSet.parse(input);
+ }
+ };
+
+ /**
+ * Parse a string representation of a Rule Set into a Java POJO.
+ *
+ * TODO Extract out a js evaluation env.
+ *
+ * @param str
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static final RuleSet parse(String str) {
+ HtmlUnitDriver driver = new HtmlUnitDriver(true);
+ String name = "";
+ String desc = "";
+ List<Rule> rules = Lists.newArrayList();
+ HashMap<String, Object> res = null;
+ try {
+ driver.get("http://localhost:8000/test.html");
+ res =
+ (HashMap<String, Object>) driver.executeScript("var x = "
+ + str + "; return x;");
+ name = (String) res.get("name");
+ desc = (String) res.get("description");
+ List<HashMap<String, Object>> rawRules =
+ (List<HashMap<String, Object>>) res.get("rules");
+
+ rules = Lists.transform(rawRules, Rule.PARSE);
+ } finally {
+ driver.quit();
+ }
+ return new RuleSet(name, desc, ImmutableList.copyOf(rules));
+ }
+
+ private final String _name;
+ private final String _description;
+ private final ImmutableList<Rule> _rules;
+
+ public RuleSet(String name, String description,
+ ImmutableList<Rule> immutableList) {
+ _name = name;
+ _description = description;
+ _rules = immutableList;
+ }
+
+ public String getName() {
+ return _name;
+ }
+
+ public String getDescription() {
+ return _description;
+ }
+
+ public ImmutableList<Rule> getRules() {
+ return _rules;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder rules = new StringBuilder();
+ for (Rule r : getRules()) {
+ if (0 != rules.length()) {
+ rules.append(",\n");
+ }
+ rules.append(r.toString());
+ }
+ Gson gson = new Gson();
+ return "{ 'name': " + gson.toJson(getName()) + ", " +
+ " 'description': " + gson.toJson(getDescription()) + ", " +
+ " 'rules': [" + rules.toString() + "]" +
+ "}";
+ }
+
+ public Rule getRule(int ruleId) {
+ for (Rule rule : getRules()) {
+ if ( ruleId == rule.getId()) {
+ return rule;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((_description == null) ? 0 : _description.hashCode());
+ result = prime * result + ((_name == null) ? 0 : _name.hashCode());
+ result = prime * result + ((_rules == null) ? 0 : _rules.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RuleSet other = (RuleSet) obj;
+ if (_description == null) {
+ if (other._description != null)
+ return false;
+ } else if (!_description.equals(other._description))
+ return false;
+ if (_name == null) {
+ if (other._name != null)
+ return false;
+ } else if (!_name.equals(other._name))
+ return false;
+ if (_rules == null) {
+ if (other._rules != null)
+ return false;
+ } else if (!_rules.equals(other._rules))
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/RuleSetTester.java b/rsTester/src/main/java/com/galois/fiveui/RuleSetTester.java
new file mode 100644
index 0000000..beea351
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/RuleSetTester.java
@@ -0,0 +1,90 @@
+/**
+ * Module : BatchExecutor.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.firefox.FirefoxDriver;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * The main entry point for testing Rule Sets.
+ *
+ *
+ * @author creswick
+ *
+ */
+public class RuleSetTester {
+
+ /**
+ * @param args
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ public static void main(final String[] args) throws IOException,
+ URISyntaxException {
+ System.out.println(args.length);
+
+ if (0 == args.length) {
+ printHelp();
+ System.exit(1);
+ }
+
+ for (int i = 0; i < args.length; i++) {
+ String runDescFileName = args[i];
+ RSTestDescription descr = RSTestDescription.parse(runDescFileName);
+
+ for (WebDriver driver : getDrivers()) {
+ try {
+ ImmutableList<Result> results = invokeTest(descr, driver);
+
+ for (Result result : results) {
+ System.out.println(result);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ driver.quit();
+ }
+ }
+ }
+ }
+
+ private static ImmutableList<WebDriver> getDrivers() {
+ return ImmutableList.of(Drivers.buildFFDriver()
+ // , Drivers.buildChromeDriver()
+ );
+ }
+
+ private static void printHelp() {
+ System.out
+ .println("Usage: RuleSetTester [<ruleSetTestDescirption.json>]");
+ }
+
+ private static ImmutableList<Result> invokeTest(RSTestDescription descr,
+ WebDriver driver) throws IOException {
+ BatchRunner runner = new BatchRunner(driver);
+
+ return runner.runTests(descr.getTests());
+
+ }
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/RuleTest.java b/rsTester/src/main/java/com/galois/fiveui/RuleTest.java
new file mode 100644
index 0000000..020f787
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/RuleTest.java
@@ -0,0 +1,70 @@
+/**
+ * Module : RuleTest.java
+ * Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer :
+ * Stability : Provisional
+ * Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.net.URI;
+import java.util.Collection;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultiset;
+
+/**
+ * @author creswick
+ *
+ */
+public class RuleTest {
+
+ private final URI _uri;
+ private final RuleSet _ruleSet;
+ private final int _ruleId;
+ private final ImmutableMultiset<ResType> _oracle;
+
+ public RuleTest(URI uri, RuleSet ruleSet, int ruleId, Collection<ResType> oracle) {
+ _uri = uri;
+ _ruleSet = ruleSet;
+ _ruleId = ruleId;
+ _oracle = ImmutableMultiset.copyOf(oracle);
+ }
+
+ public RuleSet getRule() {
+ RuleSet newRS = new RuleSet(_ruleSet.getName(),
+ _ruleSet.getDescription(), ImmutableList.of(_ruleSet.getRule(_ruleId)));
+ return newRS;
+ }
+
+ public URI getUri() {
+ return _uri;
+ }
+
+ public RuleSet getRuelSet() {
+ return _ruleSet;
+ }
+
+ public int getRuleId() {
+ return _ruleId;
+ }
+
+ public ImmutableMultiset<ResType> getOracle() {
+ return _oracle;
+ }
+
+
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/URITest.java b/rsTester/src/main/java/com/galois/fiveui/URITest.java
new file mode 100644
index 0000000..5a0f920
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/URITest.java
@@ -0,0 +1,55 @@
+/**
+ * Module : URITest.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.net.URI;
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+
+public class URITest {
+
+ private URI uri;
+ private int id;
+ private List<ResType> oracle;
+
+ /**
+ * Deserialization constructor.
+ */
+ URITest() {}
+
+// public URITest(URI uri, RuleSet ruleSet, ResType oracle) {
+// assert(1 == ruleSet.getRules().size());
+//
+// this._uri = uri;
+// this._ruleSet = ruleSet;
+// this._oracle = oracle;
+// }
+
+ public URI getUri() {
+ return uri;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public ImmutableList<ResType> getOracle() {
+ return ImmutableList.copyOf(oracle);
+ }
+}
diff --git a/rsTester/src/main/java/com/galois/fiveui/Utils.java b/rsTester/src/main/java/com/galois/fiveui/Utils.java
new file mode 100644
index 0000000..b9e231c
--- /dev/null
+++ b/rsTester/src/main/java/com/galois/fiveui/Utils.java
@@ -0,0 +1,39 @@
+/**
+ * Module : Utils.java Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer : Stability : Provisional Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.google.common.io.CharStreams;
+
+public class Utils {
+
+ public static String readFile(String fileName) throws IOException {
+ InputStream in = new FileInputStream(new File(fileName));
+ return readStream(in);
+ }
+
+ public static String readStream(final InputStream stream)
+ throws IOException {
+ return CharStreams.toString(new InputStreamReader(stream));
+ }
+}
diff --git a/rsTester/src/main/resources/javascript/ruleEval.js b/rsTester/src/main/resources/javascript/ruleEval.js
new file mode 100644
index 0000000..04e81ba
--- /dev/null
+++ b/rsTester/src/main/resources/javascript/ruleEval.js
@@ -0,0 +1,74 @@
+/**
+ * Module : ruleEval.js
+ * Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer :
+ * Stability : Provisional
+ * Portability: Portable
+ *
+ * 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.
+ */
+/* Evaluate a rule.
+ *
+ * @param {!string} ruleStr The string representation of the rule (as
+ * a JavaScript Object literal).
+ * @return {?Array<Problem>} Empty if no problems were found or a string
+ * with an error if an exception occurred.
+ */
+var evaluate = function(ruleName, description, ruleStr) {
+ var theRule = null;
+ var results = [];
+
+// return [{ 'name': 'some rule',
+// 'descr': 'some description',
+// 'url': 'http:\/\/localhost:8000',
+// 'severity': '1'
+// }];
+//};
+
+ var report = function(name, node) {
+ var prob = {
+ 'name': name,
+ 'descr': description,
+ 'url': window.location.href,
+ 'severity': 1
+ };
+
+ results.push(prob);
+ };
+
+ try {
+ eval('var theRule = '+ruleStr);
+ return theRule.toString();
+ } catch (x) {
+// console.log('could not load rule: '+ruleStr);
+// console.log(x);
+ return "Error: "+x;
+ }
+
+ var scope = {
+ name : ruleName,
+ description : description
+ };
+
+ if (theRule) {
+ try {
+ theRule.apply(scope);
+ } catch (x) {
+// console.log('exception running rule: '+theRule.name);
+// console.log(x);
+ return "Error: "+x;
+ }
+ }
+ return results;
+};
diff --git a/rsTester/src/main/resources/seleniumDrivers/linux64/chromedriver b/rsTester/src/main/resources/seleniumDrivers/linux64/chromedriver
new file mode 100755
index 0000000..b0a0e4a
--- /dev/null
+++ b/rsTester/src/main/resources/seleniumDrivers/linux64/chromedriver
Binary files differ
diff --git a/rsTester/src/test/java/com/galois/fiveui/BatchExecutorTest.java b/rsTester/src/test/java/com/galois/fiveui/BatchExecutorTest.java
new file mode 100644
index 0000000..bb4dd31
--- /dev/null
+++ b/rsTester/src/test/java/com/galois/fiveui/BatchExecutorTest.java
@@ -0,0 +1,38 @@
+/**
+ * Module : BatchExecutorTest.java
+ * Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer :
+ * Stability : Provisional
+ * Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+
+/**
+ * @author creswick
+ *
+ */
+public class BatchExecutorTest {
+
+ @Test
+ public void simpleTest() {
+ Assert.assertEquals("Booleans are not equal.", true, true);
+ }
+}
diff --git a/rsTester/src/test/java/com/galois/fiveui/RuleSetTest.java b/rsTester/src/test/java/com/galois/fiveui/RuleSetTest.java
new file mode 100644
index 0000000..1cd4dae
--- /dev/null
+++ b/rsTester/src/test/java/com/galois/fiveui/RuleSetTest.java
@@ -0,0 +1,57 @@
+/**
+ * Module : RuleSetTest.java
+ * Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer :
+ * Stability : Provisional
+ * Portability: Portable
+ *
+ * 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.galois.fiveui;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class RuleSetTest {
+ @Test
+ public void testParseNoFns() {
+ testParse("the name", "a descr", "[]", new ArrayList<String>());
+ }
+
+ @Ignore
+ @Test
+ public void testParseOneFn() {
+ List<String> rules = ImmutableList.of("\n function () {\n }\n");
+ testParse("the name", "a descr", "[function () {}]", rules);
+ }
+
+ private void testParse(String name, String desc, String rules, List<String> rulesOracle) {
+ RuleSet rs = RuleSet.parse("{ 'name': '" +name+"'" +
+ ", 'description': '"+desc+"'" +
+ ", 'rules': " + rules +
+ "};");
+
+ assertEquals("", name, rs.getName());
+ assertEquals("", desc, rs.getDescription());
+ Assert.assertArrayEquals("", rulesOracle.toArray(), rs.getRules().toArray());
+ }
+}
diff --git a/rsTester/src/test/java/com/galois/fiveui/RunDescriptionTest.java b/rsTester/src/test/java/com/galois/fiveui/RunDescriptionTest.java
new file mode 100644
index 0000000..4c58f74
--- /dev/null
+++ b/rsTester/src/test/java/com/galois/fiveui/RunDescriptionTest.java
@@ -0,0 +1,82 @@
+/**
+ * RunDescriptionTest.java
+ *
+ * Copyright (c) 2012 Galois, Inc.
+ */
+package com.galois.fiveui;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * @author creswick
+ *
+ */
+public class RunDescriptionTest {
+
+ private static final String RUN_DESCRIPTION_DIR = "src/test/resources/runDescriptions/";
+
+ /**
+ * Test method for {@link com.galois.fiveui.RSTestDescription#RunDescription(java.lang.String, java.util.List, com.galois.fiveui.RuleSet)}.
+ * @throws FileNotFoundException
+ */
+ @Test
+ public final void testDeserialize_sample0() throws FileNotFoundException {
+
+ String jsonFileName = RUN_DESCRIPTION_DIR + "sample0.json";
+ String ruleSetLoc =
+ RUN_DESCRIPTION_DIR + "../ruleSets/emptyRuleSet.json";
+
+ ImmutableList<Rule> emptyRuleList = ImmutableList.of();
+ RuleSet rsOracle =
+ new RuleSet("emptyRuleSet", "", emptyRuleList);
+
+ RSTestDescription oracle =
+ new RSTestDescription(ruleSetLoc,
+ new ArrayList<RSTestDescription.URIMap>(), rsOracle);
+
+
+ RSTestDescription actual = RSTestDescription.parse(jsonFileName);
+ assertObjEqual("Object deserialized incorrectly.", oracle, actual);
+ }
+
+ /**
+ * Test method for {@link com.galois.fiveui.RSTestDescription#RunDescription(java.lang.String, java.util.List, com.galois.fiveui.RuleSet)}.
+ * @throws FileNotFoundException
+ */
+ @Test
+ public final void testDeserialize_sample1() throws FileNotFoundException {
+
+ String jsonFileName = RUN_DESCRIPTION_DIR + "sample1.json";
+ String ruleSetLoc =
+ RUN_DESCRIPTION_DIR + "../ruleSets/simpleRuleSet1.json";
+
+ RuleSet rsOracle =
+ new RuleSet("simpleRuleSet1", "", ImmutableList.of(
+ new Rule("trivial check", "test desc", "", 42)));
+
+ RSTestDescription oracle =
+ new RSTestDescription(ruleSetLoc,
+ new ArrayList<RSTestDescription.URIMap>(), rsOracle);
+
+
+ RSTestDescription actual = RSTestDescription.parse(jsonFileName);
+ assertObjEqual("Object deserialized incorrectly.", oracle, actual);
+ }
+
+ private void assertObjEqual(String msg, Object oracle, Object actual) {
+ Assert.assertTrue(msg + "; expected: "+oracle+" actual: "+actual,
+ oracle.equals(actual));
+ }
+
+
+}
diff --git a/rsTester/src/test/resources/ruleSets/emptyRuleSet.json b/rsTester/src/test/resources/ruleSets/emptyRuleSet.json
new file mode 100644
index 0000000..a01bc68
--- /dev/null
+++ b/rsTester/src/test/resources/ruleSets/emptyRuleSet.json
@@ -0,0 +1,4 @@
+{ "name": "emptyRuleSet"
+, "description": ""
+, "rules": []
+}
diff --git a/rsTester/src/test/resources/ruleSets/headingGuidelines.json b/rsTester/src/test/resources/ruleSets/headingGuidelines.json
new file mode 100644
index 0000000..be69fac
--- /dev/null
+++ b/rsTester/src/test/resources/ruleSets/headingGuidelines.json
@@ -0,0 +1,37 @@
+{ "name": "Heading Guidelines"
+, "description": "Guidelines pertaining to the formatting and content of headings."
+, "rules": [ { "id": 1
+ , "name": "Headings are capitalized"
+ , "description": "Check to see if all headings use leading capital letters."
+ , "rule":
+ function() {
+ var badHeadings =
+ fiveui.query(':header').filter(
+ function(idx) {
+ var ch = $(this).text()[0];
+ if (ch) {
+ return (ch == ch.toLowerCase() );
+ } else {
+ return false;
+ }
+ });
+ $(badHeadings).map(function(idx, elt){
+ report('Heading does not start with a capitol letter.', elt);
+ });
+
+ }
+ },
+ { "id": 2
+ , "name": "Disallow Empty Headers"
+ , "description": "Heading elements should contain text."
+ , "rule": function() {
+ fiveui.query(':header').each(
+ function(ix, elt) {
+ if($(elt).text() == '') {
+ report('Heading does not contain text', elt);
+ }
+ });
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/rsTester/src/test/resources/ruleSets/simpleRuleSet1.json b/rsTester/src/test/resources/ruleSets/simpleRuleSet1.json
new file mode 100644
index 0000000..8365d1d
--- /dev/null
+++ b/rsTester/src/test/resources/ruleSets/simpleRuleSet1.json
@@ -0,0 +1,9 @@
+{ "name": "simpleRuleSet1"
+, "description": ""
+, "rules": [ { "id": 42
+ , "name": "trivial check"
+ , "description": "test desc"
+ , "rule":
+ function() { }
+ }]
+}
diff --git a/rsTester/src/test/resources/runDescriptions/headingSample.json b/rsTester/src/test/resources/runDescriptions/headingSample.json
new file mode 100644
index 0000000..e8228ca
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/headingSample.json
@@ -0,0 +1,13 @@
+{
+ 'ruleSet': '../ruleSets/headingGuidelines.json',
+ 'tests': [ { 'url': 'http://localhost:8000/exampleData/basic/headings.html',
+ 'oracle': [ { 'ruleId': 1
+ , 'results': ['Error', 'Error']
+ },
+ { 'ruleId': 2
+ , 'results': ['Error']
+ }
+ ]
+ }
+ ]
+}
diff --git a/rsTester/src/test/resources/runDescriptions/sample0.json b/rsTester/src/test/resources/runDescriptions/sample0.json
new file mode 100644
index 0000000..0c2bbb7
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/sample0.json
@@ -0,0 +1,4 @@
+{
+ 'ruleSet': '../ruleSets/emptyRuleSet.json',
+ 'tests': []
+}
diff --git a/rsTester/src/test/resources/runDescriptions/sample1.json b/rsTester/src/test/resources/runDescriptions/sample1.json
new file mode 100644
index 0000000..91f8f34
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/sample1.json
@@ -0,0 +1,4 @@
+{
+ 'ruleSet': '../ruleSets/simpleRuleSet1.json',
+ 'tests': []
+}
diff --git a/rsTester/src/test/resources/runDescriptions/sample2.json b/rsTester/src/test/resources/runDescriptions/sample2.json
new file mode 100644
index 0000000..a8ea9ec
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/sample2.json
@@ -0,0 +1,10 @@
+{
+ 'ruleSet': '../ruleSets/simpleRuleSet1.json',
+ 'tests': [ { 'url': 'http://localhost:8000/',
+ 'oracle': [ { 'ruleId': 42
+ , 'results': ['Error', 'Error']
+ }
+ ]
+ }
+ ]
+}
diff --git a/rsTester/src/test/resources/runDescriptions/sample3.json b/rsTester/src/test/resources/runDescriptions/sample3.json
new file mode 100644
index 0000000..e4d1cea
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/sample3.json
@@ -0,0 +1,7 @@
+{
+ 'ruleSet': '../ruleSets/simpleRuleSet1.json',
+ 'tests': [ { 'url': 'http://localhost:8000/',
+ 'oracle': [ ]
+ }
+ ]
+}
diff --git a/rsTester/src/test/resources/runDescriptions/sample4.json b/rsTester/src/test/resources/runDescriptions/sample4.json
new file mode 100644
index 0000000..c4f46cd
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/sample4.json
@@ -0,0 +1,10 @@
+{
+ 'ruleSet': '../ruleSets/simpleRuleSet1.json',
+ 'tests': [ { 'url': 'http://localhost:8000/',
+ 'oracle': [ ]
+ },
+ { 'url': 'http://localhost:8000/',
+ 'oracle': [ ]
+ }
+ ]
+}
diff --git a/rsTester/src/test/resources/runDescriptions/sample5.json b/rsTester/src/test/resources/runDescriptions/sample5.json
new file mode 100644
index 0000000..11ca957
--- /dev/null
+++ b/rsTester/src/test/resources/runDescriptions/sample5.json
@@ -0,0 +1,13 @@
+{
+ 'ruleSet': '../ruleSets/simpleRuleSet1.json',
+ 'tests': [ { 'url': 'http://localhost:8000/',
+ 'oracle': [ { 'ruleId': 42
+ , 'results': ['Error']
+ }
+ ]
+ },
+ { 'url': 'http://localhost:8000/',
+ 'oracle': [ ]
+ }
+ ]
+}