forked from babel/babel
/
isPure.js
109 lines (100 loc) 路 3.21 KB
/
isPure.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { parse } from "@babel/parser";
import _traverse from "../../lib/index.js";
const traverse = _traverse.default;
function getPath(code) {
const ast = parse(code, {
plugins: [
["decorators", { version: "2021-12", decoratorsBeforeExport: true }],
["recordAndTuple", { syntaxType: "hash" }],
"decoratorAutoAccessors",
["pipelineOperator", { proposal: "hack", topicToken: "%" }],
],
});
let path;
traverse(ast, {
Program: function (_path) {
path = _path;
_path.stop();
},
});
return path;
}
describe("isPure() returns true", () => {
it.each([
"class C { [0]() {} }",
"class C extends class {} {}",
"class C { static accessor x = 1; accessor y = f() }",
"class C { #x = f(); static #y }",
"class C { static target = new.target }",
"class X { get foo() { return 1 } set foo(v) {} }",
])(`NodePath(%p).get("body.0").isPure() should be true`, input => {
const path = getPath(input).get("body.0");
expect(path.node).toBeTruthy();
expect(path.isPure()).toBe(true);
});
it.each([
"({ x: 1, foo() { return 1 } })",
"String.raw`foo`",
`"a" + "b"`,
`[function () {}]`,
`#{ 0: 0, 1n: 1, two: "two"}`,
`#[0, 1n, "2", \`3\`]`,
`[,]`,
`-1 || void 0`,
`null ?? (true && false)`,
`this`,
])(`NodePath(%p).get("body.0.expression").isPure() should be true`, input => {
const path = getPath(input).get("body.0.expression");
expect(path.node).toBeTruthy();
expect(path.isPure()).toBe(true);
});
it.each(["let a = 1; `${a}`", `let a = 1; a |> % + %`])(
`NodePath(%p).get("body.1.expression").isPure() should be true`,
input => {
const path = getPath(input).get("body.1.expression");
expect(path.node).toBeTruthy();
expect(path.isPure()).toBe(true);
},
);
});
describe("isPure() returns false", () => {
it.each([
"@dec() class X {}",
"@dec class C {}; function dec () {}",
"class C { @dec foo() {} }",
"class C { @dec foo }",
"class C { @dec accessor foo = 1 }",
"class C { static {} }",
"class C extends class { [f()] } {}",
])(`NodePath(%p).get("body.0").isPure() should be false`, input => {
const path = getPath(input).get("body.0");
expect(path.node).toBeTruthy();
expect(path.isPure()).toBe(false);
});
it.each(["`${a}`", "tagged`foo`"])(
`NodePath(%p).get("body.0.expression").isPure() should be false`,
input => {
const path = getPath(input).get("body.0.expression");
expect(path.node).toBeTruthy();
expect(path.isPure()).toBe(false);
},
);
it.each(["let a = 1; `${a++}`"])(
`NodePath(%p).get("body.1.expression").isPure() should be false`,
input => {
const path = getPath(input).get("body.1.expression");
expect(path.node).toBeTruthy();
expect(path.isPure()).toBe(false);
},
);
});
describe("isPure(constantsOnly: true) returns false", () => {
it.each(["x", "1 + x", "({ [x]: 0 })", "(class { static x = x })"])(
`NodePath(%p).get("body.0.expression").isPure(/* constantsOnly */true) should be false`,
input => {
const path = getPath(input).get("body.0.expression");
expect(path.node).toBeTruthy();
expect(path.isPure(true)).toBe(false);
},
);
});