Skip to content

Commit f277068

Browse files
johnjenkinsJohn Jenkins
andauthored
fix(test): trigger @watch decorators on inherited classes in jest env (#6402)
* fix(test): trigger @watch decorators on inherited classes in jest env * chore: lint * chore: prettier * chore: fixup testing --------- Co-authored-by: John Jenkins <[email protected]>
1 parent 32160ad commit f277068

File tree

3 files changed

+57
-6
lines changed

3 files changed

+57
-6
lines changed

src/compiler/transformers/static-to-meta/class-extension.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,19 @@ function buildExtendsTree(
170170
} catch (_e) {
171171
// sad path (normally >1 levels removed): the extends type does not resolve so let's find it manually:
172172

173-
const currentSource = classDeclaration.getSourceFile();
174-
if (!currentSource) return;
173+
let currentSource: ts.SourceFile = classDeclaration.getSourceFile();
174+
// try to see if we can find the class in the current source file first
175+
let matchedStatement: ts.ClassDeclaration | ts.FunctionDeclaration | ts.VariableStatement;
176+
177+
if (!currentSource) {
178+
// fallback for jest tests where getSourceFile() is undefined
179+
currentSource = compilerCtx.moduleMap.entries().next()?.value[1]?.staticSourceFile;
180+
matchedStatement = findClassWalk(currentSource, extendee.getText());
181+
} else {
182+
matchedStatement = currentSource.statements.find(matchesNamedDeclaration(extendee.getText()));
183+
}
175184

176-
// let's see if we can find the class in the current source file first
177-
const matchedStatement = currentSource.statements.find(matchesNamedDeclaration(extendee.getText()));
185+
if (!currentSource) return;
178186

179187
if (matchedStatement && ts.isClassDeclaration(matchedStatement)) {
180188
foundClassDeclaration = matchedStatement;

src/compiler/transformers/static-to-meta/visitor.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ export const convertStaticToMeta = (
4646
moduleFile.isCollectionDependency = false;
4747
moduleFile.collectionName = null;
4848
}
49-
49+
if (!moduleFile.staticSourceFile) {
50+
moduleFile.staticSourceFile = tsSourceFile;
51+
moduleFile.staticSourceFileText = tsSourceFile.getFullText();
52+
}
5053
return visitNode(tsSourceFile) as ts.SourceFile;
5154
};
5255
};

src/runtime/test/extends-basic.spec.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
import { Component } from '@stencil/core';
1+
import { Component, h, Prop, Watch } from '@stencil/core';
22
import { newSpecPage } from '@stencil/core/testing';
33

4+
declare global {
5+
namespace JSX {
6+
interface IntrinsicElements {
7+
[elemName: string]: any;
8+
}
9+
}
10+
}
11+
412
describe('extends', () => {
513
it('renders a component that extends from a base class', async () => {
614
class Base {
@@ -22,4 +30,36 @@ describe('extends', () => {
2230
<cmp-a>base</cmp-a>
2331
`);
2432
});
33+
34+
it('should call inherited watch methods when props change', async () => {
35+
let called = 0;
36+
37+
class BaseWatch {
38+
@Prop() foo: string;
39+
40+
@Watch('foo')
41+
fooChanged() {
42+
called++;
43+
}
44+
}
45+
46+
@Component({ tag: 'extended-component' })
47+
class ExtendedComponent extends BaseWatch {
48+
render() {
49+
return <div>{this.foo}</div>;
50+
}
51+
}
52+
53+
const { root } = await newSpecPage({
54+
components: [ExtendedComponent],
55+
html: `<extended-component></extended-component>`,
56+
});
57+
58+
expect(called).toBe(0);
59+
60+
root.foo = '1';
61+
62+
expect(called).toBe(1);
63+
expect(root.foo).toBe('1');
64+
});
2565
});

0 commit comments

Comments
 (0)