parse-domain 2.2.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,10 +3,8 @@
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
5
  const chai = require("chai");
6
- const parsePubSuffixList = require("../lib/tries/parsePubSuffixList");
7
- const serializeTrie = require("../lib/tries/serializeTrie");
8
- const parseTrie = require("../lib/tries/parseTrie");
9
- const lookUp = require("../lib/tries/lookUp");
6
+ const parsePubSuffixList = require("../lib/trie/parsePubSuffixList");
7
+ const serializeTrie = require("../lib/trie/serializeTrie");
10
8
 
11
9
  const expect = chai.expect;
12
10
  const TEST_SNAPSHOT = true;
@@ -36,23 +34,4 @@ describe("snapshots", () => {
36
34
  fs.writeFileSync(pathToSerializeTrieSnapshot, JSON.stringify(serializedTrie));
37
35
  });
38
36
  });
39
- describe("parseTrie() and lookUp() calling lookUp() with the result from parseTrie(snapshot) and hostname", () => {
40
- const serializedTrie = JSON.parse(fs.readFileSync(pathToSerializeTrieSnapshot, "utf8"));
41
- const parsedTrie = parseTrie(serializedTrie);
42
-
43
- [
44
- ["example.com", "com"],
45
- ["example.a.com", "com"],
46
- ["example.uk", "uk"],
47
- ["example.co.uk", "co.uk"],
48
- ["example.ab.uk", "uk"],
49
- ].forEach(testArgs => {
50
- const hostname = testArgs[0];
51
- const expectedResult = testArgs[1];
52
-
53
- it(`'${hostname}' returns ${expectedResult}`, () => {
54
- expect(lookUp(parsedTrie, hostname)).to.equal(expectedResult);
55
- });
56
- });
57
- });
58
37
  });
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ const chai = require("chai");
4
+ const lookUp = require("../../lib/trie/lookUp");
5
+ const characters = require("../../lib/trie/characters");
6
+ const {createNode, adoptChild} = require("../../lib/trie/nodes");
7
+
8
+ const expect = chai.expect;
9
+
10
+ function createOneLevelDeepTrie() {
11
+ const root = createNode();
12
+ const com = createNode("com");
13
+
14
+ adoptChild(root, com);
15
+
16
+ return root;
17
+ }
18
+
19
+ function createTwoLevelDeepTrie() {
20
+ const root = createNode();
21
+ const uk = createNode("uk");
22
+ const co = createNode("co");
23
+
24
+ adoptChild(root, uk);
25
+ adoptChild(uk, co);
26
+
27
+ return root;
28
+ }
29
+
30
+ function createTrieWithWildcardAndException() {
31
+ const root = createNode();
32
+ const wildcard = createNode(characters.WILDCARD);
33
+ const exception = createNode(characters.EXCEPTION + "exception");
34
+
35
+ adoptChild(root, wildcard);
36
+ adoptChild(root, exception);
37
+
38
+ return root;
39
+ }
40
+
41
+ describe("lookUp()", () => {
42
+ describe("with an empty trie", () => {
43
+ it("returns an empty array", () => {
44
+ const root = createNode();
45
+
46
+ expect(lookUp(root, ["com"])).to.eql([]);
47
+ expect(lookUp(root, ["example", "com"])).to.eql([]);
48
+ });
49
+ });
50
+ describe("with a one level deep trie", () => {
51
+ it("returns the known TLD as array", () => {
52
+ const root = createOneLevelDeepTrie();
53
+
54
+ expect(lookUp(root, ["com"])).to.eql(["com"]);
55
+ expect(lookUp(root, ["example", "com"])).to.eql(["com"]);
56
+ expect(lookUp(root, ["www", "example", "com"])).to.eql(["com"]);
57
+ });
58
+ it("returns an empty array if there is no known TLD", () => {
59
+ const root = createOneLevelDeepTrie();
60
+
61
+ expect(lookUp(root, ["de"])).to.eql([]);
62
+ expect(lookUp(root, ["example", "de"])).to.eql([]);
63
+ expect(lookUp(root, ["www", "example", "de"])).to.eql([]);
64
+ });
65
+ });
66
+ describe("with a two level deep trie", () => {
67
+ it("returns the known TLD", () => {
68
+ const root = createTwoLevelDeepTrie();
69
+
70
+ expect(lookUp(root, ["uk"])).to.eql(["uk"]);
71
+ expect(lookUp(root, ["example", "uk"])).to.eql(["uk"]);
72
+ expect(lookUp(root, ["co", "uk"])).to.eql(["co", "uk"]);
73
+ expect(lookUp(root, ["example", "co", "uk"])).to.eql(["co", "uk"]);
74
+ expect(lookUp(root, ["www", "example", "co", "uk"])).to.eql(["co", "uk"]);
75
+ });
76
+
77
+ it("returns an empty array if there is no known TLD", () => {
78
+ const root = createTwoLevelDeepTrie();
79
+
80
+ expect(lookUp(root, ["de"])).to.eql([]);
81
+ expect(lookUp(root, ["example", "de"])).to.eql([]);
82
+ expect(lookUp(root, ["www", "example", "de"])).to.eql([]);
83
+ });
84
+ });
85
+ describe("with a wildcard and exceptions", () => {
86
+ it("does not accept the exception as TLD", () => {
87
+ const root = createTrieWithWildcardAndException();
88
+
89
+ expect(lookUp(root, ["exception"])).to.eql([]);
90
+ expect(lookUp(root, ["www", "exception"])).to.eql([]);
91
+ });
92
+ it("accepts all domain names as TLD in place of the wildcard", () => {
93
+ const root = createTrieWithWildcardAndException();
94
+
95
+ expect(lookUp(root, ["anything"])).to.eql(["anything"]);
96
+ expect(lookUp(root, ["www", "anything"])).to.eql(["anything"]);
97
+ });
98
+ });
99
+ });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ const chai = require("chai");
4
+ const {createNode, adoptChild} = require("../../lib/trie/nodes");
5
+
6
+ const expect = chai.expect;
7
+
8
+ describe("adoptChild()", () => {
9
+ it("throws an error if the child has no domain", () => {
10
+ expect(() => {
11
+ adoptChild(createNode(), createNode());
12
+ }).to.throw("Cannot adopt child: child.domain must be a string");
13
+ });
14
+ it("throws an error if the parent has already a child with that domain", () => {
15
+ expect(() => {
16
+ const parent = createNode();
17
+
18
+ adoptChild(parent, createNode("some-domain"));
19
+ adoptChild(parent, createNode("some-domain"));
20
+ }).to.throw("Cannot adopt child: parent has already a child with the domain 'some-domain'");
21
+ });
22
+ });
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+
3
+ const chai = require("chai");
4
+ const parse = require("../../lib/trie/parse");
5
+
6
+ const expect = chai.expect;
7
+
8
+ describe("parse()", () => {
9
+ describe("when called with ''", () => {
10
+ it("returns a node with null as domain and no children", () => {
11
+ const root = parse("");
12
+
13
+ expect(root.domain).to.equal(null);
14
+ expect(root.children.size).to.equal(0);
15
+ });
16
+ });
17
+ describe("when called with 'a'", () => {
18
+ it("adds 'a' as child of root", () => {
19
+ const root = parse("a");
20
+
21
+ expect(root.children.has("a")).to.be.true;
22
+ });
23
+ it("initializes 'a' with the correct domain and parent", () => {
24
+ const root = parse("a");
25
+ const a = root.children.get("a");
26
+
27
+ expect(a.domain).to.equal("a");
28
+ expect(a.parent).to.equal(root);
29
+ });
30
+ });
31
+ describe("when called with 'a,b'", () => {
32
+ it("adds 'a' and 'b' as child of root", () => {
33
+ const root = parse("a,b");
34
+
35
+ expect(root.children.has("a")).to.be.true;
36
+ expect(root.children.has("b")).to.be.true;
37
+ });
38
+ it("initializes 'b' with the correct domain and parent", () => {
39
+ const root = parse("a,b");
40
+ const b = root.children.get("b");
41
+
42
+ expect(b.domain).to.equal("b");
43
+ expect(b.parent).to.equal(root);
44
+ });
45
+ });
46
+ describe("when called with 'a>b'", () => {
47
+ it("adds 'a' as child of root and 'b' as child of 'a'", () => {
48
+ const root = parse("a>b");
49
+
50
+ expect(root.children.has("a")).to.be.true;
51
+ expect(root.children.get("a").children.has("b")).to.be.true;
52
+ });
53
+ it("initializes 'b' with the correct domain and parent", () => {
54
+ const root = parse("a>b");
55
+ const a = root.children.get("a");
56
+ const b = a.children.get("b");
57
+
58
+ expect(b.domain).to.equal("b");
59
+ expect(b.parent).to.equal(a);
60
+ });
61
+ });
62
+ describe("when called with 'a>b,c'", () => {
63
+ it("adds 'b' and 'c' as child of 'a'", () => {
64
+ const root = parse("a>b,c");
65
+ const a = root.children.get("a");
66
+
67
+ expect(a.children.has("b")).to.be.true;
68
+ expect(a.children.has("c")).to.be.true;
69
+ });
70
+ it("initializes 'c' with the correct domain and parent", () => {
71
+ const root = parse("a>b,c");
72
+ const a = root.children.get("a");
73
+ const c = a.children.get("c");
74
+
75
+ expect(c.domain).to.equal("c");
76
+ expect(c.parent).to.equal(a);
77
+ });
78
+ });
79
+ describe("when called with 'a>b<c'", () => {
80
+ it("adds 'b' as child of 'a' and 'c' as child of root", () => {
81
+ const root = parse("a>b<c");
82
+ const a = root.children.get("a");
83
+
84
+ expect(a.children.has("b")).to.be.true;
85
+ expect(root.children.has("c")).to.be.true;
86
+ });
87
+ it("initializes 'c' with the correct domain and parent", () => {
88
+ const root = parse("a>b<c");
89
+ const c = root.children.get("c");
90
+
91
+ expect(c.domain).to.equal("c");
92
+ expect(c.parent).to.equal(root);
93
+ });
94
+ });
95
+ describe("when called with 'a|b'", () => {
96
+ it("adds 'a' and 'b' as child of root", () => {
97
+ const root = parse("a|b");
98
+
99
+ expect(root.children.has("a")).to.be.true;
100
+ expect(root.children.has("b")).to.be.true;
101
+ });
102
+ it("initializes 'b' with the correct domain and parent", () => {
103
+ const root = parse("a|b");
104
+ const b = root.children.get("b");
105
+
106
+ expect(b.domain).to.equal("b");
107
+ expect(b.parent).to.equal(root);
108
+ });
109
+ });
110
+ describe("when called with 'a>b|c'", () => {
111
+ it("adds 'b' as child of 'a' and 'c' as child of root", () => {
112
+ const root = parse("a>b|c");
113
+ const a = root.children.get("a");
114
+
115
+ expect(a.children.has("b")).to.be.true;
116
+ expect(root.children.has("c")).to.be.true;
117
+ });
118
+ });
119
+ describe("when called with 'a>b<a>d'", () => {
120
+ it("adds 'b' and 'd' as child of 'a'", () => {
121
+ const root = parse("a>b<a>c");
122
+ const a = root.children.get("a");
123
+
124
+ expect(a.children.has("b")).to.be.true;
125
+ expect(a.children.has("c")).to.be.true;
126
+ });
127
+ });
128
+ describe("when called with 'a>b>c'", () => {
129
+ it("adds 'c' as child of 'b'", () => {
130
+ const root = parse("a>b>c");
131
+ const b = root.children.get("a").children.get("b");
132
+
133
+ expect(b.children.has("c")).to.be.true;
134
+ });
135
+ });
136
+ describe("when called with 'a>b>c>d|e'", () => {
137
+ it("adds 'e' as child node of root", () => {
138
+ const node = parse("a>b>c>d|e");
139
+
140
+ expect(node.children.has("e")).to.be.true;
141
+ });
142
+ });
143
+ });
@@ -3,7 +3,7 @@
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
5
  const chai = require("chai");
6
- const parsePubSuffixList = require("../../lib/tries/parsePubSuffixList");
6
+ const parsePubSuffixList = require("../../lib/trie/parsePubSuffixList");
7
7
 
8
8
  const expect = chai.expect;
9
9
  const pathToFixtures = path.resolve(__dirname, "..", "fixtures");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  const chai = require("chai");
4
- const serializeTrie = require("../../lib/tries/serializeTrie");
4
+ const serializeTrie = require("../../lib/trie/serializeTrie");
5
5
 
6
6
  const expect = chai.expect;
7
7
 
@@ -1,40 +0,0 @@
1
- "use strict";
2
-
3
- var WILDCARD = "*";
4
- var EXCEPTION = "!";
5
-
6
- function lookUp(trie, hostname) {
7
- var domains = hostname.split(".").reverse();
8
- var tlds = [];
9
- var currentTrie = trie;
10
-
11
- for (var i = 0; i < domains.length; i++) {
12
- var domain = domains[i];
13
- var isWildcardRule = currentTrie.has(WILDCARD);
14
-
15
- if (isWildcardRule) {
16
- if (currentTrie.has(EXCEPTION + domain) === false) {
17
- tlds.push(domain);
18
- }
19
-
20
- break;
21
- }
22
-
23
- if (currentTrie.has(domain) === false) {
24
- break;
25
- }
26
-
27
- tlds.push(domain);
28
- var value = currentTrie.get(domain);
29
-
30
- if (value === true) {
31
- break;
32
- }
33
-
34
- currentTrie = value;
35
- }
36
-
37
- return tlds.length === 0 ? null : tlds.reverse().join(".");
38
- }
39
-
40
- module.exports = lookUp;
@@ -1,62 +0,0 @@
1
- "use strict";
2
-
3
- var SEPARATORS = require("./separators");
4
-
5
- function parseTrie(input) {
6
- var map = new Map();
7
- var parentMaps = [map];
8
- var domain = "";
9
-
10
- function setDomain(value) {
11
- if (domain === "") {
12
- return;
13
- }
14
-
15
- map.set(domain, value);
16
- domain = "";
17
- }
18
-
19
- for (var i = 0; i < input.length; i++) {
20
- var _char = input.charAt(i);
21
-
22
- switch (_char) {
23
- case SEPARATORS.SAME:
24
- {
25
- setDomain(true);
26
- continue;
27
- }
28
-
29
- case SEPARATORS.DOWN:
30
- {
31
- var childMap = new Map();
32
- setDomain(childMap);
33
- parentMaps.push(map);
34
- map = childMap;
35
- continue;
36
- }
37
-
38
- case SEPARATORS.RESET:
39
- {
40
- setDomain(true); // Remove all parent maps but the top most
41
-
42
- parentMaps.length = 1;
43
- map = parentMaps[0];
44
- continue;
45
- }
46
-
47
- case SEPARATORS.UP:
48
- {
49
- setDomain(true);
50
- map = parentMaps.pop();
51
- continue;
52
- }
53
- }
54
-
55
- domain += _char;
56
- }
57
-
58
- setDomain(true);
59
- return parentMaps[0];
60
- }
61
-
62
- module.exports = parseTrie;
@@ -1,12 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = {
4
- UP: "<",
5
- // one level up
6
- SAME: ",",
7
- // same level
8
- DOWN: ">",
9
- // one level down
10
- RESET: "|" // reset level index and start new
11
-
12
- };
@@ -1,116 +0,0 @@
1
- "use strict";
2
-
3
- const chai = require("chai");
4
- const lookUp = require("../../lib/tries/lookUp");
5
-
6
- const expect = chai.expect;
7
-
8
- describe("lookUp()", () => {
9
- it("returns null if the trie is empty", () => {
10
- const trie = new Map();
11
- const hostname = "a.b.c";
12
-
13
- expect(lookUp(trie, hostname)).to.eql(null);
14
- });
15
- it("returns null if the trie contains no matching top-level domain", () => {
16
- const trie = new Map();
17
- const hostname = "a.b.c";
18
-
19
- trie.set("cc", true);
20
-
21
- expect(lookUp(trie, hostname)).to.eql(null);
22
- });
23
- it("returns the hostname if the hostname is a top-level domain", () => {
24
- const trie = new Map();
25
- const hostname = "a";
26
-
27
- trie.set("a", true);
28
- trie.set("b", true);
29
-
30
- expect(lookUp(trie, hostname)).to.eql("a");
31
- });
32
- it("returns the top-level domain from the hostname (2 domains)", () => {
33
- const trie = new Map();
34
- const hostname = "b.a";
35
-
36
- trie.set("a", true);
37
- trie.set("b", true);
38
-
39
- expect(lookUp(trie, hostname)).to.eql("a");
40
- });
41
- it("returns the top-level domain from the hostname (3 domains)", () => {
42
- const trie = new Map();
43
- const hostname = "c.b.a";
44
-
45
- trie.set("a", true);
46
- trie.set("b", true);
47
-
48
- expect(lookUp(trie, hostname)).to.eql("a");
49
- });
50
- it("returns the top-level domain (2 tlds) from the hostname (3 domains)", () => {
51
- const trie = new Map();
52
- const trieA = new Map();
53
- const hostname = "c.b.a";
54
-
55
- trieA.set("b", true);
56
- trie.set("a", trieA);
57
- trie.set("b", new Map());
58
-
59
- expect(lookUp(trie, hostname)).to.eql("b.a");
60
- });
61
- it("returns the top-level domain (3 tlds) from the hostname (4 domains)", () => {
62
- const trie = new Map();
63
- const trieA = new Map();
64
- const trieAB = new Map();
65
- const hostname = "d.c.b.a";
66
-
67
- trieAB.set("c", true);
68
- trieA.set("b", trieAB);
69
- trieA.set("a", true);
70
- trie.set("a", trieA);
71
- trie.set("b", new Map());
72
-
73
- expect(lookUp(trie, hostname)).to.eql("c.b.a");
74
- });
75
- it("interprets wildcards in the trie correctly (simple)", () => {
76
- const trie = new Map();
77
- const hostname = "a.b.c";
78
-
79
- trie.set("*", true);
80
-
81
- expect(lookUp(trie, hostname)).to.eql("c");
82
- });
83
- it("interprets wildcards in the trie correctly (nested)", () => {
84
- const trie = new Map();
85
- const trieA = new Map();
86
- const hostname = "c.b.a";
87
-
88
- trieA.set("*", true);
89
- trie.set("a", trieA);
90
-
91
- expect(lookUp(trie, hostname)).to.eql("b.a");
92
- });
93
- it("interprets exceptions of wildcards in the trie correctly (simple)", () => {
94
- const trie = new Map();
95
- const trieA = new Map();
96
- const hostname = "c.b.a";
97
-
98
- trieA.set("*", true);
99
- trieA.set("!b", true);
100
- trie.set("a", trieA);
101
-
102
- expect(lookUp(trie, hostname)).to.eql("a");
103
- });
104
- it("still handles wildcards correctly if there are non-matching exceptions", () => {
105
- const trie = new Map();
106
- const trieA = new Map();
107
- const hostname = "c.b.a";
108
-
109
- trieA.set("*", true);
110
- trieA.set("!a", true);
111
- trieA.set("!c", true);
112
- trie.set("a", trieA);
113
-
114
- expect(lookUp(trie, hostname)).to.eql("b.a");
115
- });
116
- });