├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .eslintrc.js ├── .gitignore ├── .jscsrc ├── .npmignore ├── .prettierrc ├── .travis.yml ├── .vscode └── settings.json ├── .watchmanconfig ├── LICENSE.md ├── README.md ├── addon ├── .gitkeep └── index.js ├── app └── .gitkeep ├── bower.json ├── config ├── ember-try.js └── environment.js ├── ember-cli-build.js ├── ember-data-preload.sublime-project ├── index.js ├── package.json ├── renovate.json ├── testem.js ├── tests ├── .eslintrc.js ├── acceptance │ └── index-test.js ├── dummy │ ├── app │ │ ├── adapters │ │ │ └── application.js │ │ ├── app.js │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ └── .gitkeep │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ ├── .gitkeep │ │ │ ├── city.js │ │ │ ├── country.js │ │ │ ├── house.js │ │ │ ├── neighborhood.js │ │ │ ├── park.js │ │ │ └── street.js │ │ ├── resolver.js │ │ ├── router.js │ │ ├── routes │ │ │ ├── .gitkeep │ │ │ └── application.js │ │ ├── styles │ │ │ └── app.css │ │ └── templates │ │ │ ├── application.hbs │ │ │ └── components │ │ │ └── .gitkeep │ ├── config │ │ ├── environment.js │ │ └── targets.js │ └── public │ │ ├── crossdomain.xml │ │ └── robots.txt ├── helpers │ ├── destroy-app.js │ ├── module-for-acceptance.js │ ├── resolver.js │ └── start-app.js ├── index.html ├── integration │ └── .gitkeep ├── test-helper.js └── unit │ └── .gitkeep ├── vendor └── .gitkeep └── yarn.lock /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /.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 | // node files 21 | { 22 | files: [ 23 | 'index.js', 24 | 'testem.js', 25 | 'ember-cli-build.js', 26 | 'config/**/*.js', 27 | 'tests/dummy/config/**/*.js' 28 | ], 29 | excludedFiles: [ 30 | 'app/**', 31 | 'addon/**' 32 | ], 33 | parserOptions: { 34 | sourceType: 'script', 35 | ecmaVersion: 2015 36 | }, 37 | env: { 38 | browser: false, 39 | node: true 40 | }, 41 | plugins: ['node'], 42 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 43 | // add your custom rules and overrides for node files here 44 | }) 45 | }, 46 | 47 | // test files 48 | { 49 | files: ['tests/**/*.js'], 50 | excludedFiles: ['tests/dummy/**/*.js'], 51 | env: { 52 | embertest: true 53 | } 54 | } 55 | ] 56 | }; 57 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ember-suave" 3 | } 4 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "bracketSpacing": true, 4 | "trailingComma": "none", 5 | "useTabs": false, 6 | "tabWidth": 2, 7 | "printWidth": 120, 8 | "semi": true 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 'stable' 4 | 5 | sudo: required 6 | dist: trusty 7 | addons: 8 | chrome: stable 9 | before_script: 10 | - "sudo chown root /opt/google/chrome/chrome-sandbox" 11 | - "sudo chmod 4755 /opt/google/chrome/chrome-sandbox" 12 | 13 | addons: 14 | chrome: stable 15 | 16 | cache: 17 | yarn: true 18 | 19 | env: 20 | global: 21 | # See https://git.io/vdao3 for details. 22 | - JOBS=1 23 | matrix: 24 | fast_finish: true 25 | allow_failures: 26 | - env: EMBER_TRY_SCENARIO=ember-canary 27 | 28 | before_install: 29 | - curl -o- -L https://yarnpkg.com/install.sh | bash 30 | - export PATH=$HOME/.yarn/bin:$PATH 31 | 32 | install: 33 | - yarn install --no-lockfile --non-interactive 34 | 35 | script: 36 | - yarn lint:js 37 | # Usually, it's ok to finish the test scenario without reverting 38 | # to the addon's original dependency state, skipping "cleanup". 39 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO --skip-cleanup 40 | 41 | 42 | stages: 43 | - basic test 44 | - additional tests 45 | jobs: 46 | fail_fast: true 47 | include: 48 | - stage: basic test 49 | env: EMBER_TRY_SCENARIO=ember-release 50 | - stage: additional tests 51 | env: EMBER_TRY_SCENARIO=ember-lts-2.12 52 | - env: EMBER_TRY_SCENARIO=ember-lts-2.16 53 | - env: EMBER_TRY_SCENARIO=ember-beta 54 | - env: EMBER_TRY_SCENARIO=ember-canary -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "javascript.implicitProjectConfig.checkJs": true 3 | } -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Levanto Financial 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-data-preload [![Build Status](https://travis-ci.org/mike-north/ember-data-preload.svg?branch=master)](https://travis-ci.org/mike-north/ember-data-preload) [![Ember Observer Score](https://emberobserver.com/badges/ember-data-preload.svg)](https://emberobserver.com/addons/ember-data-preload) 2 | 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/mike-north/ember-data-preload.svg)](https://greenkeeper.io/) 4 | 5 | 6 | # Why? 7 | Preloading deeply nested relationships is possible w/ ember-data, but it can be a little messy 8 | 9 | For example, if we have a `List` model, each record of which has many `ListItem`s, each of which has an `Assignee`, and we wanted to load all of the relevant data by the time the route was done resolving, we'd have to do something like this: 10 | 11 | ```js 12 | 13 | Ember.Route.extend({ 14 | model() { 15 | 16 | // Load lists 17 | return this.store.findAll('lists').then((lists) => { 18 | 19 | // Get promises for loading all list-items owned by the lists, 20 | // and wait for them all to resolve 21 | return Ember.RSVP.all( 22 | lists.map((l) => l.get('list-item')) 23 | .reduce((prev, cur) => prev.concat(cur)) 24 | ).then((listItems) => { 25 | // Get promises for loading all assignees of the list-items, 26 | return Ember.RSVP.all( 27 | listItems.map((listItem) => listItem.get('assignee')) 28 | .reduce((prev, cur) => prev.concat(cur)) 29 | ); 30 | }).then(() => lists); 31 | }); 32 | } 33 | }); 34 | 35 | ``` 36 | 37 | # Use 38 | 39 | First, install this addon in your ember-cli app 40 | `ember install ember-data-preload` 41 | 42 | And then, you may preload relationships (i.e., in a route) 43 | 44 | ```js 45 | import preload from 'ember-data-preload'; 46 | 47 | export default Ember.Route.extend({ 48 | model() { 49 | return preload(this.store.findAll('lists'), {'list-items': 'assignees'}); 50 | } 51 | }); 52 | 53 | ``` 54 | 55 | 56 | Particularly when relationship hierarchies are deep, this can be particularly time-saving 57 | 58 | ```js 59 | import preload from 'ember-data-preload'; 60 | 61 | export default Ember.Route.extend({ 62 | model() { 63 | return preload(this.store.findAll('country'), { 64 | city: { 65 | neighborhood: { 66 | street: 'house' 67 | } 68 | } 69 | }); 70 | } 71 | }); 72 | 73 | ``` 74 | 75 | This README outlines the details of collaborating on this Ember addon. 76 | 77 | ## Installation 78 | 79 | * `git clone` this repository 80 | * `npm install` 81 | * `bower install` 82 | 83 | ## Running 84 | 85 | * `ember server` 86 | * Visit your app at http://localhost:4200. 87 | 88 | ## Running Tests 89 | 90 | * `npm test` (Runs `ember try:testall` to test your addon against multiple Ember versions) 91 | * `ember test` 92 | * `ember test --server` 93 | 94 | ## Building 95 | 96 | * `ember build` 97 | 98 | For more information on using ember-cli, visit [http://www.ember-cli.com/](http://www.ember-cli.com/). 99 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/addon/.gitkeep -------------------------------------------------------------------------------- /addon/index.js: -------------------------------------------------------------------------------- 1 | import { resolve, all } from 'rsvp'; 2 | import { get } from '@ember/object'; 3 | import { isArray } from '@ember/array'; 4 | import { typeOf } from '@ember/utils'; 5 | 6 | function getPromise(object, property) { 7 | return resolve(get(object, property)); 8 | } 9 | 10 | function preloadRecord(record, toPreload) { 11 | if (!record) { 12 | return resolve(record); 13 | } 14 | 15 | switch (typeOf(toPreload)) { 16 | case 'string': 17 | return getPromise(record, toPreload).then(() => record); 18 | case 'array': 19 | return all(toPreload.map(p => preloadRecord(record, p))).then(() => record); 20 | case 'object': 21 | return all(Object.keys(toPreload).map(p => getPromise(record, p).then(data => preload(data, toPreload[p])))).then( 22 | () => record 23 | ); 24 | default: 25 | throw 'Illegal Argument'; 26 | } 27 | } 28 | 29 | function preloadAll(records, toPreload) { 30 | return all(records.map(record => preload(record, toPreload))); 31 | } 32 | 33 | function preload(thing, toPreload) { 34 | return resolve(thing).then(() => { 35 | return isArray(thing) ? preloadAll(thing, toPreload) : preloadRecord(thing, toPreload); 36 | }); 37 | } 38 | 39 | export default preload; 40 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/app/.gitkeep -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-data-preload", 3 | "dependencies": { 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | useYarn: true, 3 | scenarios: [ 4 | { 5 | name: 'ember-lts-2.12', 6 | npm: { 7 | devDependencies: { 8 | 'ember-source': '~2.12.0' 9 | } 10 | } 11 | }, 12 | { 13 | name: 'ember-lts-2.16', 14 | npm: { 15 | devDependencies: { 16 | 'ember-source': '~2.16.0' 17 | } 18 | } 19 | }, 20 | { 21 | name: 'ember-release', 22 | bower: { 23 | dependencies: { 24 | ember: 'components/ember#release' 25 | }, 26 | resolutions: { 27 | ember: 'release' 28 | } 29 | }, 30 | npm: { 31 | devDependencies: { 32 | 'ember-source': null 33 | } 34 | } 35 | }, 36 | { 37 | name: 'ember-beta', 38 | bower: { 39 | dependencies: { 40 | ember: 'components/ember#beta' 41 | }, 42 | resolutions: { 43 | ember: 'beta' 44 | } 45 | }, 46 | npm: { 47 | devDependencies: { 48 | 'ember-source': null 49 | } 50 | } 51 | }, 52 | { 53 | name: 'ember-canary', 54 | bower: { 55 | dependencies: { 56 | ember: 'components/ember#canary' 57 | }, 58 | resolutions: { 59 | ember: 'canary' 60 | } 61 | }, 62 | npm: { 63 | devDependencies: { 64 | 'ember-source': null 65 | } 66 | } 67 | }, 68 | { 69 | name: 'ember-default', 70 | npm: { 71 | devDependencies: {} 72 | } 73 | } 74 | ] 75 | }; 76 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ember-data-preload.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "path": ".", 6 | "name": "EmberDataPreload", 7 | "folder_exclude_patterns": ["node_modules", "bower_components", "tmp"] 8 | } 9 | ], 10 | "settings": { 11 | "tab_size": 2, 12 | "translate_tabs_to_spaces": true 13 | }, 14 | "build_systems": [ 15 | { 16 | "name": "Ember-CLI Server", 17 | "shell_cmd": "ember s" 18 | }, 19 | { 20 | "name": "Ember-CLI Tests", 21 | "shell_cmd": "ember test ci" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | name: 'ember-data-preload' 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-data-preload", 3 | "version": "0.2.1", 4 | "description": "Eagerly load deeply nested ember-data relationships", 5 | "directories": { 6 | "doc": "doc", 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "build": "ember build", 11 | "lint:js": "eslint ./*.js addon addon-test-support app config lib server test-support tests", 12 | "start": "ember serve", 13 | "test": "ember try:each" 14 | }, 15 | "repository": "https://github.com/mike-north/ember-data-preload.git", 16 | "engines": { 17 | "node": "^4.5 || 6.* || >= 7.*" 18 | }, 19 | "author": "Mike North (http://mike.works)", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "@types/ember": "4.0.11", 23 | "broccoli-asset-rev": "3.0.0", 24 | "ember-cli": "6.4.0", 25 | "ember-cli-app-version": "7.0.0", 26 | "ember-cli-dependency-checker": "3.3.3", 27 | "ember-cli-eslint": "5.1.0", 28 | "ember-cli-htmlbars": "6.3.0", 29 | "ember-cli-htmlbars-inline-precompile": "3.0.2", 30 | "ember-cli-inject-live-reload": "2.1.0", 31 | "ember-cli-pretender": "4.0.0", 32 | "ember-cli-qunit": "4.4.0", 33 | "ember-cli-release": "1.0.0-beta.2", 34 | "ember-cli-shims": "1.2.0", 35 | "ember-cli-test-loader": "3.1.0", 36 | "ember-cli-uglify": "3.0.0", 37 | "ember-data": "5.5.0", 38 | "ember-disable-prototype-extensions": "1.1.3", 39 | "ember-export-application-global": "2.0.1", 40 | "ember-load-initializers": "3.0.1", 41 | "ember-resolver": "13.1.1", 42 | "ember-source": "6.5.0", 43 | "ember-sublime": "0.0.9", 44 | "eslint-plugin-ember": "12.5.0", 45 | "eslint-plugin-n": "17.19.0", 46 | "greenkeeper-lockfile": "1.15.1", 47 | "loader.js": "4.7.0" 48 | }, 49 | "keywords": [ 50 | "ember-addon", 51 | "data", 52 | "api", 53 | "elixir", 54 | "ecto", 55 | "preload", 56 | "load", 57 | "ajax", 58 | "xhr", 59 | "persistence" 60 | ], 61 | "dependencies": { 62 | "ember-cli-babel": "8.2.0" 63 | }, 64 | "ember-addon": { 65 | "configPath": "tests/dummy/config" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "automerge": true 6 | } 7 | -------------------------------------------------------------------------------- /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 | '--disable-gpu', 15 | '--headless', 16 | '--remote-debugging-port=0', 17 | '--window-size=1440,900' 18 | ] 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | embertest: true 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /tests/acceptance/index-test.js: -------------------------------------------------------------------------------- 1 | import { test } from 'qunit'; 2 | import moduleForAcceptance from '../../tests/helpers/module-for-acceptance'; 3 | import Pretender from 'pretender'; 4 | 5 | let server = null; 6 | 7 | function json(obj) { 8 | return [200, {}, JSON.stringify(obj)]; 9 | } 10 | 11 | moduleForAcceptance('Acceptance | index', { 12 | beforeEach() { 13 | server = new Pretender(); 14 | }, 15 | afterEach() { 16 | server.shutdown(); 17 | } 18 | }); 19 | 20 | test('visiting /', function(assert) { 21 | assert.expect(7); 22 | 23 | server.get('/countries', function() { 24 | assert.ok(true, 'Countries requested'); 25 | return json({ 26 | countries: [ 27 | { 28 | id: 1, 29 | name: 'USA', 30 | cities: [1, 2], 31 | capital: 1 32 | } 33 | ] 34 | }); 35 | }); 36 | 37 | server.get('/cities', function() { 38 | assert.ok(true, 'Cities requested'); 39 | return json({ 40 | cities: [ 41 | { 42 | country: 1, 43 | id: 1, 44 | name: 'Washington, DC', 45 | neighborhoods: [1] 46 | }, 47 | { 48 | country: 1, 49 | id: 2, 50 | name: 'San Francisco', 51 | neighborhoods: [2, 3] 52 | } 53 | ] 54 | }); 55 | }); 56 | 57 | server.get('/neighborhoods', function() { 58 | assert.ok(true, 'Neighborhoods requested'); 59 | return json({ 60 | neighborhoods: [ 61 | { 62 | city: 1, 63 | id: 1, 64 | name: 'Adams Morgan', 65 | streets: [1, 2], 66 | parks: [1, 2] 67 | }, 68 | { 69 | city: 2, 70 | id: 2, 71 | name: 'Tenderloin', 72 | streets: [3], 73 | parks: [] 74 | }, 75 | { 76 | city: 2, 77 | id: 3, 78 | name: 'Financial District', 79 | streets: [], 80 | parks: [3] 81 | } 82 | ] 83 | }); 84 | }); 85 | 86 | server.get('/parks', function() { 87 | assert.ok(true, 'Parks requested'); 88 | return json({ 89 | parks: [ 90 | { 91 | neighborhood: 1, 92 | id: 1, 93 | name: 'Smithsonian National Zoological Park' 94 | }, 95 | { 96 | neighborhood: 1, 97 | id: 2, 98 | name: 'Meridian Hill Park' 99 | }, 100 | { 101 | neighborhood: 2, 102 | id: 3, 103 | name: 'Sue Bierman Park' 104 | } 105 | ] 106 | }); 107 | }); 108 | 109 | server.get('/streets', function() { 110 | assert.ok(true, 'Streets requested'); 111 | return json({ 112 | streets: [ 113 | { 114 | neighborhood: 1, 115 | id: 1, 116 | name: 'California St.', 117 | houses: [1, 2] 118 | }, 119 | { 120 | neighborhood: 2, 121 | id: 2, 122 | name: 'Eddie St.', 123 | houses: [] 124 | }, 125 | { 126 | neighborhood: 2, 127 | id: 3, 128 | name: 'Sacramento St.', 129 | houses: [] 130 | } 131 | ] 132 | }); 133 | }); 134 | 135 | server.get('/houses', function() { 136 | assert.ok(true, 'Houses requested'); 137 | return json({ 138 | houses: [ 139 | { 140 | street: 1, 141 | id: 1, 142 | name: 'A house' 143 | }, 144 | { 145 | street: 1, 146 | id: 2, 147 | name: 'Another house' 148 | } 149 | ] 150 | }); 151 | }); 152 | 153 | visit('/'); 154 | 155 | andThen(() => { 156 | assert.equal(find('.country').text(), 'USA', 'One country div on the screen'); 157 | assert.equal(currentURL(), '/'); 158 | }); 159 | }); 160 | -------------------------------------------------------------------------------- /tests/dummy/app/adapters/application.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { RESTAdapter } = DS; 4 | 5 | export default RESTAdapter.extend({ 6 | coalesceFindRequests: true 7 | }); 8 | -------------------------------------------------------------------------------- /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 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/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/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/models/city.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr, hasMany, belongsTo, Model } = DS; 4 | 5 | export default Model.extend({ 6 | name: attr('string'), 7 | country: belongsTo('country', { inverse: 'cities' }), 8 | capitalOf: belongsTo('country', { inverse: 'capital' }), 9 | neighborhoods: hasMany('neighborhood') 10 | }); 11 | -------------------------------------------------------------------------------- /tests/dummy/app/models/country.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr, belongsTo, hasMany, Model } = DS; 4 | 5 | export default Model.extend({ 6 | name: attr('string'), 7 | capital: belongsTo('city', { inverse: 'capitalOf' }), 8 | cities: hasMany('city', { inverse: 'country' }) 9 | }); 10 | -------------------------------------------------------------------------------- /tests/dummy/app/models/house.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr, belongsTo, Model } = DS; 4 | 5 | export default Model.extend({ 6 | name: attr('string'), 7 | street: belongsTo('street') 8 | }); 9 | -------------------------------------------------------------------------------- /tests/dummy/app/models/neighborhood.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr, hasMany, belongsTo, Model } = DS; 4 | 5 | export default Model.extend({ 6 | name: attr('string'), 7 | city: belongsTo('city'), 8 | streets: hasMany('street') 9 | }); 10 | -------------------------------------------------------------------------------- /tests/dummy/app/models/park.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr, belongsTo, Model } = DS; 4 | 5 | export default Model.extend({ 6 | name: attr('string'), 7 | neighborhood: belongsTo('neighborhood') 8 | }); 9 | -------------------------------------------------------------------------------- /tests/dummy/app/models/street.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr, hasMany, belongsTo, Model } = DS; 4 | 5 | export default Model.extend({ 6 | name: attr('string'), 7 | neighborhood: belongsTo('neighborhood'), 8 | houses: hasMany('house') 9 | }); 10 | -------------------------------------------------------------------------------- /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.rootURL 7 | }); 8 | 9 | Router.map(function() {}); 10 | 11 | export default Router; 12 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/routes/application.js: -------------------------------------------------------------------------------- 1 | import Route from '@ember/routing/route'; 2 | import preload from 'ember-data-preload'; 3 | 4 | export default Route.extend({ 5 | model() { 6 | return preload(this.store.findAll('country'), [ 7 | { 8 | cities: { 9 | neighborhoods: [{ streets: 'houses' }, 'parks'] 10 | } 11 | }, 12 | 'capital' 13 | ]); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/dummy/app/styles/app.css -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

Welcome to Ember

2 | {{#each model as |country|}} 3 | {{country.name}} 4 | {{/each}} 5 | {{outlet}} 6 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /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 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. 'with-controller': true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false 17 | } 18 | }, 19 | 20 | APP: { 21 | // Here you can pass flags/options to your application instance 22 | // when it is created 23 | } 24 | }; 25 | 26 | if (environment === 'development') { 27 | // ENV.APP.LOG_RESOLVER = true; 28 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 29 | // ENV.APP.LOG_TRANSITIONS = true; 30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 31 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 32 | } 33 | 34 | if (environment === 'test') { 35 | // Testem prefers this... 36 | ENV.locationType = 'none'; 37 | 38 | // keep test console output quieter 39 | ENV.APP.LOG_ACTIVE_GENERATION = false; 40 | ENV.APP.LOG_VIEW_LOOKUPS = false; 41 | 42 | ENV.APP.rootElement = '#ember-testing'; 43 | ENV.APP.autoboot = false; 44 | } 45 | 46 | if (environment === 'production') { 47 | // here you can enable a production-specific feature 48 | } 49 | 50 | return ENV; 51 | }; 52 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | browsers: ['ie 9', 'last 1 Chrome versions', 'last 1 Firefox versions', 'last 1 Safari versions'] 3 | }; 4 | -------------------------------------------------------------------------------- /tests/dummy/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/destroy-app.js: -------------------------------------------------------------------------------- 1 | import { run } from '@ember/runloop'; 2 | 3 | export default function destroyApp(application) { 4 | run(application, 'destroy'); 5 | } 6 | -------------------------------------------------------------------------------- /tests/helpers/module-for-acceptance.js: -------------------------------------------------------------------------------- 1 | import { module } from 'qunit'; 2 | import { resolve } from 'rsvp'; 3 | import startApp from '../helpers/start-app'; 4 | import destroyApp from '../helpers/destroy-app'; 5 | 6 | export default function(name, options = {}) { 7 | module(name, { 8 | beforeEach() { 9 | this.application = startApp(); 10 | 11 | if (options.beforeEach) { 12 | return options.beforeEach.apply(this, arguments); 13 | } 14 | }, 15 | 16 | afterEach() { 17 | let afterEach = options.afterEach && options.afterEach.apply(this, arguments); 18 | return resolve(afterEach).then(() => destroyApp(this.application)); 19 | } 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from '../../resolver'; 2 | import config from '../../config/environment'; 3 | 4 | const resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import Application from '../../app'; 2 | import config from '../../config/environment'; 3 | import { merge } from '@ember/polyfills'; 4 | import { run } from '@ember/runloop'; 5 | 6 | export default function startApp(attrs) { 7 | let attributes = merge({}, config.APP); 8 | attributes.autoboot = true; 9 | attributes = merge(attributes, attrs); // use defaults, but you can override; 10 | 11 | return run(() => { 12 | let application = Application.create(attributes); 13 | application.setupForTesting(); 14 | application.injectTestHelpers(); 15 | return application; 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /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/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/integration/.gitkeep -------------------------------------------------------------------------------- /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/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/tests/unit/.gitkeep -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mike-north/ember-data-preload/47fc1d3efd743d1a88b55ec404aefaafcf5a0ebb/vendor/.gitkeep --------------------------------------------------------------------------------