Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/domutils/test/fixture.js b/node_modules/domutils/test/fixture.js
new file mode 100644
index 0000000..9bd791b
--- /dev/null
+++ b/node_modules/domutils/test/fixture.js
@@ -0,0 +1,6 @@
+var makeDom = require("./utils").makeDom;
+var markup = Array(21).join(
+	"<?xml><tag1 id='asdf'> <script>text</script> <!-- comment --> <tag2> text </tag1>"
+);
+
+module.exports = makeDom(markup);
diff --git a/node_modules/domutils/test/tests/helpers.js b/node_modules/domutils/test/tests/helpers.js
new file mode 100644
index 0000000..2e30afb
--- /dev/null
+++ b/node_modules/domutils/test/tests/helpers.js
@@ -0,0 +1,89 @@
+var makeDom = require("../utils").makeDom;
+var helpers = require("../..");
+var assert = require("assert");
+
+describe("helpers", function() {
+	describe("removeSubsets", function() {
+		var removeSubsets = helpers.removeSubsets;
+		var dom = makeDom("<div><p><span></span></p><p></p></div>")[0];
+
+		it("removes identical trees", function() {
+			var matches = removeSubsets([dom, dom]);
+			assert.equal(matches.length, 1);
+		});
+
+		it("Removes subsets found first", function() {
+			var matches = removeSubsets([dom, dom.children[0].children[0]]);
+			assert.equal(matches.length, 1);
+		});
+
+		it("Removes subsets found last", function() {
+			var matches = removeSubsets([dom.children[0], dom]);
+			assert.equal(matches.length, 1);
+		});
+
+		it("Does not remove unique trees", function() {
+			var matches = removeSubsets([dom.children[0], dom.children[1]]);
+			assert.equal(matches.length, 2);
+		});
+	});
+
+	describe("compareDocumentPosition", function() {
+		var compareDocumentPosition = helpers.compareDocumentPosition;
+		var markup = "<div><p><span></span></p><a></a></div>";
+		var dom = makeDom(markup)[0];
+		var p = dom.children[0];
+		var span = p.children[0];
+		var a = dom.children[1];
+
+		it("reports when the first node occurs before the second indirectly", function() {
+			assert.equal(compareDocumentPosition(span, a), 2);
+		});
+
+		it("reports when the first node contains the second", function() {
+			assert.equal(compareDocumentPosition(p, span), 10);
+		});
+
+		it("reports when the first node occurs after the second indirectly", function() {
+			assert.equal(compareDocumentPosition(a, span), 4);
+		});
+
+		it("reports when the first node is contained by the second", function() {
+			assert.equal(compareDocumentPosition(span, p), 20);
+		});
+
+		it("reports when the nodes belong to separate documents", function() {
+			var other = makeDom(markup)[0].children[0].children[0];
+
+			assert.equal(compareDocumentPosition(span, other), 1);
+		});
+
+		it("reports when the nodes are identical", function() {
+			assert.equal(compareDocumentPosition(span, span), 0);
+		});
+	});
+
+	describe("uniqueSort", function() {
+		var uniqueSort = helpers.uniqueSort;
+		var dom, p, span, a;
+
+		beforeEach(function() {
+			dom = makeDom("<div><p><span></span></p><a></a></div>")[0];
+			p = dom.children[0];
+			span = p.children[0];
+			a = dom.children[1];
+		});
+
+		it("leaves unique elements untouched", function() {
+			assert.deepEqual(uniqueSort([p, a]), [p, a]);
+		});
+
+		it("removes duplicate elements", function() {
+			assert.deepEqual(uniqueSort([p, a, p]), [p, a]);
+		});
+
+		it("sorts nodes in document order", function() {
+			assert.deepEqual(uniqueSort([a, dom, span, p]), [dom, p, span, a]);
+		});
+	});
+});
diff --git a/node_modules/domutils/test/tests/legacy.js b/node_modules/domutils/test/tests/legacy.js
new file mode 100644
index 0000000..87fabfa
--- /dev/null
+++ b/node_modules/domutils/test/tests/legacy.js
@@ -0,0 +1,119 @@
+var DomUtils = require("../..");
+var fixture = require("../fixture");
+var assert = require("assert");
+
+// Set up expected structures
+var expected = {
+	idAsdf: fixture[1],
+	tag2: [],
+	typeScript: []
+};
+for (var idx = 0; idx < 20; ++idx) {
+	expected.tag2.push(fixture[idx*2 + 1].children[5]);
+	expected.typeScript.push(fixture[idx*2 + 1].children[1]);
+}
+
+describe("legacy", function() {
+	describe("getElements", function() {
+		var getElements = DomUtils.getElements;
+		it("returns the node with the specified ID", function() {
+			assert.deepEqual(
+				getElements({ id: "asdf" }, fixture, true, 1),
+				[expected.idAsdf]
+			);
+		});
+		it("returns empty array for unknown IDs", function() {
+			assert.deepEqual(getElements({ id: "asdfs" }, fixture, true), []);
+		});
+		it("returns the nodes with the specified tag name", function() {
+			assert.deepEqual(
+				getElements({ tag_name:"tag2" }, fixture, true),
+				expected.tag2
+			);
+		});
+		it("returns empty array for unknown tag names", function() {
+			assert.deepEqual(
+				getElements({ tag_name : "asdfs" }, fixture, true),
+				[]
+			);
+		});
+		it("returns the nodes with the specified tag type", function() {
+			assert.deepEqual(
+				getElements({ tag_type: "script" }, fixture, true),
+				expected.typeScript
+			);
+		});
+		it("returns empty array for unknown tag types", function() {
+			assert.deepEqual(
+				getElements({ tag_type: "video" }, fixture, true),
+				[]
+			);
+		});
+	});
+
+	describe("getElementById", function() {
+		var getElementById = DomUtils.getElementById;
+		it("returns the specified node", function() {
+			assert.equal(
+				expected.idAsdf,
+				getElementById("asdf", fixture, true)
+			);
+		});
+		it("returns `null` for unknown IDs", function() {
+			assert.equal(null, getElementById("asdfs", fixture, true));
+		});
+	});
+
+	describe("getElementsByTagName", function() {
+		var getElementsByTagName = DomUtils.getElementsByTagName;
+		it("returns the specified nodes", function() {
+			assert.deepEqual(
+				getElementsByTagName("tag2", fixture, true),
+				expected.tag2
+			);
+		});
+		it("returns empty array for unknown tag names", function() {
+			assert.deepEqual(
+				getElementsByTagName("tag23", fixture, true),
+				[]
+			);
+		});
+	});
+
+	describe("getElementsByTagType", function() {
+		var getElementsByTagType = DomUtils.getElementsByTagType;
+		it("returns the specified nodes", function() {
+			assert.deepEqual(
+				getElementsByTagType("script", fixture, true),
+				expected.typeScript
+			);
+		});
+		it("returns empty array for unknown tag types", function() {
+			assert.deepEqual(
+				getElementsByTagType("video", fixture, true),
+				[]
+			);
+		});
+	});
+
+	describe("getOuterHTML", function() {
+		var getOuterHTML = DomUtils.getOuterHTML;
+		it("Correctly renders the outer HTML", function() {
+			assert.equal(
+				getOuterHTML(fixture[1]),
+				"<tag1 id=\"asdf\"> <script>text</script> <!-- comment --> <tag2> text </tag2></tag1>"
+			);
+		});
+	});
+
+	describe("getInnerHTML", function() {
+		var getInnerHTML = DomUtils.getInnerHTML;
+		it("Correctly renders the inner HTML", function() {
+			assert.equal(
+				getInnerHTML(fixture[1]),
+				" <script>text</script> <!-- comment --> <tag2> text </tag2>"
+			);
+		});
+	});
+
+});
diff --git a/node_modules/domutils/test/tests/traversal.js b/node_modules/domutils/test/tests/traversal.js
new file mode 100644
index 0000000..f500e08
--- /dev/null
+++ b/node_modules/domutils/test/tests/traversal.js
@@ -0,0 +1,17 @@
+var makeDom = require("../utils").makeDom;
+var traversal = require("../..");
+var assert = require("assert");
+
+describe("traversal", function() {
+  describe("hasAttrib", function() {
+    var hasAttrib = traversal.hasAttrib;
+
+    it("doesn't throw on text nodes", function() {
+      var dom = makeDom("textnode");
+      assert.doesNotThrow(function() {
+        hasAttrib(dom[0], "some-attrib");
+      });
+    });
+
+  });
+});
diff --git a/node_modules/domutils/test/utils.js b/node_modules/domutils/test/utils.js
new file mode 100644
index 0000000..676e8f6
--- /dev/null
+++ b/node_modules/domutils/test/utils.js
@@ -0,0 +1,9 @@
+var htmlparser = require("htmlparser2");
+
+exports.makeDom = function(markup) {
+	var handler = new htmlparser.DomHandler(),
+		parser = new htmlparser.Parser(handler);
+	parser.write(markup);
+	parser.done();
+	return handler.dom;
+};