Skip to content

Commit

Permalink
[IMP] Bump support for Node 18+
Browse files Browse the repository at this point in the history
This commit bump the support for Node 18+.
Some tests was adapted due to some change in Error Handling in V8 (NodeJS v20+)
  • Loading branch information
rfr-odoo committed Oct 8, 2024
1 parent 20c6cac commit 12ad412
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
node-version: [18.x, 20.x, 22.x]

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dist"
],
"engines": {
"node": ">=12.18.3"
"node": ">=18.0.0"
},
"scripts": {
"build:bundle": "rollup -c --failAfterWarnings",
Expand Down
22 changes: 20 additions & 2 deletions tests/compiler/validation.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TemplateSet } from "../../src/runtime/template_set";
import { renderToString, snapshotTemplate, TestContext } from "../helpers";
import { isNode20Plus, isNotNode20Plus, renderToString, snapshotTemplate, TestContext, testIf } from "../helpers";

// -----------------------------------------------------------------------------
// basic validation
Expand Down Expand Up @@ -45,11 +45,29 @@ describe("basic validation", () => {
expect(() => renderToString(template)).toThrow("Unknown QWeb directive: 't-best-beer'");
});

test("compilation error", () => {
testIf(isNotNode20Plus, "compilation error (NodeJS < 20)", () => {
const template = `<div t-att-class="a b">test</div>`;
expect(() => renderToString(template))
.toThrow(`Failed to compile anonymous template: Unexpected identifier
generated code:
function(app, bdom, helpers) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0="class">test</div>\`);
return function template(ctx, node, key = "") {
let attr1 = ctx['a']ctx['b'];
return block1([attr1]);
}
}`);

});
testIf(isNode20Plus, "compilation error (NodeJS 20+)", () => {
const template = `<div t-att-class="a b">test</div>`;
expect(() => renderToString(template))
.toThrow(`Failed to compile anonymous template: Unexpected identifier 'ctx'
generated code:
function(app, bdom, helpers) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
Expand Down
66 changes: 64 additions & 2 deletions tests/components/error_handling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import {
useLogLifecycle,
nextAppError,
steps,
testIf,
isNotNode20Plus,
isNode20Plus,
} from "../helpers";
import { OwlError } from "../../src/common/owl_error";

Expand Down Expand Up @@ -144,7 +147,7 @@ describe("basics", () => {
);
});

test("display a nice error if the root component template fails to compile", async () => {
testIf(isNotNode20Plus, "display a nice error if the root component template fails to compile", async () => {
// This is a special case: mount throws synchronously and we don't have any
// node which can handle the error, hence the different structure of this test
class Comp extends Component {
Expand Down Expand Up @@ -174,7 +177,37 @@ function(app, bdom, helpers) {
expect(error!.message).toBe(expectedErrorMessage);
});

test("display a nice error if a non-root component template fails to compile", async () => {
testIf(isNode20Plus, "display a nice error if the root component template fails to compile", async () => {
// This is a special case: mount throws synchronously and we don't have any
// node which can handle the error, hence the different structure of this test
class Comp extends Component {
static template = xml`<div t-att-class="a b">test</div>`;
}
const app = new App(Comp);
let error: Error;
try {
await app.mount(fixture);
} catch (e) {
error = e as Error;
}
const expectedErrorMessage = `Failed to compile anonymous template: Unexpected identifier 'ctx'
generated code:
function(app, bdom, helpers) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0="class">test</div>\`);
return function template(ctx, node, key = "") {
let attr1 = ctx['a']ctx['b'];
return block1([attr1]);
}
}`;
expect(error!).toBeDefined();
expect(error!.message).toBe(expectedErrorMessage);
});

testIf(isNotNode20Plus, "display a nice error if a non-root component template fails to compile", async () => {
class Child extends Component {
static template = xml`<div t-att-class="a b">test</div>`;
}
Expand All @@ -183,6 +216,35 @@ function(app, bdom, helpers) {
static template = xml`<Child/>`;
}
const expectedErrorMessage = `Failed to compile anonymous template: Unexpected identifier
generated code:
function(app, bdom, helpers) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
let block1 = createBlock(\`<div block-attribute-0="class">test</div>\`);
return function template(ctx, node, key = "") {
let attr1 = ctx['a']ctx['b'];
return block1([attr1]);
}
}`;
const app = new App(Parent as typeof Component);
let error: Error;
const mountProm = app.mount(fixture).catch((e: Error) => (error = e));
await expect(nextAppError(app)).resolves.toThrow(expectedErrorMessage);
await mountProm;
expect(error!).toBeDefined();
expect(error!.message).toBe(expectedErrorMessage);
});

testIf(isNode20Plus, "display a nice error if a non-root component template fails to compile", async () => {
class Child extends Component {
static template = xml`<div t-att-class="a b">test</div>`;
}
class Parent extends Component {
static components = { Child };
static template = xml`<Child/>`;
}
const expectedErrorMessage = `Failed to compile anonymous template: Unexpected identifier 'ctx'
generated code:
function(app, bdom, helpers) {
Expand Down
11 changes: 11 additions & 0 deletions tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ export function nextAppError(app: any) {
});
}

export function testIf(predicate: Function, testName: string, testFn?: jest.ProvidesCallback) {
if (predicate()) {
test(testName, testFn);
} else {
test.skip(testName, testFn);
}
}

export const isNode20Plus = () => Number(process.versions.node.split('.')[0]) >= 20;
export const isNotNode20Plus = () => !isNode20Plus();

declare global {
namespace jest {
interface Matchers<R> {
Expand Down

0 comments on commit 12ad412

Please sign in to comment.