From cd6366e47262f0f8f94fb06a179db6c6e2cd830f Mon Sep 17 00:00:00 2001 From: Matthew Beale Date: Fri, 24 Nov 2017 09:07:42 -0800 Subject: [PATCH] Add support to glimmer-wrapper for MU namespaces resolver.resolve now takes a third argument `rawString` which is the string used at the invocation site of the lookup. For example for: ``` {{ember-power-select::option}} ``` The lookup should be: ``` resolver.resolve('template:component/', null, 'ember-power-select::option') `` And for a service example: ``` Ember.service.inject('auth-addon::main-service') ``` The lookup would be: ``` resolver.resolve('service', null, 'auth-addon::main-service') ``` Refs: https://github.com/ember-cli/ember-resolver/issues/214 Refs: https://github.com/emberjs/ember.js/issues/15350#issuecomment-328118310 --- .../addon/resolvers/glimmer-wrapper/index.js | 35 +++++++++--- .../resolvers/glimmer-wrapper/basic-test.js | 53 +++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/mu-trees/addon/resolvers/glimmer-wrapper/index.js b/mu-trees/addon/resolvers/glimmer-wrapper/index.js index b68c62ff..06a9340b 100644 --- a/mu-trees/addon/resolvers/glimmer-wrapper/index.js +++ b/mu-trees/addon/resolvers/glimmer-wrapper/index.js @@ -30,7 +30,22 @@ const Resolver = DefaultResolver.extend({ normalize: null, - resolve(lookupString, referrer) { + resolve(lookupString, referrer, rawString) { + /* + * Ember namespaces are part of the raw invocation passed as a third + * argument, for example other-addon::some-service + */ + let rootName = this._configRootName; + let rawStringName = null; + if (rawString) { + let [namespace, name] = rawString.split('::'); + rootName = namespace; + rawStringName = name; + } + + let [type, lookupStringName] = lookupString.split(':'); + let name = lookupStringName; + /* * Ember components require their lookupString to be massaged. Make this * as "pay-go" as possible. @@ -38,11 +53,18 @@ const Resolver = DefaultResolver.extend({ if (referrer) { // make absolute let parts = referrer.split(':src/ui/'); - referrer = `${parts[0]}:/${this._configRootName}/${parts[1]}`; + referrer = `${parts[0]}:/${rootName}/${parts[1]}`; referrer = referrer.split('/template.hbs')[0]; + } else if (rawString) { + // This is only required because: + // https://github.com/glimmerjs/glimmer-di/issues/45 + referrer = `${type}:/${rootName}/`; } - let [type, name] = lookupString.split(':'); + /* If there is no name, fallback to the name passed in the rawString */ + if (!name) { + name = rawStringName; + } if (name) { if (type === 'service') { /* Services may be camelCased */ @@ -54,8 +76,9 @@ const Resolver = DefaultResolver.extend({ /* Controllers may have.dot.paths */ lookupString = `controller:${slasherize(name)}`; } else if (type === 'template') { - if (name.indexOf('components/') === 0) { - lookupString = `template:${name.slice(11)}`; + if (lookupStringName && lookupStringName.indexOf('components/') === 0) { + let sliced = lookupStringName.slice(11); + lookupString = `template:${sliced.length ? sliced : rawStringName}`; } else { /* * Ember partials are looked up as templates. Here we replace the template @@ -77,7 +100,7 @@ const Resolver = DefaultResolver.extend({ * have dots.in.paths */ lookupString = `template`; - referrer = `route:/${this._configRootName}/routes/${slasherize(name)}`; + referrer = `route:/${rootName}/routes/${slasherize(name)}`; } } } diff --git a/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js b/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js index 8f79ba88..b326fc33 100644 --- a/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js +++ b/mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js @@ -723,3 +723,56 @@ test('Can resolve a local helper for another component', function(assert) { 'helper not resolved at global levelt' ); }); + +// Namespaces + +test('Can resolve a namespaced service lookup', function(assert) { + let service = {}; + let resolver = this.resolverForEntries({ + app: { + name: 'example-app' + }, + types: { + service: { definitiveCollection: 'services' } + }, + collections: { + services: { + types: [ 'service' ] + } + } + }, { + 'service:/other-namespace/services/i18n': service + }); + + assert.equal( + resolver.resolve('service', null, 'other-namespace::i18n'), + service, + 'namespaced resolution resolved' + ); +}); + +test('Can resolve a namespaced component template', function(assert) { + let template = {}; + let resolver = this.resolverForEntries({ + app: { + name: 'example-app' + }, + types: { + template: { definitiveCollection: 'components' } + }, + collections: { + components: { + group: 'ui', + types: [ 'template' ] + } + } + }, { + 'template:/other-namespace/components/my-component': template + }); + + assert.equal( + resolver.resolve('template:components/', null, 'other-namespace::my-component'), + template, + 'namespaced resolution resolved' + ); +});