From 6b6519e397b3b01ad0add3fff82f711338f39213 Mon Sep 17 00:00:00 2001 From: Chad Hietala Date: Tue, 12 Jan 2021 16:01:27 -0500 Subject: [PATCH] bugfix: Ensure Component Lookup Is Well Formed This PR introduces an assertion during the component name refinement to assert that the lookup syntax is well formed. If a developer accidentally types ":" instead of "::" you will end up with a runtime erorr that looks like: ``` Uncaught Error: Assertion Failed: fullName must be a proper full name at assert (vendor.js:52729) at Container.lookup (vendor.js:16581) at Class.lookup (vendor.js:43950) at layoutFor (vendor.js:28680) at lookupComponentPair (vendor.js:28697) at lookupComponent (vendor.js:28711) at RuntimeResolver._lookupComponentDefinition (vendor.js:28992) at RuntimeResolver.lookupComponentHandle (vendor.js:28837) at CompileTimeLookup.lookupComponentDefinition (vendor.js:25065) at LazyCompiler.resolveLayoutForTag (vendor.js:60366) ``` This message is not actionable for developers. This PR will causes a compile time error to occur with the following information: ``` Malformed component lookup in "test.js". Got but you must use \"::\" to indicate a lookup ``` --- .../lib/system/compile-options.ts | 10 ++++++++++ .../tests/system/compile_options_test.js | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/ember-template-compiler/lib/system/compile-options.ts b/packages/ember-template-compiler/lib/system/compile-options.ts index 1e9e2129cfc..6a3d6cccfc4 100644 --- a/packages/ember-template-compiler/lib/system/compile-options.ts +++ b/packages/ember-template-compiler/lib/system/compile-options.ts @@ -1,4 +1,5 @@ import { EMBER_STRICT_MODE } from '@ember/canary-features'; +import { assert } from '@ember/debug'; import { assign } from '@ember/polyfills'; import { PrecompileOptions } from '@glimmer/compiler'; import { AST, ASTPlugin, ASTPluginEnvironment, Syntax } from '@glimmer/syntax'; @@ -8,6 +9,10 @@ import COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE from './dasherize-component-name'; let USER_PLUGINS: PluginFunc[] = []; +function malformedComponentLookup(string: string) { + return string.indexOf('::') === -1 && string.indexOf(':') > -1; +} + export default function compileOptions( _options: Partial = {} ): PrecompileOptions { @@ -16,6 +21,11 @@ export default function compileOptions( _options, { customizeComponentName(tagname: string): string { + assert( + `Malformed component lookup in "${_options.moduleName}". Got <${tagname} /> but you must use "::" to indicate a lookup`, + !malformedComponentLookup(tagname) + ); + return COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get(tagname); }, } diff --git a/packages/ember-template-compiler/tests/system/compile_options_test.js b/packages/ember-template-compiler/tests/system/compile_options_test.js index 1ee2968adf8..0da24eb1f76 100644 --- a/packages/ember-template-compiler/tests/system/compile_options_test.js +++ b/packages/ember-template-compiler/tests/system/compile_options_test.js @@ -15,6 +15,16 @@ moduleFor( assert.notEqual(compileOptions(), compileOptions()); } + ['@test customizeComponentName asserts name is well formed'](assert) { + const options = compileOptions({ moduleName: 'test.js' }); + + expectAssertion(() => { + options.customizeComponentName('Foo:Bar'); + }, /Malformed component lookup in "test.js". Got but you must use \"::\" to indicate a lookup/); + + assert.ok(options.customizeComponentName('Foo::Bar')); + } + ['@test has default AST plugins in resolution mode'](assert) { assert.expect(RESOLUTION_MODE_TRANSFORMS.length);