|
1 | 1 | import traverse from "../lib"; |
2 | 2 | import { parse } from "@babel/parser"; |
| 3 | +import * as t from "@babel/types"; |
3 | 4 |
|
4 | 5 | describe("path/family", function () { |
5 | 6 | describe("getBindingIdentifiers", function () { |
@@ -81,6 +82,32 @@ describe("path/family", function () { |
81 | 82 | expect(sibling.getAllNextSiblings()).toHaveLength(2); |
82 | 83 | expect(lastSibling.getAllPrevSiblings()).toHaveLength(2); |
83 | 84 | }); |
| 85 | + |
| 86 | + it("should initialize path.scope when needed", function () { |
| 87 | + const ast = parse("if (0) {}"); |
| 88 | + |
| 89 | + let testHasScope = false; |
| 90 | + let consequentHasScope = false; |
| 91 | + |
| 92 | + traverse(ast, { |
| 93 | + IfStatement(path) { |
| 94 | + // @babel/traverse pre-traverses the whole tree to populate the initial |
| 95 | + // scope. Thus, it pre-caches paths for all the original nodes. |
| 96 | + // We need to introduce two new nodes to avoid using the cached paths |
| 97 | + // that already have the path.scope property. |
| 98 | + path.set("test", t.identifier("a")); |
| 99 | + path.set("consequent", t.expressionStatement(t.identifier("b"))); |
| 100 | + |
| 101 | + const testPath = path.get("test"); |
| 102 | + |
| 103 | + testHasScope = !!testPath.scope; |
| 104 | + consequentHasScope = !!testPath.getSibling("consequent").scope; |
| 105 | + }, |
| 106 | + }); |
| 107 | + |
| 108 | + expect(testHasScope).toBe(true); |
| 109 | + expect(consequentHasScope).toBe(true); |
| 110 | + }); |
84 | 111 | }); |
85 | 112 | }); |
86 | 113 |
|
|
0 commit comments