From 6ad177c55bb5ea6f47cf741487308ee612c75222 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Sat, 23 Sep 2023 13:59:35 -0400 Subject: [PATCH] add some js decorator printing tests --- .../bundler_tests/bundler_default_test.go | 84 ++++++++++++++++ .../snapshots/snapshots_default.txt | 96 +++++++++++++++++++ internal/js_parser/js_parser_test.go | 5 + 3 files changed, 185 insertions(+) diff --git a/internal/bundler_tests/bundler_default_test.go b/internal/bundler_tests/bundler_default_test.go index a36a5d3a0c0..4b0ca439c74 100644 --- a/internal/bundler_tests/bundler_default_test.go +++ b/internal/bundler_tests/bundler_default_test.go @@ -8448,3 +8448,87 @@ NOTE: You can mark the path "bar" as external to exclude it from the bundle, whi `, }) } + +func TestDecoratorPrintingESM(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + import { constant } from './constants' + import { imported } from 'somewhere' + import { undef } from './empty' + + _ = class Outer { + #bar; + + classes = [ + class { @imported @imported() imported }, + class { @unbound @unbound() unbound }, + class { @constant @constant() constant }, + class { @undef @undef() undef }, + + class { @(element[access]) indexed }, + class { @foo.#bar private }, + class { @foo.\u30FF unicode }, + class { @(() => {}) arrow }, + ] + } + `, + "/constants.js": ` + export const constant = 123 + `, + "/empty.js": ``, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + Mode: config.ModeBundle, + OutputFormat: config.FormatESModule, + AbsOutputFile: "/out.js", + ExternalPackages: true, + MinifySyntax: true, + }, + expectedCompileLog: `entry.js: WARNING: Import "undef" will always be undefined because the file "empty.js" has no exports +`, + }) +} + +func TestDecoratorPrintingCJS(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + import { constant } from './constants' + import { imported } from 'somewhere' + import { undef } from './empty' + + _ = class Outer { + #bar; + + classes = [ + class { @imported @imported() imported }, + class { @unbound @unbound() unbound }, + class { @constant @constant() constant }, + class { @undef @undef() undef }, + + class { @(element[access]) indexed }, + class { @foo.#bar private }, + class { @foo.\u30FF unicode }, + class { @(() => {}) arrow }, + ] + } + `, + "/constants.js": ` + export const constant = 123 + `, + "/empty.js": ``, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + Mode: config.ModeBundle, + OutputFormat: config.FormatCommonJS, + AbsOutputFile: "/out.js", + ExternalPackages: true, + MinifySyntax: true, + }, + expectedCompileLog: `entry.js: WARNING: Import "undef" will always be undefined because the file "empty.js" has no exports +`, + }) +} diff --git a/internal/bundler_tests/snapshots/snapshots_default.txt b/internal/bundler_tests/snapshots/snapshots_default.txt index d76d075f800..fab5f422719 100644 --- a/internal/bundler_tests/snapshots/snapshots_default.txt +++ b/internal/bundler_tests/snapshots/snapshots_default.txt @@ -920,6 +920,102 @@ for (const d in x) for (const e of x) console.log(e); +================================================================================ +TestDecoratorPrintingCJS +---------- /out.js ---------- +// entry.js +var import_somewhere = require("somewhere"); +_ = class { + #bar; + classes = [ + class { + @(import_somewhere.imported) + @(0, import_somewhere.imported)() + imported; + }, + class { + @unbound + @unbound() + unbound; + }, + class { + @(123) + @123() + constant; + }, + class { + @(void 0) + @(void 0)() + undef; + }, + class { + @(element[access]) + indexed; + }, + class { + @foo.#bar + private; + }, + class { + @(foo["ヿ"]) + unicode; + }, + class { + @(() => { + }) + arrow; + } + ]; +}; + +================================================================================ +TestDecoratorPrintingESM +---------- /out.js ---------- +// entry.js +import { imported } from "somewhere"; +_ = class { + #bar; + classes = [ + class { + @(imported) + @imported() + imported; + }, + class { + @unbound + @unbound() + unbound; + }, + class { + @(123) + @123() + constant; + }, + class { + @(void 0) + @(void 0)() + undef; + }, + class { + @(element[access]) + indexed; + }, + class { + @foo.#bar + private; + }, + class { + @(foo["ヿ"]) + unicode; + }, + class { + @(() => { + }) + arrow; + } + ]; +}; + ================================================================================ TestDefineAssignWarning ---------- /out/read.js ---------- diff --git a/internal/js_parser/js_parser_test.go b/internal/js_parser/js_parser_test.go index 50833368c73..58b31a26652 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -2036,6 +2036,11 @@ func TestDecorators(t *testing.T) { expectParseError(t, "@new Function() class Foo {}", ": ERROR: Expected identifier but found \"new\"\n") expectParseError(t, "@() => {} class Foo {}", ": ERROR: Unexpected \")\"\n") + // See: https://github.com/microsoft/TypeScript/issues/55336 + expectParseError(t, "@x().y() class Foo {}", + ": ERROR: Expected \"class\" after decorator but found \".\"\n"+ + ": NOTE: The preceding decorator is here:\nNOTE: Decorators can only be used with class declarations.\n") + errorText := ": ERROR: Transforming JavaScript decorators to the configured target environment is not supported yet\n" expectParseErrorWithUnsupportedFeatures(t, compat.Decorators, "@dec class Foo {}", errorText) expectParseErrorWithUnsupportedFeatures(t, compat.Decorators, "class Foo { @dec x }", errorText)