├── .editorconfig ├── .ember-cli ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .travis.yml ├── .watchmanconfig ├── LICENSE.md ├── README.md ├── addon ├── .gitkeep ├── components │ └── rel-link-to.js ├── initializers │ └── route-alias.js └── mixins │ ├── rel-link-to.js │ └── route-alias-resolver.js ├── app ├── .gitkeep ├── components │ └── rel-link-to.js ├── initializers │ └── route-alias.js └── mixins │ ├── rel-link-to.js │ └── route-alias-resolver.js ├── config ├── ember-try.js └── environment.js ├── ember-cli-build.js ├── index.js ├── package.json ├── testem.js ├── tests ├── dummy │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ └── .gitkeep │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ └── .gitkeep │ │ ├── resolver.js │ │ ├── router.js │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── styles │ │ │ └── app.css │ │ └── templates │ │ │ ├── application.hbs │ │ │ ├── components │ │ │ └── .gitkeep │ │ │ ├── index.hbs │ │ │ ├── one.hbs │ │ │ ├── one │ │ │ ├── a.hbs │ │ │ ├── a │ │ │ │ ├── i.hbs │ │ │ │ ├── i │ │ │ │ │ └── index.hbs │ │ │ │ ├── ii.hbs │ │ │ │ ├── iii.hbs │ │ │ │ └── index.hbs │ │ │ ├── alias-a.hbs │ │ │ ├── b.hbs │ │ │ ├── c.hbs │ │ │ └── index.hbs │ │ │ ├── three.hbs │ │ │ └── two.hbs │ ├── config │ │ ├── environment.js │ │ └── targets.js │ └── public │ │ └── robots.txt ├── helpers │ └── .gitkeep ├── index.html ├── test-helper.js └── unit │ ├── .gitkeep │ ├── initializers │ └── route-alias-test.js │ └── mixins │ ├── rel-link-to-test.js │ └── route-alias-resolver-test.js └── vendor └── .gitkeep /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 2017, 5 | sourceType: 'module' 6 | }, 7 | plugins: [ 8 | 'ember' 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:ember/recommended' 13 | ], 14 | env: { 15 | browser: true 16 | }, 17 | rules: { 18 | }, 19 | overrides: [ 20 | { 21 | files: [ 22 | 'addon/**', 23 | 'tests/**' 24 | ], 25 | rules: { 26 | 'ember/new-module-imports': 'off' 27 | } 28 | }, 29 | // node files 30 | { 31 | files: [ 32 | 'ember-cli-build.js', 33 | 'index.js', 34 | 'testem.js', 35 | 'config/**/*.js', 36 | 'tests/dummy/config/**/*.js' 37 | ], 38 | excludedFiles: [ 39 | 'addon/**', 40 | 'addon-test-support/**', 41 | 'app/**', 42 | 'tests/dummy/app/**' 43 | ], 44 | parserOptions: { 45 | sourceType: 'script', 46 | ecmaVersion: 2015 47 | }, 48 | env: { 49 | browser: false, 50 | node: true 51 | }, 52 | plugins: ['node'], 53 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 54 | // add your custom rules and overrides for node files here 55 | }) 56 | } 57 | ] 58 | }; 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log* 17 | yarn-error.log 18 | testem.log 19 | 20 | # ember-try 21 | .node_modules.ember-try/ 22 | bower.json.ember-try 23 | package.json.ember-try 24 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /bower_components 2 | /config/ember-try.js 3 | /dist 4 | /tests 5 | /tmp 6 | **/.gitkeep 7 | .bowerrc 8 | .editorconfig 9 | .ember-cli 10 | .eslintrc.js 11 | .gitignore 12 | .watchmanconfig 13 | .travis.yml 14 | bower.json 15 | ember-cli-build.js 16 | testem.js 17 | 18 | # ember-try 19 | .node_modules.ember-try/ 20 | bower.json.ember-try 21 | package.json.ember-try 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | # we recommend testing addons with the same minimum supported node version as Ember CLI 5 | # so that your addon works for all apps 6 | - "4" 7 | 8 | sudo: false 9 | dist: trusty 10 | 11 | addons: 12 | chrome: stable 13 | 14 | cache: 15 | directories: 16 | - $HOME/.npm 17 | 18 | env: 19 | # we recommend testing LTS's and latest stable release (bonus points to beta/canary) 20 | - EMBER_TRY_SCENARIO=ember-lts-2.12 21 | - EMBER_TRY_SCENARIO=ember-lts-2.16 22 | - EMBER_TRY_SCENARIO=ember-lts-2.18 23 | - EMBER_TRY_SCENARIO=ember-release 24 | - EMBER_TRY_SCENARIO=ember-beta 25 | - EMBER_TRY_SCENARIO=ember-canary 26 | 27 | matrix: 28 | fast_finish: true 29 | allow_failures: 30 | - env: EMBER_TRY_SCENARIO=ember-canary 31 | 32 | before_install: 33 | - npm config set spin false 34 | - npm install -g npm@4 35 | - npm --version 36 | 37 | script: 38 | - npm run lint:js 39 | # Usually, it's ok to finish the test scenario without reverting 40 | # to the addon's original dependency state, skipping "cleanup". 41 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO --skip-cleanup 42 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Nathan Hammond 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-route-alias 2 | 3 | [![Build Status](https://travis-ci.org/nathanhammond/ember-route-alias.svg)](https://travis-ci.org/nathanhammond/ember-route-alias) 4 | [![npm version](https://badge.fury.io/js/ember-route-alias.svg)](http://badge.fury.io/js/ember-route-alias) 5 | [![Ember Observer Score](http://emberobserver.com/badges/ember-route-alias.svg)](http://emberobserver.com/addons/ember-route-alias) 6 | [![Code Climate](https://codeclimate.com/github/nathanhammond/ember-route-alias/badges/gpa.svg)](https://codeclimate.com/github/nathanhammond/ember-route-alias) 7 | 8 | This Ember addon makes it easy to create multiple paths to the same route. By default it uses the same set of assets as the original route, but individual assets for each route can be overidden. 9 | 10 | It also includes a simple `{{#rel-link-to}}` helper to make template reuse easier. 11 | 12 | **Warning:** This addon monkey-patches the private `Ember.RouterDSL#route` method. As a result this addon can easily be broken by changes in Ember core. It is, however, used by a major product in the Ember ecosystem and will be kept up-to-date as best as possible. 13 | 14 | ## Usage 15 | 16 | `ember install ember-route-alias` 17 | 18 | In `app.js`: 19 | ```javascript 20 | import RouteAliasResolver from 'ember-route-alias/mixins/route-alias-resolver'; 21 | 22 | App = Ember.Application.extend({ 23 | /* ... */ 24 | Resolver: Resolver.extend(RouteAliasResolver) 25 | }); 26 | ``` 27 | 28 | In `router.js`: 29 | ```javascript 30 | Router.map(function() { 31 | this.route('one', function() { 32 | this.route('a', function () { 33 | this.route('i', function() {}); 34 | this.route('ii'); 35 | this.route('iii'); 36 | 37 | this.alias('alias-i', '/alias-i', 'i'); 38 | }); 39 | this.route('b'); 40 | this.route('c'); 41 | 42 | this.alias('alias-a', '/alias-a', 'a'); 43 | }); 44 | this.route('two'); 45 | this.route('three'); 46 | 47 | this.alias('alias-one', '/alias-one', 'one'); 48 | this.alias('not-one', '/not-one', 'alias-one'); 49 | }); 50 | ``` 51 | 52 | Electively you may add assets for any of the aliased routes by their name and it will load those assets instead. (The custom resolver is placed last in the queue.) For example, in `templates/alias-one.hbs`: 53 | 54 | ```handlebars 55 | This template will be loaded instead of
templates/one.hbs
. 56 | 57 | {{outlet}} 58 | ``` 59 | 60 | ## Running the sample application 61 | 62 | The included sample application contains complete usage examples. 63 | 64 | * `ember server` 65 | * Visit your app at [http://localhost:4200](http://localhost:4200). 66 | * Also available via GitHub Pages [http://nathanhammond.github.io/ember-route-alias/](http://nathanhammond.github.io/ember-route-alias/) 67 | 68 | ### Running tests 69 | 70 | * `npm run test` 71 | 72 | ## Pushing an updated sample app 73 | 74 | ```sh 75 | ember github-pages:commit --message "Update demo app." 76 | git push origin gh-pages:gh-pages 77 | ``` 78 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/addon/.gitkeep -------------------------------------------------------------------------------- /addon/components/rel-link-to.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import RelLinkToMixin from '../mixins/rel-link-to'; 3 | 4 | export default Ember.LinkComponent.extend(RelLinkToMixin); 5 | -------------------------------------------------------------------------------- /addon/initializers/route-alias.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | /* 4 | Reopen `Ember.Route` to attach a new property to the controller to make it 5 | available in all route templates. We only need to do this once as it is a global 6 | change that is not instance specific. 7 | */ 8 | Ember.Route.reopen({ 9 | setupController(controller) { 10 | this._super.apply(this, arguments); 11 | controller.set('contextRoute', this.routeName); 12 | } 13 | }); 14 | 15 | // Sets up our magic alias function. 16 | function createAlias() { 17 | Ember.RouterDSL.prototype.alias = function(aliasRoute, aliasPath, aliasTarget) { 18 | Ember.assert('You must create a route prior to creating an alias.', this.handlers || this.intercepting); 19 | Ember.assert('The alias target must exist before attempting to alias it.', this.handlers[aliasTarget]); 20 | 21 | // Grab a reference to the arguments passed in for the original route. 22 | let [options, callback] = this.handlers[aliasTarget]; 23 | options.path = aliasPath; 24 | 25 | this.intercepting.push({ aliasRoute, aliasTarget }); 26 | 27 | this.route(aliasRoute, options, callback); 28 | }; 29 | } 30 | 31 | // Patches the RouterDSL route function to work with aliases. 32 | function patchRoute(lookup) { 33 | // Save off the original method in scope of the prototype modifications. 34 | let originalRouteMethod = Ember.RouterDSL.prototype.route; 35 | 36 | // We need to do a few things before and after the original route function. 37 | Ember.RouterDSL.prototype.route = function(name, options, callback) { 38 | Ember.assert('You may not include a "." in your route name.', !~name.indexOf('.')); 39 | 40 | // Method signature identification from the original method. 41 | if (arguments.length === 2 && typeof options === 'function') { 42 | callback = options; 43 | options = {}; 44 | } 45 | 46 | if (arguments.length === 1) { 47 | options = {}; 48 | } 49 | 50 | // Save off a reference to the original arguments in a reachable scope. 51 | // This is so later calls to `alias` have something to find. 52 | if (!this.handlers) { this.handlers = {}; } 53 | this.handlers[name] = [ options, callback ]; 54 | 55 | // For storing the root of the aliased route. 56 | if (!this.intercepting) { this.intercepting = []; } 57 | 58 | // So, we're "recursing" through a structure, but we can sneak in by wrapping the invoked function. 59 | if (this.intercepting.length) { 60 | 61 | // Make the callback modify the DSL generated for nested routes. 62 | // Necessary so they can register themselves. 63 | // Propogate the original interception information forward. 64 | var currentIntercepting = this.intercepting[this.intercepting.length - 1]; 65 | let interceptingCallback = function() { 66 | this.intercepting = [currentIntercepting]; 67 | callback.call(this); 68 | }; 69 | 70 | // Figure out how many routes we created. 71 | let originalLength = [].concat.apply([], this.matches).length; 72 | originalRouteMethod.call(this, name, options, callback ? interceptingCallback : undefined); 73 | let newMatches = [].concat.apply([], this.matches); 74 | let newLength = newMatches.length; 75 | 76 | // Add each of them to the lookup. 77 | for (let i = originalLength; i < newLength; i += 3) { 78 | let intermediate = newMatches[i + 1].split('.'); 79 | let qualifiedAliasRoute = intermediate.join('/'); 80 | let qualifiedTargetRoute = qualifiedAliasRoute.replace(currentIntercepting.aliasRoute, currentIntercepting.aliasTarget); 81 | 82 | if (qualifiedAliasRoute !== qualifiedTargetRoute) { 83 | lookup[qualifiedAliasRoute] = qualifiedTargetRoute; 84 | } else { 85 | // For index routes we need to try again with the base intercepting object. 86 | let isIndex = intermediate.pop().indexOf('index') === 0; 87 | qualifiedTargetRoute = qualifiedAliasRoute.replace(this.intercepting[0].aliasRoute, this.intercepting[0].aliasTarget); 88 | if (isIndex && qualifiedAliasRoute !== qualifiedTargetRoute) { 89 | lookup[qualifiedAliasRoute] = qualifiedTargetRoute; 90 | } 91 | } 92 | } 93 | 94 | } else { 95 | originalRouteMethod.call(this, name, options, callback); 96 | } 97 | }; 98 | } 99 | 100 | // Routing only happens once. 101 | const lookup = {}; 102 | 103 | // Only patch things once for testing. 104 | let hasRun = false; 105 | export function initialize() { 106 | if (!hasRun) { 107 | hasRun = true; 108 | createAlias(); 109 | patchRoute(lookup); 110 | } 111 | 112 | // Feed the lookup into the application. 113 | let application = arguments[1] || arguments[0]; 114 | application._routeAliasLookup = lookup; 115 | } 116 | 117 | export default { 118 | name: 'route-alias', 119 | initialize: initialize 120 | }; 121 | -------------------------------------------------------------------------------- /addon/mixins/rel-link-to.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | const { computed, get } = Ember; 3 | 4 | export default Ember.Mixin.create({ 5 | /** 6 | This is a simplistic traversal function. It does not function 7 | identically to pathing in a file system. It does use the same nomenclature. 8 | 9 | Be careful and watch for things like generated index routes–the behavior 10 | will seem wrong but be functioning correctly. 11 | 12 | Examples: 13 | ``` 14 | (base = 'foo.bar', targetRouteName = '') => 'foo.bar' 15 | (base = 'foo.bar', targetRouteName = './') => 'foo.bar' 16 | (base = 'foo.bar', targetRouteName = '../') => 'foo' 17 | (base = 'foo.bar', targetRouteName = '../baz') => 'foo.baz' 18 | (base = 'foo', targetRouteName = 'baz') => 'foo.baz' 19 | 20 | ``` 21 | */ 22 | _process(base, targetRouteName) { 23 | let nextBase, nextTarget, result; 24 | 25 | if (targetRouteName === '' || targetRouteName === './') { 26 | // Support non-traversing paths. 27 | return base; 28 | } else if (targetRouteName.indexOf('../') === 0) { 29 | nextTarget = targetRouteName.substring(3); 30 | nextBase = base.split('.'); 31 | nextBase.pop(); 32 | nextBase = nextBase.join('.'); 33 | return this._process(nextBase, nextTarget); 34 | } else { 35 | result = []; 36 | if (base !== '') { result.push(base); } 37 | if (targetRouteName !== '') { result.push(targetRouteName); } 38 | return result.join('.'); 39 | } 40 | }, 41 | 42 | /** 43 | Modified from the original to remove the HAS_BLOCK check, recompute on `base` 44 | attr changes, and process the provided arguments into a relative link. 45 | */ 46 | qualifiedRouteName: computed('base', 'targetRouteName', '_routing.currentState', function computeRelLinkToComponentQualifiedRouteName() { 47 | let params = get(this, 'params').slice(); 48 | let lastParam = params[params.length - 1]; 49 | if (lastParam && lastParam.isQueryParams) { 50 | params.pop(); 51 | } 52 | let onlyQueryParamsSupplied = (params.length === 0); 53 | if (onlyQueryParamsSupplied) { 54 | return get(this, '_routing.currentRouteName'); 55 | } 56 | return this._process(get(this, 'base'), get(this, 'targetRouteName')); 57 | }) 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /addon/mixins/route-alias-resolver.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Mixin.create({ 4 | 5 | /** 6 | Push the new module name lookup pattern on to the list of previous lookup 7 | patterns. 8 | */ 9 | moduleNameLookupPatterns: Ember.computed(function() { 10 | var result = this._super.call(this); 11 | result.push(this.aliasedModuleName); 12 | return result; 13 | }), 14 | 15 | /** 16 | Check to see if the targeted module has an alias in the lookup. If this lookup 17 | function is invoked we've already missed finding a direct hit for this module, 18 | making this safe. 19 | */ 20 | aliasedModuleName(parsedName) { 21 | // Short circuit if you're not aliased or a type we care about for aliasing. 22 | if (!this.namespace || !this.namespace._routeAliasLookup) { return false; } 23 | if (!~['controller','route','template','view'].indexOf(parsedName.type)) { return false; } 24 | 25 | // See if the key we have is in the lookup. 26 | // If it is, traverse through the lookup "recursively" until we hit a leaf node. 27 | let alias; 28 | let key = parsedName.fullNameWithoutType; 29 | while (this.namespace._routeAliasLookup[key]) { 30 | alias = this.namespace._routeAliasLookup[key]; 31 | key = alias; 32 | } 33 | 34 | // If we found something in the lookup, return it. Otherwise, proceed to the next resolver. 35 | if (alias) { 36 | return parsedName.prefix + '/' + this.pluralize(parsedName.type) + '/' + alias; 37 | } else { 38 | return false; 39 | } 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/app/.gitkeep -------------------------------------------------------------------------------- /app/components/rel-link-to.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-route-alias/components/rel-link-to'; -------------------------------------------------------------------------------- /app/initializers/route-alias.js: -------------------------------------------------------------------------------- 1 | export { default, initialize } from 'ember-route-alias/initializers/route-alias'; 2 | -------------------------------------------------------------------------------- /app/mixins/rel-link-to.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-route-alias/mixins/rel-link-to'; 2 | -------------------------------------------------------------------------------- /app/mixins/route-alias-resolver.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-route-alias/mixins/route-alias-resolver'; 2 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary'), 10 | ]).then((urls) => { 11 | return { 12 | scenarios: [ 13 | { 14 | name: 'ember-lts-2.12', 15 | npm: { 16 | devDependencies: { 17 | 'ember-source': '~2.12.0' 18 | } 19 | } 20 | }, 21 | { 22 | name: 'ember-lts-2.16', 23 | npm: { 24 | devDependencies: { 25 | 'ember-source': '~2.16.0' 26 | } 27 | } 28 | }, 29 | { 30 | name: 'ember-lts-2.18', 31 | npm: { 32 | devDependencies: { 33 | 'ember-source': '~2.18.0' 34 | } 35 | } 36 | }, 37 | { 38 | name: 'ember-release', 39 | npm: { 40 | devDependencies: { 41 | 'ember-source': urls[0] 42 | } 43 | } 44 | }, 45 | { 46 | name: 'ember-beta', 47 | npm: { 48 | devDependencies: { 49 | 'ember-source': urls[1] 50 | } 51 | } 52 | }, 53 | { 54 | name: 'ember-canary', 55 | npm: { 56 | devDependencies: { 57 | 'ember-source': urls[2] 58 | } 59 | } 60 | }, 61 | { 62 | name: 'ember-default', 63 | npm: { 64 | devDependencies: {} 65 | } 66 | } 67 | ] 68 | }; 69 | }); 70 | }; 71 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | module.exports = function(defaults) { 6 | let app = new EmberAddon(defaults, { 7 | // Add options here 8 | }); 9 | 10 | /* 11 | This build file specifies the options for the dummy test app of this 12 | addon, located in `/tests/dummy` 13 | This build file does *not* influence how the addon or the app using it 14 | behave. You most likely want to be modifying `./index.js` or app's build file 15 | */ 16 | 17 | return app.toTree(); 18 | }; 19 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: 'ember-route-alias' 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-route-alias", 3 | "version": "0.1.7", 4 | "description": "Ember addon to create multiple paths for the same route.", 5 | "keywords": [ 6 | "ember-addon", 7 | "ember-route-alias", 8 | "ember", 9 | "route", 10 | "alias", 11 | "relative", 12 | "link" 13 | ], 14 | "license": "MIT", 15 | "author": "Nathan Hammond", 16 | "directories": { 17 | "doc": "doc", 18 | "test": "tests" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/nathanhammond/ember-route-alias.git" 23 | }, 24 | "scripts": { 25 | "build": "ember build", 26 | "lint:js": "eslint ./*.js addon addon-test-support app config lib server test-support tests", 27 | "start": "ember serve", 28 | "test": "ember test", 29 | "test:all": "ember try:each" 30 | }, 31 | "dependencies": { 32 | "ember-cli-babel": "^6.6.0" 33 | }, 34 | "devDependencies": { 35 | "broccoli-asset-rev": "^2.4.5", 36 | "ember-cli": "~3.1.1", 37 | "ember-cli-dependency-checker": "^2.0.0", 38 | "ember-cli-eslint": "^4.2.1", 39 | "ember-cli-github-pages": "0.1.2", 40 | "ember-cli-htmlbars": "^2.0.1", 41 | "ember-cli-htmlbars-inline-precompile": "^1.0.0", 42 | "ember-cli-inject-live-reload": "^1.4.1", 43 | "ember-cli-qunit": "^4.1.1", 44 | "ember-cli-shims": "^1.2.0", 45 | "ember-cli-sri": "^2.1.0", 46 | "ember-cli-uglify": "^2.0.0", 47 | "ember-disable-prototype-extensions": "^1.1.2", 48 | "ember-export-application-global": "^2.0.0", 49 | "ember-load-initializers": "^1.0.0", 50 | "ember-maybe-import-regenerator": "^0.1.6", 51 | "ember-resolver": "^4.0.0", 52 | "ember-source": "~3.1.0", 53 | "ember-source-channel-url": "^1.0.1", 54 | "ember-try": "^0.2.23", 55 | "eslint-plugin-ember": "^5.0.0", 56 | "eslint-plugin-node": "^6.0.1", 57 | "loader.js": "^4.2.3" 58 | }, 59 | "engines": { 60 | "node": "^4.5 || 6.* || >= 7.*" 61 | }, 62 | "ember-addon": { 63 | "configPath": "tests/dummy/config", 64 | "demoURL": "http://nathanhammond.github.io/ember-route-alias" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | mode: 'ci', 13 | args: [ 14 | // --no-sandbox is needed when running Chrome inside a container 15 | process.env.TRAVIS ? '--no-sandbox' : null, 16 | 17 | '--disable-gpu', 18 | '--headless', 19 | '--remote-debugging-port=0', 20 | '--window-size=1440,900' 21 | ].filter(Boolean) 22 | } 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | import RouteAliasResolver from 'ember-route-alias/mixins/route-alias-resolver'; 6 | 7 | const App = Application.extend({ 8 | modulePrefix: config.modulePrefix, 9 | podModulePrefix: config.podModulePrefix, 10 | Resolver: Resolver.extend(RouteAliasResolver) 11 | }); 12 | 13 | loadInitializers(App, config.modulePrefix); 14 | 15 | export default App; 16 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.routerRootURL 7 | }); 8 | 9 | Router.map(function() { 10 | this.route('one', function() { 11 | this.route('a', function () { 12 | this.route('i', function() {}); 13 | this.route('ii'); 14 | this.route('iii'); 15 | 16 | this.alias('alias-i', '/alias-i', 'i'); 17 | }); 18 | this.route('b'); 19 | this.route('c'); 20 | 21 | this.alias('alias-a', '/alias-a', 'a'); 22 | }); 23 | this.route('two'); 24 | this.route('three'); 25 | 26 | this.alias('alias-one', '/alias-one', 'one'); 27 | this.alias('not-one', '/not-one', 'alias-one'); 28 | }); 29 | 30 | export default Router; 31 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | h1 { margin: .5em 0; } 2 | dt, dd { display: inline; margin: 0; } 3 | dt { font-weight: bold; } 4 | dt::after { content: ':';} 5 | 6 | div.ember-view > div { margin-left: 0; } 7 | div.ember-view > dl::before { content:''; } 8 | div.ember-view > ul { margin: 0 0 1em; display: inline-block; } 9 | div.ember-view > ul + ul { border-left: 1px solid black; margin-left: 1em; padding-left: 2em; } 10 | div.ember-view > ul ul { margin-left: 0; } 11 | 12 | dl ~ div { margin-left: 1em; } 13 | div dl::before { content:'└'; } 14 | 15 | ul { padding-left: 1em; } 16 | 17 | div > ul { margin-left: 1.5em; } 18 | 19 | .active { color: red; } 20 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

Ember Route Alias

2 | 3 | 28 | 29 | 54 | 55 | 80 | 81 | 106 | 107 | 132 | 133 |
134 | 135 |
136 |
originalRoute
137 |
application
138 |
contextRoute
139 |
{{contextRoute}}
140 |
141 | 142 |
{{outlet}}
143 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/templates/index.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
index
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 | 20 | 21 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/a.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.a
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/a/i.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.a.i
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/a/i/index.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.a.i
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/a/ii.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.a.ii
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/a/iii.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.a.iii
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/a/index.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.a.index
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/alias-a.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.alias-a
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/b.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.b
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/c.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.c
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/one/index.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
one.index
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/three.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
three
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/app/templates/two.hbs: -------------------------------------------------------------------------------- 1 |
2 |
originalRoute
3 |
two
4 |
contextRoute
5 |
{{contextRoute}}
6 |
7 | 8 |
{{outlet}}
-------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | routerRootURL: '/', 9 | 10 | locationType: 'auto', 11 | EmberENV: { 12 | FEATURES: { 13 | // Here you can enable experimental features on an ember canary build 14 | // e.g. 'with-controller': true 15 | } 16 | }, 17 | 18 | APP: { 19 | // Here you can pass flags/options to your application instance 20 | // when it is created 21 | } 22 | }; 23 | 24 | if (environment === 'development') { 25 | // ENV.APP.LOG_RESOLVER = true; 26 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 27 | // ENV.APP.LOG_TRANSITIONS = true; 28 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 29 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 30 | } 31 | 32 | if (environment === 'test') { 33 | // Testem prefers this... 34 | ENV.locationType = 'none'; 35 | 36 | // keep test console output quieter 37 | ENV.APP.LOG_ACTIVE_GENERATION = false; 38 | ENV.APP.LOG_VIEW_LOOKUPS = false; 39 | 40 | ENV.APP.rootElement = '#ember-testing'; 41 | ENV.APP.autoboot = false; 42 | } 43 | 44 | if (environment === 'production') { 45 | ENV.locationType = 'hash'; 46 | ENV.rootURL = '/ember-route-alias'; 47 | ENV.routerRootURL = '/ember-route-alias'; 48 | } 49 | 50 | return ENV; 51 | }; 52 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ]; 8 | 9 | const isCI = !!process.env.CI; 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/initializers/route-alias-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import RouteAliasInitializer from '../../../initializers/route-alias'; 3 | import { module, test } from 'qunit'; 4 | 5 | var application, DSL; 6 | var originals = { 7 | route: Ember.RouterDSL.prototype.route 8 | }; 9 | 10 | module('Unit | Initializer | route alias', { 11 | beforeEach: function() { 12 | Ember.run(function() { 13 | application = Ember.Application.create(); 14 | application.deferReadiness(); 15 | RouteAliasInitializer.initialize(application); 16 | DSL = new Ember.RouterDSL('application', {}); 17 | }); 18 | } 19 | }); 20 | 21 | test('Initializer properly modifies/hooks all objects.', function(assert) { 22 | var replacements = { 23 | route: Ember.RouterDSL.prototype.route 24 | }; 25 | 26 | assert.ok(application._routeAliasLookup, 'Ensure that the dictionary we use is present.'); 27 | assert.notEqual(originals.route, replacements.route, 'RouterDSL#route has been replaced.'); 28 | assert.ok(Ember.RouterDSL.prototype.route, 'RouterDSL#alias exists.'); 29 | }); 30 | 31 | test('Route#setupController sets the contextRoute on the controller', function(assert) { 32 | var route = Ember.Route.create({ routeName: 'testy-mctesterton' }); 33 | var controller = Ember.Controller.create({ }); 34 | 35 | assert.notOk(controller.get('contextRoute'), 'contextRoute is empty to start'); 36 | 37 | route.setupController(controller); 38 | 39 | assert.equal(controller.get('contextRoute'), 'testy-mctesterton', 'contextRoute is set after setup'); 40 | }); 41 | 42 | test('RouterDSL assertions work.', function(assert) { 43 | assert.throws( 44 | function() { DSL.alias('asdf', '/asdf', 'target'); }, 45 | /You must create a route prior to creating an alias\./, 46 | 'Throws an error when you create an alias prior to generating any routes.' 47 | ); 48 | 49 | assert.throws( 50 | function() { DSL.route('period.separated'); }, 51 | /You may not include a "\." in your route name\./, 52 | 'Throws an error when you attempt to create a route with a period in it.' 53 | ); 54 | 55 | DSL.route('index', { path: '/' }); 56 | 57 | assert.throws( 58 | function() { DSL.alias('asdf', '/asdf', 'elsewhere'); }, 59 | /The alias target must exist before attempting to alias it\./, 60 | 'Throws an error when you target an alias at a non-existent route.' 61 | ); 62 | }); 63 | 64 | test('RouterDSL#route saving of scope works as expected.', function(assert) { 65 | var stub = function() {}; 66 | 67 | DSL.route('index', { path: '/' }, stub); 68 | assert.ok(DSL.handlers.index, 'Sets up a lookup for the original arguments passed in for each route.'); 69 | assert.equal(stub, DSL.handlers.index[1], 'The saved callback is the original reference.'); 70 | }); 71 | 72 | test('RouterDSL#alias creates the lookup.', function(assert) { 73 | assert.notOk(DSL.intercepting, 'Not set as intercepting prior to an alias call.'); 74 | 75 | DSL.route('index', { path: '/' }); 76 | 77 | assert.equal(DSL.intercepting.length, 0, 'Not set as intercepting prior to an alias call.'); 78 | 79 | DSL.alias('asdf', '/asdf', 'index'); 80 | 81 | assert.equal(DSL.intercepting.length, 1, 'Sets up intercepting to identify state.'); 82 | assert.equal(application._routeAliasLookup['asdf'], 'index', 'Lookup entry is created for the alias route.'); 83 | 84 | DSL.route('one', function() { 85 | this.route('a'); 86 | this.alias('alias-a', '/alias-a', 'a'); 87 | }); 88 | DSL.alias('alias-one', '/alias-one', 'one'); 89 | 90 | assert.equal(application._routeAliasLookup['alias-one'], 'one', 'Lookup entry is created for the alias route with nesting.'); 91 | assert.equal(application._routeAliasLookup['alias-one/index'], 'one/index', 'Lookup entry is created for the alias route with nesting.'); 92 | assert.equal(application._routeAliasLookup['alias-one/a'], 'one/a', 'Lookup entry is created for the alias route with nesting.'); 93 | assert.equal(application._routeAliasLookup['alias-one/alias-a'], 'alias-one/a', 'Lookup entry is created for the alias route with nesting.'); 94 | assert.equal(application._routeAliasLookup['one/alias-a'], 'one/a', 'Lookup entry is created for the alias route with nesting.'); 95 | 96 | DSL.alias('not-one', '/not-one', 'alias-one'); 97 | 98 | assert.equal(application._routeAliasLookup['not-one'], 'alias-one', 'Can alias an alias.'); 99 | assert.equal(application._routeAliasLookup['not-one/index'], 'alias-one/index', 'Can alias an alias.'); 100 | assert.equal(application._routeAliasLookup['not-one/a'], 'alias-one/a', 'Can alias an alias.'); 101 | assert.equal(application._routeAliasLookup['not-one/alias-a'], 'not-one/a', 'Can alias an alias.'); 102 | }); 103 | -------------------------------------------------------------------------------- /tests/unit/mixins/rel-link-to-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import RelLinkToMixin from '../../../mixins/rel-link-to'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | rel link to'); 6 | 7 | test('Check _process lookups.', function(assert) { 8 | let RelLinkToObject = Ember.Object.extend(RelLinkToMixin); 9 | let subject = RelLinkToObject.create(); 10 | 11 | assert.equal(subject._process('foo.bar', ''), 'foo.bar', 'Empty string lookup.'); 12 | assert.equal(subject._process('foo.bar', './'), 'foo.bar', './ lookup.'); 13 | assert.equal(subject._process('foo.bar', '../'), 'foo', '../ lookup.'); 14 | assert.equal(subject._process('foo.bar', '../baz'), 'foo.baz', 'Sibling lookup.'); 15 | assert.equal(subject._process('foo', 'baz'), 'foo.baz', 'Child lookup.'); 16 | }); 17 | -------------------------------------------------------------------------------- /tests/unit/mixins/route-alias-resolver-test.js: -------------------------------------------------------------------------------- 1 | // import Ember from 'ember'; 2 | import Resolver from 'ember-resolver'; 3 | import RouteAliasResolver from '../../../mixins/route-alias-resolver'; 4 | import { module, test } from 'qunit'; 5 | 6 | module('Unit | Mixin | route alias resolver'); 7 | 8 | test('Adds a module name lookup pattern.', function(assert) { 9 | let base = Resolver.create(); 10 | let baseLength = base.get('moduleNameLookupPatterns').length; 11 | 12 | let subject = Resolver.extend(RouteAliasResolver).create(); 13 | let subjectLength = subject.get('moduleNameLookupPatterns').length; 14 | 15 | assert.equal(baseLength + 1, subjectLength, 'Successfully added a module name lookup pattern.'); 16 | }); 17 | 18 | test('The module name lookup works.', function(assert) { 19 | let result; 20 | let subject = Resolver.extend(RouteAliasResolver).create(); 21 | 22 | assert.equal(subject.aliasedModuleName(), false, 'Returns falsy with no namespace.'); 23 | 24 | subject.namespace = {}; 25 | 26 | assert.equal(subject.aliasedModuleName(), false, 'Returns falsy with no lookup.'); 27 | 28 | subject.namespace._routeAliasLookup = { 29 | 'alias-one': 'one', 30 | 'alias-one/a': 'one/a', 31 | 'alias-one/alias-a': 'alias-one/a', 32 | 'not-one': 'alias-one', 33 | }; 34 | 35 | result = subject.aliasedModuleName({ 36 | prefix: 'ember-route-alias', 37 | type: 'something-else', 38 | fullNameWithoutType: 'something-else' 39 | }); 40 | 41 | assert.equal(result, false, 'Returns falsy when the lookup is for the wrong type.'); 42 | 43 | result = subject.aliasedModuleName({ 44 | prefix: 'ember-route-alias', 45 | type: 'template', 46 | fullNameWithoutType: 'something-else' 47 | }); 48 | 49 | assert.equal(result, false, 'Returns falsy when not found in the lookup.'); 50 | 51 | result = subject.aliasedModuleName({ 52 | prefix: 'ember-route-alias', 53 | type: 'template', 54 | fullNameWithoutType: 'alias-one' 55 | }); 56 | 57 | assert.equal(result, 'ember-route-alias/templates/one', 'Succeeds at simple lookups.'); 58 | 59 | result = subject.aliasedModuleName({ 60 | prefix: 'ember-route-alias', 61 | type: 'template', 62 | fullNameWithoutType: 'not-one' 63 | }); 64 | 65 | assert.equal(result, 'ember-route-alias/templates/one', 'Succeeds at "recursive" lookups, alias to alias.'); 66 | 67 | result = subject.aliasedModuleName({ 68 | prefix: 'ember-route-alias', 69 | type: 'template', 70 | fullNameWithoutType: 'alias-one/alias-a' 71 | }); 72 | 73 | assert.equal(result, 'ember-route-alias/templates/one/a', 'Succeeds at "recursive" lookups.'); 74 | 75 | }); 76 | 77 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathanhammond/ember-route-alias/e1f39cd775662b6e5dbae1654b8584902f8f44e2/vendor/.gitkeep --------------------------------------------------------------------------------