grapheme-conformance 0.1.3 → 0.1.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.
package/README.md CHANGED
@@ -45,10 +45,22 @@ Cases passed:
45
45
  | `grapheme-splitter@1.0.4` | 1175 | 1081 |
46
46
  | `runes2@1.1.4` | 730 | 695 |
47
47
 
48
- `Intl.Segmenter`'s single failure is the input `2701 200D 2701`, a known ICU
49
- deviation and one that arrived with a later ICU rather than an earlier one.
50
- Node 18.20.8 ships an ICU without it and passes every case (`1187` and `1093`);
51
- Node 20 and 22 split that input and score `1186` and `1092`.
48
+ The one case `Intl.Segmenter` misses in both columns is `2701 200D 2701`, and
49
+ it is an artefact of the answer key, not a bug in ICU. Unicode 17.0 removed
50
+ U+2701 from `Extended_Pictographic`, so GB11 no longer applies and the correct
51
+ result became **two** clusters. Scored against the `17.0.0` key, ICU on Node 22
52
+ passes every case:
53
+
54
+ | implementation | U17.0.0 (766) |
55
+ |---|---|
56
+ | `Intl.Segmenter` (ICU, Node 22) | 766 |
57
+ | `unicode-segmenter@0.17.3` | 766 |
58
+ | `graphemer@1.4.0` | 749 |
59
+ | `grapheme-splitter@1.0.4` | 746 |
60
+ | `runes2@1.1.4` | 501 |
61
+
62
+ Score an implementation against the key it targets. A current segmenter judged
63
+ by a superseded key reports failures it does not have.
52
64
 
53
65
  ## Install
54
66
 
@@ -62,23 +74,20 @@ Zero runtime dependencies. Dual ESM/CJS. Node 18+.
62
74
 
63
75
  ```sh
64
76
  npx grapheme-conformance --module unicode-segmenter/grapheme \
65
- --export splitGraphemes --version 16.0.0
77
+ --export splitGraphemes
66
78
  ```
67
79
 
68
80
  ```
69
- unicode-segmenter/grapheme (splitGraphemes) GraphemeBreakTest 16.0.0
70
- passed 1092/1093 99.91%
71
- failed 1
72
-
73
- line input want got rule
74
- 1105 2701 200D 2701 1 2 -
81
+ unicode-segmenter/grapheme (splitGraphemes) GraphemeBreakTest 17.0.0
82
+ passed 766/766 100.00%
83
+ failed 0
75
84
  ```
76
85
 
77
86
  | flag | default | meaning |
78
87
  |---|---|---|
79
88
  | `--module` | required | module to load: a bare name, or a path relative to cwd |
80
89
  | `--export` | `default` | the export to score |
81
- | `--version` | `16.0.0` | vendored vectors: `15.0.0`, `15.1.0`, `16.0.0`, `17.0.0` |
90
+ | `--version` | `17.0.0` | vendored vectors: `15.0.0`, `15.1.0`, `16.0.0`, `17.0.0` |
82
91
  | `--min` | `1.0` | minimum pass rate before exiting non-zero |
83
92
  | `--limit` | `10` | failing cases to print |
84
93
 
@@ -94,13 +103,13 @@ import { parseBreakTest, score, vectors } from 'grapheme-conformance';
94
103
  const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
95
104
  const report = score(
96
105
  (s) => [...segmenter.segment(s)].map((part) => part.segment),
97
- vectors['16.0.0'],
106
+ vectors['17.0.0'],
98
107
  );
99
108
 
100
- report.passed; // 1092
101
- report.total; // 1093
102
- report.rate; // 0.999085...
103
- report.failures[0].inputHex; // '2701 200D 2701'
109
+ report.passed; // 766
110
+ report.total; // 766
111
+ report.rate; // 1
112
+ report.failures; // []
104
113
  ```
105
114
 
106
115
  ```ts
@@ -149,9 +158,12 @@ UAX #29 and does not prove which rule an implementation actually got wrong.
149
158
  ## Intl.Segmenter and the host ICU
150
159
 
151
160
  `Intl.Segmenter` is scored against whatever ICU the host Node ships, so its row
152
- moves with the runtime, and not monotonically: Node 18.20.8 scores higher than
153
- Node 22 because the `2701 200D 2701` deviation is a newer ICU behaviour. The
154
- pure-JS libraries are pinned to exact versions and score identically everywhere.
161
+ moves with the runtime. Against the older keys the movement is not even
162
+ monotonic: Node 18.20.8 scores `1187` and `1093` where Node 20 and 22 score
163
+ `1186` and `1092`, because newer ICU implements the Unicode 17.0 property
164
+ change that those keys predate. Against the `17.0.0` key every one of them is
165
+ correct. The pure-JS libraries are pinned to exact versions and score
166
+ identically everywhere.
155
167
 
156
168
  ## Verifying this build
157
169
 
package/dist/cli.cjs CHANGED
@@ -212,7 +212,7 @@ async function main() {
212
212
  console.log(USAGE);
213
213
  process.exit(args.module ? 0 : 2);
214
214
  }
215
- const version = args.version ?? "16.0.0";
215
+ const version = args.version ?? "17.0.0";
216
216
  const cases = vectors[version];
217
217
  if (!cases) fail(`Unknown version '${version}'. Have: ${Object.keys(vectors).join(", ")}`);
218
218
  const min = args.min === void 0 ? 1 : Number(args.min);
package/dist/cli.js CHANGED
@@ -207,7 +207,7 @@ async function main() {
207
207
  console.log(USAGE);
208
208
  process.exit(args.module ? 0 : 2);
209
209
  }
210
- const version = args.version ?? "16.0.0";
210
+ const version = args.version ?? "17.0.0";
211
211
  const cases = vectors[version];
212
212
  if (!cases) fail(`Unknown version '${version}'. Have: ${Object.keys(vectors).join(", ")}`);
213
213
  const min = args.min === void 0 ? 1 : Number(args.min);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grapheme-conformance",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Score any JavaScript grapheme segmenter against Unicode's official GraphemeBreakTest.txt. Find out which string splitters are wrong, and about what.",
5
5
  "keywords": [
6
6
  "unicode",