Skip to content

Commit 88f3ce9

Browse files
committed
fix(patterns): Implement M.null() and M.undefined() as Key Patterns
Fixes #1601
1 parent cebc442 commit 88f3ce9

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

packages/patterns/src/patterns/patternMatchers.js

+12
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ const makePatternKit = () => {
167167
* that the store level associates with that kind.
168168
*/
169169

170+
/** @type {Map<Kind, unknown>} */
171+
const singletonKinds = new Map([
172+
['null', null],
173+
['undefined', undefined],
174+
]);
175+
170176
/**
171177
* @type {WeakMap<CopyTagged, Kind>}
172178
* Only for tagged records of recognized kinds whose store-level invariants
@@ -251,6 +257,12 @@ const makePatternKit = () => {
251257
* @returns {boolean}
252258
*/
253259
const checkKind = (specimen, kind, check) => {
260+
// check null and undefined as Keys
261+
if (singletonKinds.has(kind)) {
262+
// eslint-disable-next-line no-use-before-define
263+
return checkAsKeyPatt(specimen, singletonKinds.get(kind), check);
264+
}
265+
254266
const realKind = kindOf(specimen, check);
255267
if (kind === realKind) {
256268
return true;

packages/patterns/test/test-patterns.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ const runTests = (successCase, failCase) => {
4343
remotable: (repr, kind) => `${kind} ${repr} - Must be a remotable`,
4444
error: (repr, kind) => `${kind} ${repr} - Must be a error`,
4545
promise: (repr, kind) => `${kind} ${repr} - Must be a promise`,
46-
undefined: (repr, kind) => `${kind} ${repr} - Must be a undefined`,
46+
// M.undefined() and M.null() match as exact Keys rather than kinds.
47+
undefined: repr => `${repr} - Must be: "[undefined]"`,
4748
null: repr => `${repr} - Must be: null`,
4849
};
50+
const tagIgnorantMethods = ['scalar', 'key', 'undefined', 'null'];
4951

5052
{
5153
const specimen = 3;
@@ -525,7 +527,7 @@ const runTests = (successCase, failCase) => {
525527
continue;
526528
}
527529
// This specimen is not a Key, so testing is less straightforward.
528-
if (method === 'scalar' || method === 'key' || method === 'null') {
530+
if (tagIgnorantMethods.includes(method)) {
529531
successCase(specimen, M.not(M[method]()));
530532
failCase(
531533
specimen,
@@ -567,10 +569,9 @@ const runTests = (successCase, failCase) => {
567569
continue;
568570
}
569571
// This specimen has an invalid payload for its tag, so testing is less straightforward.
570-
const message =
571-
method === 'scalar' || method === 'key' || method === 'null'
572-
? makeMessage('"[match:any]"', 'match:any', 'tagged')
573-
: 'match:any payload: 88 - Must be undefined';
572+
const message = tagIgnorantMethods.includes(method)
573+
? makeMessage('"[match:any]"', 'match:any', 'tagged')
574+
: 'match:any payload: 88 - Must be undefined';
574575
successCase(specimen, M.not(M[method]()));
575576
failCase(specimen, M[method](), message);
576577
}
@@ -584,7 +585,7 @@ const runTests = (successCase, failCase) => {
584585
continue;
585586
}
586587
// This specimen is not a Key, so testing is less straightforward.
587-
if (method === 'scalar' || method === 'key' || method === 'null') {
588+
if (tagIgnorantMethods.includes(method)) {
588589
successCase(specimen, M.not(M[method]()));
589590
failCase(
590591
specimen,

0 commit comments

Comments
 (0)