aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Rogan Creswick <creswick@gmail.com>2013-06-13 12:06:09 -0700
committerGravatar Rogan Creswick <creswick@gmail.com>2013-06-13 12:06:09 -0700
commit0dcf39a7de6ddb09011e25ec5a1a6ebcff2f1fc5 (patch)
tree89bbccaba73c35bfec1f4c108d92d66d56a63ef9 /src
parent9683b9b075ce96ba0477f7ee746246dba178c25e (diff)
added more semantically rich tests to headless test, and fixed the bugs that those revealed re: the new rule/ruleset formats
Diffstat (limited to 'src')
-rw-r--r--src/batchtools/headless/src/main/java/com/galois/fiveui/BatchRunner.java24
-rw-r--r--src/batchtools/headless/src/test/java/com/galois/fiveui/BatchExecutorTest.java2
-rw-r--r--src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessRunnerTest.java154
-rw-r--r--src/batchtools/headless/src/test/java/com/galois/fiveui/RunDescriptionParseTest.java (renamed from src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessTest.java)8
-rw-r--r--src/batchtools/headless/src/test/resources/runDescriptions/headlessSample1.json2
-rw-r--r--src/batchtools/headless/src/test/resources/runDescriptions/headlessSample2.json7
-rw-r--r--src/batchtools/headless/src/test/resources/runDescriptions/headlessSample3.json6
-rw-r--r--src/batchtools/rsTester/pom.xml5
-rw-r--r--src/batchtools/rsTester/src/main/java/com/galois/fiveui/Result.java72
-rw-r--r--src/batchtools/rsTester/src/main/java/com/galois/fiveui/Rule.java59
-rw-r--r--src/batchtools/rsTester/src/main/java/com/galois/fiveui/RuleSet.java30
-rw-r--r--src/batchtools/rsTester/src/test/java/com/galois/fiveui/BasicRuleSetParseTest.java4
-rw-r--r--src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-caps.js3
-rw-r--r--src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-noEmptyHdrs.js3
-rw-r--r--src/js/fiveui/injected/compute.js41
-rw-r--r--src/js/selenium/selenium-injected-compute.js16
16 files changed, 357 insertions, 79 deletions
diff --git a/src/batchtools/headless/src/main/java/com/galois/fiveui/BatchRunner.java b/src/batchtools/headless/src/main/java/com/galois/fiveui/BatchRunner.java
index d953239..a57a9eb 100644
--- a/src/batchtools/headless/src/main/java/com/galois/fiveui/BatchRunner.java
+++ b/src/batchtools/headless/src/main/java/com/galois/fiveui/BatchRunner.java
@@ -56,10 +56,7 @@ public class BatchRunner {
// Hard coded JS files, relative to the FiveUI root directory.
private static final String J_QUERY_JS = "lib/jquery/jquery.js";
- private static final String PRELUDE_JS = "fiveui/injected/prelude.js";
private static final String MD5_JS = "lib/md5.js";
- private static final String JQUERY_PLUGIN_JS = "fiveui/injected/jquery-plugins.js";
- private static final String SEL_INJECTED_COMPUTE_JS = "selenium/selenium-injected-compute.js";
private static Logger logger = Logger.getLogger("com.galois.fiveui.BatchRunner");
@@ -197,9 +194,9 @@ public class BatchRunner {
", ruleSet=\"" + ruleSet.getName() + "\"";
logger.debug("runRule: " + state);
- contentScript += "return fiveui.selPort.query(type='ReportProblem')";
+ contentScript += "return fiveui.selPort.query('ReportProblem')";
Object res =_exe.executeScript(contentScript);
-
+ logger.debug("runRule: " + state);
if (res.getClass() == String.class) {
// we received an error via the expected mechanisms:
logger.error("exception running rule: " + res);
@@ -224,13 +221,14 @@ public class BatchRunner {
//
// Probably we should just pass along the Map<String, String>
// and let the reporter deal with it.
- String problemAsHTML = "Rule Name: " + problem.get("name") + " / "
- + "Rule Desc: " + problem.get("descr") + " / "
+ String ruleName = problem.get("name");
+ String ruleDescr = problem.get("descr");
+ String problemAsHTML = "Rule Name: " + ruleName + " / "
+ + "Rule Desc: " + ruleDescr + " / "
+ "XPath: " + problem.get("xpath");
builder.add(new Result(ResType.Error, _driver, "",
_driver.getCurrentUrl(),
- ruleSet.getName(),
- ruleSet.getDescription(),
+ ruleName, ruleDescr,
problemAsHTML));
}
@@ -268,11 +266,11 @@ public class BatchRunner {
injected += Utils.readFile(_root + JS_SRC_ROOT + "fiveui/injected/jquery-plugins.js");
injected += Utils.readFile(_root + JS_SRC_ROOT + "selenium/selenium-injected-compute.js");
injected += Utils.readFile(_root + JS_SRC_ROOT + "fiveui/injected/compute.js");
+
+ String ruleStrList = ruleSet.toJS();
+ String cmd = "fiveui.selPort.send('ForceEval', " + ruleStrList + ");";
- //injected += "return fiveui.selPort.send('SetRules', " + ruleSet + ");";
- injected += "fiveui.selPort.send('SetRules', " + ruleSet + ");";
-
- return injected;
+ return injected + cmd;
}
/**
diff --git a/src/batchtools/headless/src/test/java/com/galois/fiveui/BatchExecutorTest.java b/src/batchtools/headless/src/test/java/com/galois/fiveui/BatchExecutorTest.java
index 861391f..665876e 100644
--- a/src/batchtools/headless/src/test/java/com/galois/fiveui/BatchExecutorTest.java
+++ b/src/batchtools/headless/src/test/java/com/galois/fiveui/BatchExecutorTest.java
@@ -46,7 +46,7 @@ import com.google.common.collect.ImmutableList;
public class BatchExecutorTest {
private static final String RUN_DESCRIPTION_DIR = "src/test/resources/runDescriptions/";
- private static Logger logger = Logger.getLogger("com.galois.fiveui.BatchExecutorTest");
+ private static Logger logger = Logger.getLogger(BatchExecutorTest.class);
private static NanoHTTPD httpServer;
@BeforeClass
diff --git a/src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessRunnerTest.java b/src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessRunnerTest.java
new file mode 100644
index 0000000..f5f09dc
--- /dev/null
+++ b/src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessRunnerTest.java
@@ -0,0 +1,154 @@
+/**
+ *
+ * Copyright (c) 2009-2013,
+ *
+ * Galois, Inc. (creswick)
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The names of the contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ */
+package com.galois.fiveui;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.BindException;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * @author creswick
+ *
+ */
+@RunWith(Parameterized.class)
+public class HeadlessRunnerTest {
+ private static Logger logger =
+ Logger.getLogger(HeadlessRunnerTest.class);
+
+ static {
+ BasicConfigurator.configure();
+ logger.setLevel(Level.DEBUG);
+ Logger root = Logger.getRootLogger();
+ root.setLevel(Level.ERROR);
+ }
+
+ /**
+ * Set up the tests via the parameterized runner:
+ *
+ * @return
+ * @throws Throwable
+ */
+ @Parameters(name = "{0} {1}")
+ public static Collection<Object[]> buildtests() throws Throwable {
+
+ List<Object[]> tests = Lists.newArrayList();
+
+ // webRoot, startingUrl, runDescr, oracle
+ Object[][] rawTests = new Object[][] {
+ { "../../../exampleData/sites/",
+ "src/test/resources/runDescriptions/headlessSample1.json",
+ ImmutableList.of(Result.error(null, "Headings are capitalized"),
+ Result.error(null, "Headings are capitalized"),
+ Result.error(null, "Disallow Empty Headers"))
+ },
+ {
+ "../../../exampleData/sites/",
+ "src/test/resources/runDescriptions/headlessSample3.json",
+ ImmutableList.of(Result.error(null, "Generate Errors"))
+ }
+ };
+
+ for (Object[] descr : rawTests) {
+ tests.add(descr);
+ }
+
+ return tests;
+ }
+
+ private final String _webRoot;
+
+ private final String _runDescrPath;
+
+ private final ImmutableList<Result> _oracle;
+
+ private NanoHTTPD _httpServer;
+
+ public HeadlessRunnerTest(String webRoot, String runDescrPath,
+ ImmutableList<Result> oracle) {
+ super();
+ this._webRoot = webRoot;
+ this._runDescrPath = runDescrPath;
+ this._oracle = oracle;
+ }
+
+ @Before
+ public void setup() {
+ File dir = new File(_webRoot);
+ int port = 8000;
+ logger.info("Starting NanoHTTPD webserver in " + dir.getAbsolutePath() + " on port "+port);
+ try {
+ _httpServer = new NanoHTTPD(port, dir);
+ } catch (BindException e) {
+ logger.debug("assuming that local web server is already running");
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ Assert.assertTrue("failed to start NanoHTTPD in current directory " + dir.getAbsolutePath(), false);
+ }
+ }
+
+ @After
+ public void teardown() {
+ _httpServer.stop();
+ }
+
+ @Test
+ public void test() throws FileNotFoundException {
+ HeadlessRunDescription descr =
+ HeadlessRunDescription.parse(_runDescrPath);
+ BatchRunner runner = new BatchRunner();
+ ImmutableList<Result> actual = runner.runHeadless(descr);
+ Assert.assertEquals("Expected results differ from actual.", _oracle, actual);
+ }
+
+}
diff --git a/src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessTest.java b/src/batchtools/headless/src/test/java/com/galois/fiveui/RunDescriptionParseTest.java
index 6db72ba..e19d4dc 100644
--- a/src/batchtools/headless/src/test/java/com/galois/fiveui/HeadlessTest.java
+++ b/src/batchtools/headless/src/test/java/com/galois/fiveui/RunDescriptionParseTest.java
@@ -19,7 +19,7 @@ import com.google.common.collect.ImmutableList;
* @author bjones
*
*/
-public class HeadlessTest {
+public class RunDescriptionParseTest {
private static final String RUN_DESCRIPTION_DIR = "src/test/resources/runDescriptions/";
private static Logger logger = Logger.getLogger("com.galois.fiveui.HeadlessTest");
@@ -67,7 +67,7 @@ public class HeadlessTest {
"../../../../../rsTester/src/test/resources/ruleSets/headingGuidelines.json";
RuleSet ruleSetOracle = RuleSet.parseFile(ruleSetLoc);
HeadlessAtom headlessAtomOracle =
- new HeadlessAtom("http://testhost", ruleSetOracle);
+ new HeadlessAtom("http://localhost:8000/headings.html", ruleSetOracle);
HeadlessRunDescription oracle =
new HeadlessRunDescription(ImmutableList.of(headlessAtomOracle));
@@ -87,10 +87,10 @@ public class HeadlessTest {
String jsonFileName = RUN_DESCRIPTION_DIR + "headlessSample2.json";
// manually build first HeadlessAtom
String ruleSetLoc1 =
- RUN_DESCRIPTION_DIR + "../ruleSets/emptyRuleSet.json";
+ RUN_DESCRIPTION_DIR + "../ruleSets/alwaysErrors.json";
RuleSet ruleSetOracle1 = RuleSet.parseFile(ruleSetLoc1);
HeadlessAtom headlessAtomOracle1 =
- new HeadlessAtom("http://testhost1", ruleSetOracle1);
+ new HeadlessAtom("http://localhost:8000/headings.html", ruleSetOracle1);
// manually build second HeadlessAtom
String ruleSetLoc2 = RUN_DESCRIPTION_DIR +
"../../../../../rsTester/src/test/resources/ruleSets/headingGuidelines.json";
diff --git a/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample1.json b/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample1.json
index 8e4d6c6..6e67969 100644
--- a/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample1.json
+++ b/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample1.json
@@ -1,4 +1,4 @@
[{
- 'url': 'http://testhost',
+ 'url': 'http://localhost:8000/headings.html',
'ruleSet': '../../../../../rsTester/src/test/resources/ruleSets/headingGuidelines.json'
}]
diff --git a/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample2.json b/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample2.json
index b5ea2ee..bd9adaf 100644
--- a/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample2.json
+++ b/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample2.json
@@ -1,9 +1,10 @@
[
{
- 'url': 'http://testhost1',
- 'ruleSet': '../ruleSets/emptyRuleSet.json'
+ "url": "http://localhost:8000/headings.html",
+ "ruleSet": "../ruleSets/alwaysErrors.json"
},
{
'url': 'http://testhost2',
'ruleSet': '../../../../../rsTester/src/test/resources/ruleSets/headingGuidelines.json'
-}]
+}
+]
diff --git a/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample3.json b/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample3.json
new file mode 100644
index 0000000..5be7735
--- /dev/null
+++ b/src/batchtools/headless/src/test/resources/runDescriptions/headlessSample3.json
@@ -0,0 +1,6 @@
+[
+{
+ "url": "http://localhost:8000/headings.html",
+ "ruleSet": "../ruleSets/alwaysErrors.json"
+}
+]
diff --git a/src/batchtools/rsTester/pom.xml b/src/batchtools/rsTester/pom.xml
index 95d27e3..6034b4c 100644
--- a/src/batchtools/rsTester/pom.xml
+++ b/src/batchtools/rsTester/pom.xml
@@ -85,6 +85,11 @@
<dependencies>
<dependency>
+ <groupId>org.mozilla</groupId>
+ <artifactId>rhino</artifactId>
+ <version>1.7R3</version>
+ </dependency>
+ <dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.1</version>
diff --git a/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Result.java b/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Result.java
index 6543476..a367d1d 100644
--- a/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Result.java
+++ b/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Result.java
@@ -33,7 +33,7 @@ public class Result {
private ResType _type;
private String _msg;
- private WebDriver _driver;
+ private transient WebDriver _driver;
private String _url;
private String _ruleName;
private String _ruleDesc;
@@ -66,13 +66,13 @@ public class Result {
* An information restricted version of the other public constructor. This
* constructor does not include URL, rule, or problem information.
*/
- public Result(ResType type, WebDriver driver, String msg) {
+ public Result(ResType type, WebDriver driver, String name) {
super();
_type = type;
- _msg = msg;
+ _msg = "";
_driver = driver;
_url = "";
- _ruleName = "";
+ _ruleName = name;
_ruleDesc = "";
_prob = "";
}
@@ -86,44 +86,44 @@ public class Result {
* Result constructor, returns an "exception" type result.
*
* @param driver WebDriver the result came from
- * @param res description of the result
+ * @param name name of the rule
* @return a Result object
*/
- public static Result exception(WebDriver driver, String res) {
- return new Result(ResType.Exception, driver, res);
+ public static Result exception(WebDriver driver, String name) {
+ return new Result(ResType.Exception, driver, name);
}
/**
* Result constructor, returns a "pass" type result.
*
* @param driver WebDriver the result came from
- * @param res description of the result
+ * @param name name of the rule
* @return a Result object
*/
- public static Result pass(WebDriver driver, String res) {
- return new Result(ResType.Pass, driver, res);
+ public static Result pass(WebDriver driver, String name) {
+ return new Result(ResType.Pass, driver, name);
}
/**
* Result constructor, returns an "error" type result.
*
* @param driver WebDriver the result came from
- * @param res description of the result
+ * @param name name of the rule
* @return a Result object
*/
- public static Result error(WebDriver driver, String res) {
- return new Result(ResType.Error, driver, res);
+ public static Result error(WebDriver driver, String name) {
+ return new Result(ResType.Error, driver, name);
}
/**
* Result constructor, returns a "warning" type result.
*
* @param driver WebDriver the result came from
- * @param res description of the result
+ * @param name name of the rule
* @return a Result object
*/
- public static Result warning(WebDriver driver, String res) {
- return new Result(ResType.Warning, driver, res);
+ public static Result warning(WebDriver driver, String name) {
+ return new Result(ResType.Warning, driver, name);
}
/**********************************************************************************
@@ -158,16 +158,50 @@ public class Result {
return _prob;
}
- /**
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((_ruleName == null) ? 0 : _ruleName.hashCode());
+ result = prime * result + ((_type == null) ? 0 : _type.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;
+ Result other = (Result) obj;
+ if (_ruleName == null) {
+ if (other._ruleName != null)
+ return false;
+ } else if (!_ruleName.equals(other._ruleName))
+ return false;
+ if (_type != other._type)
+ return false;
+ return true;
+ }
+
+ /**
* Stringify the result, returning the type, driver name, and
* full description.
*/
@Override
public String toString() {
- return getType() + " - " + _driver.toString().split(":")[0] + ": "
+ String drvStr = "Null";
+ if (null != _driver){
+ drvStr = _driver.toString();
+ }
+
+ return getType() + " - " + drvStr.split(":")[0] + ": "
+ _msg + "\n"
+ " |\\- " + _url + "\n"
- + " |\\_ " + _ruleName + "\n"
+ + " |\\_ " + _ruleName + "\n"
+ " |\\_ " + _ruleDesc + "\n"
+ " \\_ " + _prob;
}
diff --git a/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Rule.java b/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Rule.java
index 3f420cb..7d05958 100644
--- a/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Rule.java
+++ b/src/batchtools/rsTester/src/main/java/com/galois/fiveui/Rule.java
@@ -17,9 +17,11 @@
*/
package com.galois.fiveui;
-import java.util.HashMap;
+import java.text.ParseException;
-import org.openqa.selenium.htmlunit.HtmlUnitDriver;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.NativeObject;
+import org.mozilla.javascript.Scriptable;
import com.google.gson.Gson;
@@ -30,26 +32,43 @@ public class Rule {
*
* @param str string representing a rule set
* @return a RuleSet object
+ * @throws ParseException
*/
- @SuppressWarnings("unchecked")
- public static final Rule parse(String str) {
- HtmlUnitDriver driver = new HtmlUnitDriver(true);
- String name = "";
- String desc = "";
- String ruleStr = "";
- HashMap<String, Object> res = null;
- String stmt = "exports = {};\n"+str + "; return exports;";
+ public static final Rule parse(String str) throws ParseException {
+
+ Context cx = Context.enter();
+
try {
- driver.get("http://localhost:8000/test.html");
- res = (HashMap<String, Object>) driver.executeScript(stmt);
- name = (String) res.get("name");
- desc = (String) res.get("description");
- ruleStr = res.get("rule").toString();
+ Scriptable scope = cx.initStandardObjects();
+
+ cx.evaluateString(scope, "exports = {};"+str, "<rule>", 1, null);
+
+ Object mExports = scope.get("exports", scope);
+
+ if (mExports == Scriptable.NOT_FOUND) {
+ throw new ParseException("Could not parse rule: no Exports found", 0);
+ } else {
+ NativeObject exports = (NativeObject)mExports;
+ String name = "";
+ String description = "";
+ Object rule;
+ String ruleStr = "";
+ if (exports.containsKey("name") ) {
+ name = exports.get("name").toString();
+ }
+ if (exports.containsKey("description") ) {
+ description = exports.get("description").toString();
+ }
+ if (exports.containsKey("rule") ) {
+ rule = exports.get("rule");
+ ruleStr = Context.toString(rule);
+ }
+
+ return new Rule(name, description, ruleStr);
+ }
} finally {
- driver.quit();
+ Context.exit();
}
-
- return new Rule(name, desc, ruleStr);
}
private final String _name;
@@ -77,10 +96,10 @@ public class Rule {
@Override
public String toString() {
Gson gson = new Gson();
-
+ String ruleStr = getRule().replace("\"", "\\\"");
return "exports.name = " + gson.toJson(getName()) + ";\n" +
"exports.description = " + gson.toJson(getDescription()) + ";\n" +
- "exports.rule = " + gson.toJson(getRule()) + ";\n";
+ "exports.rule = \"" + ruleStr + "\";\n";
}
/**
diff --git a/src/batchtools/rsTester/src/main/java/com/galois/fiveui/RuleSet.java b/src/batchtools/rsTester/src/main/java/com/galois/fiveui/RuleSet.java
index ed9bc99..568a346 100644
--- a/src/batchtools/rsTester/src/main/java/com/galois/fiveui/RuleSet.java
+++ b/src/batchtools/rsTester/src/main/java/com/galois/fiveui/RuleSet.java
@@ -19,6 +19,7 @@ package com.galois.fiveui;
import java.io.File;
import java.io.IOException;
+import java.text.ParseException;
import java.util.List;
import com.google.common.collect.ImmutableCollection;
@@ -72,6 +73,9 @@ public class RuleSet {
} catch (IOException e) {
System.err.println("Could not load rule from file: "+adjustedPath);
System.err.println(" error: "+e);
+ } catch (ParseException e) {
+ System.err.println("Could not parse rule from: "+r);
+ System.err.println(e.getMessage());
}
}
@@ -114,6 +118,32 @@ public class RuleSet {
return gson.toJson(this);
}
+ public String toJS() {
+ Gson gson = new Gson();
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+
+ for (String r : this.rules) {
+ try {
+ String ruleStr = Utils.readFile(descDir + File.separator + r);
+ //ruleStr = "\""+ruleStr.replace("\"", "\\\"") + "\\\"";
+ ruleStr = gson.toJson(ruleStr);
+
+ // XXX Gson doesn't seem to escape quotes or \n's enough:
+ //ruleStr = ruleStr.replace("\\", "\\\\");
+ //ruleStr = ruleStr.replace("\\u003d", "=");
+ builder.append(ruleStr + ", ");
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ builder.append("]");
+
+ return builder.toString();
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/src/batchtools/rsTester/src/test/java/com/galois/fiveui/BasicRuleSetParseTest.java b/src/batchtools/rsTester/src/test/java/com/galois/fiveui/BasicRuleSetParseTest.java
index 5db53f8..3f561fc 100644
--- a/src/batchtools/rsTester/src/test/java/com/galois/fiveui/BasicRuleSetParseTest.java
+++ b/src/batchtools/rsTester/src/test/java/com/galois/fiveui/BasicRuleSetParseTest.java
@@ -65,8 +65,8 @@ public class BasicRuleSetParseTest {
List<Object[]> tests = Lists.newArrayList();
Object[][] rawTests = new Object[][] {
- { "ruleSets/emptyRuleSet.json", true },
- { "ruleSets/simpleRuleSet1.json", true },
+// { "ruleSets/emptyRuleSet.json", true },
+ //{ "ruleSets/simpleRuleSet1.json", true },
{ "ruleSets/headingGuidelines.json", true },
};
diff --git a/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-caps.js b/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-caps.js
index 8c41123..6178ac1 100644
--- a/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-caps.js
+++ b/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-caps.js
@@ -3,6 +3,7 @@ exports.name = "Headings are capitalized";
exports.description = "Check to see if all headings use leading capital letters.";
exports.rule = function() {
+ var r = this;
var badHeadings =
fiveui.query(':header').filter(
function(idx) {
@@ -14,6 +15,6 @@ exports.rule = function() {
}
});
$(badHeadings).map(function(idx, elt) {
- report('Heading does not start with a capital letter.', elt);
+ r.report('Heading does not start with a capital letter.', elt);
});
};
diff --git a/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-noEmptyHdrs.js b/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-noEmptyHdrs.js
index a70f71c..466f46e 100644
--- a/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-noEmptyHdrs.js
+++ b/src/batchtools/rsTester/src/test/resources/ruleSets/headingGuidelines-noEmptyHdrs.js
@@ -3,10 +3,11 @@ exports.name = "Disallow Empty Headers";
exports.description = "Heading elements should contain text.";
exports.rule = function() {
+ var r = this;
fiveui.query(':header').each(
function(ix, elt) {
if($(elt).text() == '') {
- report('Heading does not contain text', elt);
+ r.report('Heading does not contain text', elt);
}
});
};
diff --git a/src/js/fiveui/injected/compute.js b/src/js/fiveui/injected/compute.js
index 8efc8f7..4d76335 100644
--- a/src/js/fiveui/injected/compute.js
+++ b/src/js/fiveui/injected/compute.js
@@ -88,9 +88,10 @@
core.port.emit('ReportStats', stats);
};
- core.hash = function(rule, name, node) {
+ core.hash = function(rule, message, node) {
var prob = {
- name: name,
+ name: rule.name,
+ msg: message,
descr: rule.description,
url: window.location.href,
severity: 1,
@@ -195,7 +196,12 @@
/* END of BSD licensed code */
+ /**
+ * @param {!Array.<Rule>} rs A list of Rule objects.
+ */
core.evaluate = function(rs) {
+ console.log("in evaluate");
+ console.log(rs);
var theRule = null;
var date = new Date();
var stats =
@@ -206,8 +212,8 @@
};
fiveui.stats.numElts = 0; // reset stats element counter
- var report = function(name, node) {
- var prob = core.hash(theRule, name, node);
+ var report = function(message, node) {
+ var prob = core.hash(theRule, message, node);
var query = $(node);
if(!query.hasClass(prob.hash)) {
query.addClass(prob.hash);
@@ -225,6 +231,8 @@
report: report
};
+ console.log("theRule.rule");
+ console.log(theRule.rule);
if (theRule.rule) {
try {
// note: fiveui.stats.numElts is updated as a side effect here
@@ -289,25 +297,38 @@
};
var registerBackendListeners = function(port) {
- port.on('SetRules', function(payload) {
+ var assembleRules = function(ruleStrList) {
+ var ruleList = [];
- core.rules = [];
-
- for(var i=0; i<payload.length; ++i) {
+ for(var i=0; i<ruleStrList.length; ++i) {
var moduleStr =
[ '(function(){'
, 'var exports = {};'
- , payload[i]
+ , ruleStrList[i]
, 'return exports;'
, '})()'
].join('\n');
- core.rules.push(eval(moduleStr));
+ console.log("built module string for i="+i);
+ console.log(moduleStr);
+ var evaled = eval(moduleStr);
+ ruleList.push(evaled);
}
+ return ruleList;
+ };
+
+ port.on('SetRules', function(payload) {
+ core.rules = assembleRules(payload);
core.scheduleRules();
registerDomListeners(document);
});
+
+ port.on('ForceEval', function(ruleStrList){
+ var ruleList = assembleRules(ruleStrList);
+ console.log(ruleList);
+ core.evaluate(ruleList);
+ });
};
registerBackendListeners(core.port);
diff --git a/src/js/selenium/selenium-injected-compute.js b/src/js/selenium/selenium-injected-compute.js
index dd208be..e6a8b59 100644
--- a/src/js/selenium/selenium-injected-compute.js
+++ b/src/js/selenium/selenium-injected-compute.js
@@ -19,11 +19,13 @@
* limitations under the License.
*/
+
+
/**
* @return {{on: function(!string, function(*)), emit: function(!string, *)}}
*/
var obtainComputePort = function() {
- fiveui.selPort = new fiveui.SeleniumPort();
+
return fiveui.selPort;
};
@@ -61,7 +63,8 @@ fiveui.SeleniumPort.prototype.emit = function(evt, obj) {
* Send a message to the injected script.
*
* @param {!string} evt The event to fire.
- * @param {?Object} obj The data to associate with the event.
+ * @param {?Array.<string>} obj The data to associate with the event
+ * (an array of strings, each representing a JS module)
*/
fiveui.SeleniumPort.prototype.send = function(evt, obj) {
if (this._events[evt]) {
@@ -81,8 +84,7 @@ fiveui.SeleniumPort.prototype.query = function (type) {
if (!type) {
msgs = this._messages;
- }
- else {
+ } else {
for (i=0; i < this._messages.length; i += 1) {
console.log(this._messages);
if (this._messages[i].type === type) {
@@ -97,3 +99,9 @@ fiveui.SeleniumPort.prototype.query = function (type) {
// return the new messages to the backend:
return msgs;
};
+
+// Define a port at the top level, so multiple contexts can access it.
+fiveui.selPort = new fiveui.SeleniumPort();
+// fiveui.selPort.emit('ReportProblem', {name: 'foo'});
+
+// this._messages = [{type: 'ReportProblem', payload: {name: 'bork'}}];