parse-domain 2.3.0 → 2.3.4

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.
@@ -1,217 +1,219 @@
1
1
  "use strict";
2
2
 
3
- const chai = require("chai");
4
-
5
- const expect = chai.expect;
6
3
  const parseDomain = require("../lib/parseDomain.js");
7
4
 
8
- chai.config.includeStack = true;
9
-
10
5
  describe("parseDomain(url)", () => {
11
- it("should remove the protocol", () => {
12
- expect(parseDomain("http://example.com")).to.eql({
6
+ test("should remove the protocol", () => {
7
+ expect(parseDomain("http://example.com")).toEqual({
13
8
  subdomain: "",
14
9
  domain: "example",
15
10
  tld: "com",
16
11
  });
17
- expect(parseDomain("//example.com")).to.eql({
12
+ expect(parseDomain("//example.com")).toEqual({
18
13
  subdomain: "",
19
14
  domain: "example",
20
15
  tld: "com",
21
16
  });
22
- expect(parseDomain("https://example.com")).to.eql({
17
+ expect(parseDomain("https://example.com")).toEqual({
23
18
  subdomain: "",
24
19
  domain: "example",
25
20
  tld: "com",
26
21
  });
27
22
  });
28
23
 
29
- it("should remove sub-domains", () => {
30
- expect(parseDomain("www.example.com")).to.eql({
24
+ test("should remove sub-domains", () => {
25
+ expect(parseDomain("www.example.com")).toEqual({
31
26
  subdomain: "www",
32
27
  domain: "example",
33
28
  tld: "com",
34
29
  });
35
- expect(parseDomain("www.some.other.subdomain.example.com")).to.eql({
30
+ expect(parseDomain("www.some.other.subdomain.example.com")).toEqual({
36
31
  subdomain: "www.some.other.subdomain",
37
32
  domain: "example",
38
33
  tld: "com",
39
34
  });
40
35
  });
41
36
 
42
- it("should remove the path", () => {
43
- expect(parseDomain("example.com/some/path?and&query")).to.eql({
37
+ test("should remove the path", () => {
38
+ expect(parseDomain("example.com/some/path?and&query")).toEqual({
44
39
  subdomain: "",
45
40
  domain: "example",
46
41
  tld: "com",
47
42
  });
48
- expect(parseDomain("example.com/")).to.eql({
43
+ expect(parseDomain("example.com/")).toEqual({
49
44
  subdomain: "",
50
45
  domain: "example",
51
46
  tld: "com",
52
47
  });
53
48
  });
54
49
 
55
- it("should remove the query string", () => {
56
- expect(parseDomain("example.com?and&query")).to.eql({
50
+ test("should remove the query string", () => {
51
+ expect(parseDomain("example.com?and&query")).toEqual({
57
52
  subdomain: "",
58
53
  domain: "example",
59
54
  tld: "com",
60
55
  });
61
56
  });
62
57
 
63
- it("should remove special characters", () => {
64
- expect(parseDomain("http://m.example.com\r")).to.eql({
58
+ test("should remove special characters", () => {
59
+ expect(parseDomain("http://m.example.com\r")).toEqual({
65
60
  subdomain: "m",
66
61
  domain: "example",
67
62
  tld: "com",
68
63
  });
69
64
  });
70
65
 
71
- it("should remove the port", () => {
72
- expect(parseDomain("example.com:8080")).to.eql({
66
+ test("should remove the port", () => {
67
+ expect(parseDomain("example.com:8080")).toEqual({
73
68
  subdomain: "",
74
69
  domain: "example",
75
70
  tld: "com",
76
71
  });
77
72
  });
78
73
 
79
- it("should remove the authentication", () => {
80
- expect(parseDomain("user:password@example.com")).to.eql({
74
+ test("should remove the authentication", () => {
75
+ expect(parseDomain("user:password@example.com")).toEqual({
81
76
  subdomain: "",
82
77
  domain: "example",
83
78
  tld: "com",
84
79
  });
85
80
  });
86
81
 
87
- it("should allow @ characters in the path", () => {
88
- expect(parseDomain("https://medium.com/@username/")).to.eql({
82
+ test("should allow @ characters in the path", () => {
83
+ expect(parseDomain("https://medium.com/@username/")).toEqual({
89
84
  subdomain: "",
90
85
  domain: "medium",
91
86
  tld: "com",
92
87
  });
93
88
  });
94
89
 
95
- it("should also work with three-level domains like .co.uk", () => {
96
- expect(parseDomain("www.example.co.uk")).to.eql({
90
+ test("should also work with three-level domains like .co.uk", () => {
91
+ expect(parseDomain("www.example.co.uk")).toEqual({
97
92
  subdomain: "www",
98
93
  domain: "example",
99
94
  tld: "co.uk",
100
95
  });
101
96
  });
102
97
 
103
- it("should not include private domains like blogspot.com by default", () => {
104
- expect(parseDomain("foo.blogspot.com")).to.eql({
98
+ test("should not include private domains like blogspot.com by default", () => {
99
+ expect(parseDomain("foo.blogspot.com")).toEqual({
105
100
  subdomain: "foo",
106
101
  domain: "blogspot",
107
102
  tld: "com",
108
103
  });
109
104
  });
110
105
 
111
- it("should include private tlds", () => {
112
- expect(parseDomain("foo.blogspot.com", {privateTlds: true})).to.eql({
106
+ test("should include private tlds", () => {
107
+ expect(parseDomain("foo.blogspot.com", {privateTlds: true})).toEqual({
113
108
  subdomain: "",
114
109
  domain: "foo",
115
110
  tld: "blogspot.com",
116
111
  });
117
112
  });
118
113
 
119
- it("should work when all url parts are present", () => {
120
- expect(parseDomain("https://user@www.some.other.subdomain.example.co.uk:8080/some/path?and&query#hash")).to.eql(
121
- {
122
- subdomain: "www.some.other.subdomain",
123
- domain: "example",
124
- tld: "co.uk",
125
- }
126
- );
114
+ test("should work when all url parts are present", () => {
115
+ expect(parseDomain("https://user@www.some.other.subdomain.example.co.uk:8080/some/path?and&query#hash")).toEqual({
116
+ subdomain: "www.some.other.subdomain",
117
+ domain: "example",
118
+ tld: "co.uk",
119
+ });
127
120
  });
128
121
 
129
- it("should also work with the minimum", () => {
130
- expect(parseDomain("example.com")).to.eql({
122
+ test("should also work with the minimum", () => {
123
+ expect(parseDomain("example.com")).toEqual({
131
124
  subdomain: "",
132
125
  domain: "example",
133
126
  tld: "com",
134
127
  });
135
128
  });
136
129
 
137
- it("should return null if the given url contains an unsupported top-level domain", () => {
138
- expect(parseDomain("example.kk")).to.equal(null);
139
- });
130
+ test(
131
+ "should return null if the given url contains an unsupported top-level domain",
132
+ () => {
133
+ expect(parseDomain("example.kk")).toBeNull();
134
+ }
135
+ );
140
136
 
141
- it("should return null if the given value is not a string", () => {
142
- expect(parseDomain(undefined)).to.equal(null);
143
- expect(parseDomain({})).to.equal(null);
137
+ test("should return null if the given value is not a string", () => {
138
+ expect(parseDomain(undefined)).toBeNull();
139
+ expect(parseDomain({})).toBeNull();
144
140
  });
145
141
 
146
- it("should return null if the given string is not a valid URL", () => {
147
- expect(parseDomain("\xa0")).to.equal(null);
148
- expect(parseDomain("")).to.equal(null);
149
- expect(parseDomain(" ")).to.equal(null);
150
- expect(parseDomain("http://hell.d\ne.ibm.com")).to.equal(null);
142
+ test("should return null if the given string is not a valid URL", () => {
143
+ expect(parseDomain("\xa0")).toBeNull();
144
+ expect(parseDomain("")).toBeNull();
145
+ expect(parseDomain(" ")).toBeNull();
146
+ expect(parseDomain("http://hell.d\ne.ibm.com")).toBeNull();
151
147
  });
152
148
 
153
- it("should return null if the given is an empty string with a space character", () => {
154
- expect(parseDomain(" ")).to.equal(null);
155
- });
149
+ test(
150
+ "should return null if the given is an empty string with a space character",
151
+ () => {
152
+ expect(parseDomain(" ")).toBeNull();
153
+ }
154
+ );
156
155
 
157
- it("should work with domains that could match multiple tlds", () => {
158
- expect(parseDomain("http://hello.de.ibm.com")).to.eql({
156
+ test("should work with domains that could match multiple tlds", () => {
157
+ expect(parseDomain("http://hello.de.ibm.com")).toEqual({
159
158
  subdomain: "hello.de",
160
159
  domain: "ibm",
161
160
  tld: "com",
162
161
  });
163
162
  });
164
163
 
165
- it("should work with custom top-level domains (eg .local)", () => {
164
+ test("should work with custom top-level domains (eg .local)", () => {
166
165
  const options = {customTlds: ["local"]};
167
166
 
168
- expect(parseDomain("mymachine.local", options)).to.eql({
167
+ expect(parseDomain("mymachine.local", options)).toEqual({
169
168
  subdomain: "",
170
169
  domain: "mymachine",
171
170
  tld: "local",
172
171
  });
173
172
 
174
173
  // Sanity checks if the option does not misbehave
175
- expect(parseDomain("mymachine.local")).to.eql(null);
176
- expect(parseDomain("http://example.com", options)).to.eql({
174
+ expect(parseDomain("mymachine.local")).toBe(null);
175
+ expect(parseDomain("http://example.com", options)).toEqual({
177
176
  subdomain: "",
178
177
  domain: "example",
179
178
  tld: "com",
180
179
  });
181
180
  });
182
181
 
183
- it("should also work with custom top-level domains passed as regexps", () => {
184
- const options = {customTlds: /(\.local|localhost)$/};
182
+ test(
183
+ "should also work with custom top-level domains passed as regexps",
184
+ () => {
185
+ const options = {customTlds: /(\.local|localhost)$/};
185
186
 
186
- expect(parseDomain("mymachine.local", options)).to.eql({
187
- subdomain: "",
188
- domain: "mymachine",
189
- tld: "local",
190
- });
191
- expect(parseDomain("localhost", options)).to.eql({
192
- subdomain: "",
193
- domain: "",
194
- tld: "localhost",
195
- });
196
- expect(parseDomain("localhost:8080", options)).to.eql({
197
- subdomain: "",
198
- domain: "",
199
- tld: "localhost",
200
- });
187
+ expect(parseDomain("mymachine.local", options)).toEqual({
188
+ subdomain: "",
189
+ domain: "mymachine",
190
+ tld: "local",
191
+ });
192
+ expect(parseDomain("localhost", options)).toEqual({
193
+ subdomain: "",
194
+ domain: "",
195
+ tld: "localhost",
196
+ });
197
+ expect(parseDomain("localhost:8080", options)).toEqual({
198
+ subdomain: "",
199
+ domain: "",
200
+ tld: "localhost",
201
+ });
201
202
 
202
- // Sanity checks if the option does not misbehave
203
- expect(parseDomain("mymachine.local")).to.eql(null);
204
- expect(parseDomain("http://example.com", options)).to.eql({
205
- subdomain: "",
206
- domain: "example",
207
- tld: "com",
208
- });
209
- });
203
+ // Sanity checks if the option does not misbehave
204
+ expect(parseDomain("mymachine.local")).toBe(null);
205
+ expect(parseDomain("http://example.com", options)).toEqual({
206
+ subdomain: "",
207
+ domain: "example",
208
+ tld: "com",
209
+ });
210
+ }
211
+ );
210
212
 
211
213
  describe("real-world use cases", () => {
212
214
  // See https://github.com/peerigon/parse-domain/pull/65
213
- it("should parse police.uk as tld", () => {
214
- expect(parseDomain("example.police.uk")).to.eql({
215
+ test("should parse police.uk as tld", () => {
216
+ expect(parseDomain("example.police.uk")).toEqual({
215
217
  subdomain: "",
216
218
  domain: "example",
217
219
  tld: "police.uk",
@@ -219,12 +221,134 @@ describe("parseDomain(url)", () => {
219
221
  });
220
222
 
221
223
  // See https://github.com/peerigon/parse-domain/issues/67
222
- it.skip("should parse gouv.fr as tld", () => {
223
- expect(parseDomain("dev.classea12.beta.gouv.fr", {privateTlds: true})).to.eql({
224
+ test("should parse gouv.fr as tld", () => {
225
+ expect(parseDomain("dev.classea12.beta.gouv.fr", {privateTlds: true})).toEqual({
224
226
  tld: "gouv.fr",
225
227
  domain: "beta",
226
228
  subdomain: "dev.classea12",
227
229
  });
228
230
  });
229
231
  });
232
+
233
+ describe("official test suite", () => {
234
+ test("passes all inputs", () => {
235
+ function checkPublicSuffix(input, expectedTld) {
236
+ const result = parseDomain(input, {privateTlds: true});
237
+
238
+ if (expectedTld === null) {
239
+ // When the expectedTld is null it means that the domain
240
+ // should not be registerable.
241
+ // Our module will return an empty string for the domain
242
+ // in that case. The tld should match the input.
243
+ expect(result.tld).toBe(input.toLowerCase());
244
+ expect(result.domain).toBe("");
245
+ } else {
246
+ expect(result.domain + "." + result.tld).toBe(expectedTld);
247
+ }
248
+ }
249
+
250
+ // Any copyright is dedicated to the Public Domain.
251
+ // https://creativecommons.org/publicdomain/zero/1.0/
252
+
253
+ // null input.
254
+ // checkPublicSuffix(null, null);
255
+ // Mixed case.
256
+ checkPublicSuffix("COM", null);
257
+ checkPublicSuffix("example.COM", "example.com");
258
+ checkPublicSuffix("WwW.example.COM", "example.com");
259
+ // Leading dot.
260
+ // TODO: Make this test work
261
+ // checkPublicSuffix(".com", null);
262
+ // checkPublicSuffix(".example", null);
263
+ // checkPublicSuffix(".example.com", null);
264
+ // checkPublicSuffix(".example.example", null);
265
+ // Unlisted TLD.
266
+ // This is a strange test case. Why should 'example.example' be registerable when 'example' is unknown?
267
+ // checkPublicSuffix("example", null);
268
+ // checkPublicSuffix("example.example", "example.example");
269
+ // checkPublicSuffix("b.example.example", "example.example");
270
+ // checkPublicSuffix("a.b.example.example", "example.example");
271
+ // Listed, but non-Internet, TLD.
272
+ // checkPublicSuffix('local', null);
273
+ // checkPublicSuffix('example.local', null);
274
+ // checkPublicSuffix('b.example.local', null);
275
+ // checkPublicSuffix('a.b.example.local', null);
276
+ // TLD with only 1 rule.
277
+ checkPublicSuffix("biz", null);
278
+ checkPublicSuffix("domain.biz", "domain.biz");
279
+ checkPublicSuffix("b.domain.biz", "domain.biz");
280
+ checkPublicSuffix("a.b.domain.biz", "domain.biz");
281
+ // TLD with some 2-level rules.
282
+ checkPublicSuffix("com", null);
283
+ checkPublicSuffix("example.com", "example.com");
284
+ checkPublicSuffix("b.example.com", "example.com");
285
+ checkPublicSuffix("a.b.example.com", "example.com");
286
+ checkPublicSuffix("uk.com", null);
287
+ checkPublicSuffix("example.uk.com", "example.uk.com");
288
+ checkPublicSuffix("b.example.uk.com", "example.uk.com");
289
+ checkPublicSuffix("a.b.example.uk.com", "example.uk.com");
290
+ checkPublicSuffix("test.ac", "test.ac");
291
+ // TLD with only 1 (wildcard) rule.
292
+ checkPublicSuffix("mm", null);
293
+ checkPublicSuffix("c.mm", null);
294
+ checkPublicSuffix("b.c.mm", "b.c.mm");
295
+ checkPublicSuffix("a.b.c.mm", "b.c.mm");
296
+ // More complex TLD.
297
+ checkPublicSuffix("jp", null);
298
+ checkPublicSuffix("test.jp", "test.jp");
299
+ checkPublicSuffix("www.test.jp", "test.jp");
300
+ checkPublicSuffix("ac.jp", null);
301
+ checkPublicSuffix("test.ac.jp", "test.ac.jp");
302
+ checkPublicSuffix("www.test.ac.jp", "test.ac.jp");
303
+ checkPublicSuffix("kyoto.jp", null);
304
+ checkPublicSuffix("test.kyoto.jp", "test.kyoto.jp");
305
+ checkPublicSuffix("ide.kyoto.jp", null);
306
+ checkPublicSuffix("b.ide.kyoto.jp", "b.ide.kyoto.jp");
307
+ checkPublicSuffix("a.b.ide.kyoto.jp", "b.ide.kyoto.jp");
308
+ checkPublicSuffix("c.kobe.jp", null);
309
+ checkPublicSuffix("b.c.kobe.jp", "b.c.kobe.jp");
310
+ checkPublicSuffix("a.b.c.kobe.jp", "b.c.kobe.jp");
311
+ checkPublicSuffix("city.kobe.jp", "city.kobe.jp");
312
+ checkPublicSuffix("www.city.kobe.jp", "city.kobe.jp");
313
+ // TLD with a wildcard rule and exceptions.
314
+ checkPublicSuffix("ck", null);
315
+ checkPublicSuffix("test.ck", null);
316
+ checkPublicSuffix("b.test.ck", "b.test.ck");
317
+ checkPublicSuffix("a.b.test.ck", "b.test.ck");
318
+ checkPublicSuffix("www.ck", "www.ck");
319
+ checkPublicSuffix("www.www.ck", "www.ck");
320
+ // US K12.
321
+ checkPublicSuffix("us", null);
322
+ checkPublicSuffix("test.us", "test.us");
323
+ checkPublicSuffix("www.test.us", "test.us");
324
+ checkPublicSuffix("ak.us", null);
325
+ checkPublicSuffix("test.ak.us", "test.ak.us");
326
+ checkPublicSuffix("www.test.ak.us", "test.ak.us");
327
+ checkPublicSuffix("k12.ak.us", null);
328
+ checkPublicSuffix("test.k12.ak.us", "test.k12.ak.us");
329
+ checkPublicSuffix("www.test.k12.ak.us", "test.k12.ak.us");
330
+ // IDN labels.
331
+ checkPublicSuffix("食狮.com.cn", "食狮.com.cn");
332
+ checkPublicSuffix("食狮.公司.cn", "食狮.公司.cn");
333
+ checkPublicSuffix("www.食狮.公司.cn", "食狮.公司.cn");
334
+ checkPublicSuffix("shishi.公司.cn", "shishi.公司.cn");
335
+ checkPublicSuffix("公司.cn", null);
336
+ checkPublicSuffix("食狮.中国", "食狮.中国");
337
+ checkPublicSuffix("www.食狮.中国", "食狮.中国");
338
+ checkPublicSuffix("shishi.中国", "shishi.中国");
339
+ checkPublicSuffix("中国", null);
340
+ // Same as above, but punycoded.
341
+ // Punycode is currently not supported
342
+ // TODO: Make these tests work
343
+ // checkPublicSuffix("xn--85x722f.com.cn", "xn--85x722f.com.cn");
344
+ // checkPublicSuffix("xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn");
345
+ // checkPublicSuffix("www.xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn");
346
+ // checkPublicSuffix("shishi.xn--55qx5d.cn", "shishi.xn--55qx5d.cn");
347
+ // checkPublicSuffix("xn--55qx5d.cn", null);
348
+ // checkPublicSuffix("xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s");
349
+ // checkPublicSuffix("www.xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s");
350
+ // checkPublicSuffix("shishi.xn--fiqs8s", "shishi.xn--fiqs8s");
351
+ // checkPublicSuffix("xn--fiqs8s", null);
352
+ });
353
+ });
230
354
  });
@@ -2,13 +2,9 @@
2
2
 
3
3
  const fs = require("fs");
4
4
  const path = require("path");
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");
5
+ const parsePubSuffixList = require("../lib/trie/parsePubSuffixList");
6
+ const serializeTrie = require("../lib/trie/serializeTrie");
10
7
 
11
- const expect = chai.expect;
12
8
  const TEST_SNAPSHOT = true;
13
9
  const pathToFixtures = path.resolve(__dirname, "fixtures");
14
10
  const pathToSnapshots = path.resolve(__dirname, "snapshots");
@@ -17,42 +13,23 @@ const pathToSerializeTrieSnapshot = path.resolve(pathToSnapshots, "serializeTrie
17
13
 
18
14
  describe("snapshots", () => {
19
15
  describe("parsePubSuffixList()", () => {
20
- it("matches the approved snapshot", () => {
16
+ test("matches the approved snapshot", () => {
21
17
  const pubSuffixList = fs.readFileSync(path.resolve(pathToFixtures, "pubSuffixList.txt"), "utf8");
22
18
  const parsedList = parsePubSuffixList(pubSuffixList);
23
19
  const snapshot = JSON.parse(fs.readFileSync(pathToParsePubSuffixListSnapshot, "utf8"));
24
20
 
25
- TEST_SNAPSHOT && expect(parsedList).to.eql(snapshot);
21
+ TEST_SNAPSHOT && expect(parsedList).toEqual(snapshot);
26
22
  fs.writeFileSync(pathToParsePubSuffixListSnapshot, JSON.stringify(parsedList));
27
23
  });
28
24
  });
29
25
  describe("serializeTrie()", () => {
30
- it("matches the approved snapshot", () => {
26
+ test("matches the approved snapshot", () => {
31
27
  const parsedList = JSON.parse(fs.readFileSync(pathToParsePubSuffixListSnapshot, "utf8"));
32
28
  const snapshot = JSON.parse(fs.readFileSync(pathToSerializeTrieSnapshot, "utf8"));
33
29
  const serializedTrie = serializeTrie(parsedList.icann);
34
30
 
35
- TEST_SNAPSHOT && expect(serializedTrie).to.eql(snapshot);
31
+ TEST_SNAPSHOT && expect(serializedTrie).toEqual(snapshot);
36
32
  fs.writeFileSync(pathToSerializeTrieSnapshot, JSON.stringify(serializedTrie));
37
33
  });
38
34
  });
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
35
  });
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ const lookUp = require("../../lib/trie/lookUp");
4
+ const characters = require("../../lib/trie/characters");
5
+ const {createNode, adoptChild} = require("../../lib/trie/nodes");
6
+
7
+ function createOneLevelDeepTrie() {
8
+ const root = createNode();
9
+ const com = createNode("com");
10
+
11
+ adoptChild(root, com);
12
+
13
+ return root;
14
+ }
15
+
16
+ function createTwoLevelDeepTrie() {
17
+ const root = createNode();
18
+ const uk = createNode("uk");
19
+ const co = createNode("co");
20
+
21
+ adoptChild(root, uk);
22
+ adoptChild(uk, co);
23
+
24
+ return root;
25
+ }
26
+
27
+ function createTrieWithWildcardAndException() {
28
+ const root = createNode();
29
+ const wildcard = createNode(characters.WILDCARD);
30
+ const exception = createNode(characters.EXCEPTION + "exception");
31
+
32
+ adoptChild(root, wildcard);
33
+ adoptChild(root, exception);
34
+
35
+ return root;
36
+ }
37
+
38
+ describe("lookUp()", () => {
39
+ describe("with an empty trie", () => {
40
+ test("returns an empty array", () => {
41
+ const root = createNode();
42
+
43
+ expect(lookUp(root, ["com"])).toEqual([]);
44
+ expect(lookUp(root, ["example", "com"])).toEqual([]);
45
+ });
46
+ });
47
+ describe("with a one level deep trie", () => {
48
+ test("returns the known TLD as array", () => {
49
+ const root = createOneLevelDeepTrie();
50
+
51
+ expect(lookUp(root, ["com"])).toEqual(["com"]);
52
+ expect(lookUp(root, ["example", "com"])).toEqual(["com"]);
53
+ expect(lookUp(root, ["www", "example", "com"])).toEqual(["com"]);
54
+ });
55
+ test("returns an empty array if there is no known TLD", () => {
56
+ const root = createOneLevelDeepTrie();
57
+
58
+ expect(lookUp(root, ["de"])).toEqual([]);
59
+ expect(lookUp(root, ["example", "de"])).toEqual([]);
60
+ expect(lookUp(root, ["www", "example", "de"])).toEqual([]);
61
+ });
62
+ });
63
+ describe("with a two level deep trie", () => {
64
+ test("returns the known TLD", () => {
65
+ const root = createTwoLevelDeepTrie();
66
+
67
+ expect(lookUp(root, ["uk"])).toEqual(["uk"]);
68
+ expect(lookUp(root, ["example", "uk"])).toEqual(["uk"]);
69
+ expect(lookUp(root, ["co", "uk"])).toEqual(["co", "uk"]);
70
+ expect(lookUp(root, ["example", "co", "uk"])).toEqual(["co", "uk"]);
71
+ expect(lookUp(root, ["www", "example", "co", "uk"])).toEqual(["co", "uk"]);
72
+ });
73
+
74
+ test("returns an empty array if there is no known TLD", () => {
75
+ const root = createTwoLevelDeepTrie();
76
+
77
+ expect(lookUp(root, ["de"])).toEqual([]);
78
+ expect(lookUp(root, ["example", "de"])).toEqual([]);
79
+ expect(lookUp(root, ["www", "example", "de"])).toEqual([]);
80
+ });
81
+ });
82
+ describe("with a wildcard and exceptions", () => {
83
+ test("does not accept the exception as TLD", () => {
84
+ const root = createTrieWithWildcardAndException();
85
+
86
+ expect(lookUp(root, ["exception"])).toEqual([]);
87
+ expect(lookUp(root, ["www", "exception"])).toEqual([]);
88
+ });
89
+ test("accepts all domain names as TLD in place of the wildcard", () => {
90
+ const root = createTrieWithWildcardAndException();
91
+
92
+ expect(lookUp(root, ["anything"])).toEqual(["anything"]);
93
+ expect(lookUp(root, ["www", "anything"])).toEqual(["anything"]);
94
+ });
95
+ });
96
+ });
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ const {createNode, adoptChild} = require("../../lib/trie/nodes");
4
+
5
+ describe("adoptChild()", () => {
6
+ test("throws an error if the child has no domain", () => {
7
+ expect(() => {
8
+ adoptChild(createNode(), createNode());
9
+ }).toThrowError("Cannot adopt child: child.domain must be a string");
10
+ });
11
+ test(
12
+ "throws an error if the parent has already a child with that domain",
13
+ () => {
14
+ expect(() => {
15
+ const parent = createNode();
16
+
17
+ adoptChild(parent, createNode("some-domain"));
18
+ adoptChild(parent, createNode("some-domain"));
19
+ }).toThrowError(
20
+ "Cannot adopt child: parent has already a child with the domain 'some-domain'"
21
+ );
22
+ }
23
+ );
24
+ });