Skip to content

Commit f3d1e63

Browse files
committed
refactor(if_match): move if-match parser module
1 parent 6d43a63 commit f3d1e63

File tree

3 files changed

+96
-15
lines changed

3 files changed

+96
-15
lines changed

if_match.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
2+
// This module is browser compatible.
3+
4+
// TODO(miyauci): External Packaging
5+
6+
import { type ETag, parseETag } from "./deps.ts";
7+
8+
export type IfMatch = Star | ETag[];
9+
export type IfNoneMatch = IfMatch;
10+
export type Star = "*";
11+
12+
/** Parses string into {@link IfMatch}({@link IfNoneMatch}).
13+
* @throws {SyntaxError} If the input is invalid.
14+
*/
15+
export function parse(input: string): IfMatch | IfNoneMatch {
16+
input = input.trim();
17+
18+
if (input === "*") return input;
19+
20+
return input
21+
.split(",")
22+
.filter(Boolean)
23+
.map(parseETag);
24+
}

if_match_test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { parse } from "./if_match.ts";
2+
import { type ETag } from "./deps.ts";
3+
import { assertEquals, assertThrows, describe, it } from "./_dev_deps.ts";
4+
5+
describe("parse", () => {
6+
it("should return star", () => {
7+
const table: string[] = [
8+
"*",
9+
" *",
10+
"* ",
11+
" * ",
12+
];
13+
14+
table.forEach((input) => {
15+
assertEquals(parse(input), "*");
16+
});
17+
});
18+
19+
it("should return empty list", () => {
20+
const table: string[] = [
21+
"",
22+
" ",
23+
];
24+
25+
table.forEach((input) => {
26+
assertEquals(parse(input), []);
27+
});
28+
});
29+
30+
it("should return etag list", () => {
31+
const table: [string, ETag[]][] = [
32+
[`""`, [{ tag: "", weak: false }]],
33+
[`"", "a", "b"`, [{ tag: "", weak: false }, { tag: "a", weak: false }, {
34+
tag: "b",
35+
weak: false,
36+
}]],
37+
[`W/"", "a", W/"abc"`, [{ tag: "", weak: true }, {
38+
tag: "a",
39+
weak: false,
40+
}, {
41+
tag: "abc",
42+
weak: true,
43+
}]],
44+
[`"", "*"`, [{ tag: "", weak: false }, {
45+
tag: "*",
46+
weak: false,
47+
}]],
48+
];
49+
50+
table.forEach(([input, expected]) => {
51+
assertEquals(parse(input), expected);
52+
});
53+
});
54+
55+
it("should throw error if the input is invalid syntax", () => {
56+
const table: string[] = [
57+
`"`,
58+
"* a",
59+
"*,",
60+
`*, ""`,
61+
`","`,
62+
`* *`,
63+
`**`,
64+
`"", *`,
65+
];
66+
67+
table.forEach((input) => {
68+
assertThrows(() => parse(input));
69+
});
70+
});
71+
});

preconditions/utils.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
parseHttpDate,
1010
RepresentationHeader,
1111
} from "../deps.ts";
12+
import { parse } from "../if_match.ts";
1213

1314
/** Match `If-Match` field and `ETag` field.
1415
* @throws {SyntaxError} If the input is invalid syntax.
@@ -158,18 +159,3 @@ export function isBannedHeader(fieldName: string): boolean {
158159
}
159160

160161
export type Star = "*";
161-
export type IfNoneMatch = Star | ETag[];
162-
export type IfMatch = IfNoneMatch;
163-
164-
/**
165-
* @throws {SyntaxError} If the input is invalid.
166-
*/
167-
export function parse(input: string): IfMatch | IfNoneMatch {
168-
input = input.trim();
169-
170-
if (isStar(input)) return input;
171-
172-
return input
173-
.split(",")
174-
.map(parseETag);
175-
}

0 commit comments

Comments
 (0)