├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .eslintrc.js ├── .gitignore ├── .jshintrc ├── .travis.yml ├── .watchmanconfig ├── README.md ├── app ├── adapters │ └── application.js ├── app.js ├── components │ ├── .gitkeep │ ├── github-org.js │ └── github-repo.js ├── controllers │ └── .gitkeep ├── helpers │ ├── .gitkeep │ └── nice-number.js ├── index.html ├── models │ ├── .gitkeep │ ├── org.js │ └── repo.js ├── resolver.js ├── router.js ├── routes │ ├── .gitkeep │ ├── index.js │ ├── org.js │ ├── org │ │ ├── index.js │ │ ├── notfound.js │ │ ├── repo.js │ │ ├── repo │ │ │ ├── contributors.js │ │ │ ├── index.js │ │ │ └── issues.js │ │ └── repos.js │ └── orgs.js ├── serializers │ └── application.js ├── services │ └── favorites.js ├── styles │ └── app.scss ├── templates │ ├── application.hbs │ ├── components │ │ ├── .gitkeep │ │ ├── github-org.hbs │ │ └── github-repo.hbs │ ├── error.hbs │ ├── index.hbs │ ├── notfound.hbs │ ├── org-loading.hbs │ ├── org.hbs │ ├── org │ │ ├── index.hbs │ │ ├── notfound.hbs │ │ ├── repo.hbs │ │ ├── repo │ │ │ ├── contributors.hbs │ │ │ ├── index.hbs │ │ │ └── issues.hbs │ │ └── repos.hbs │ └── orgs.hbs └── utils │ └── is-in-array.js ├── bower.json ├── config └── environment.js ├── ember-cli-build.js ├── package.json ├── public ├── crossdomain.xml └── robots.txt ├── testem.js ├── testem.json ├── tests ├── .eslintrc.js ├── .jshintrc ├── acceptance │ └── index-test.js ├── helpers │ ├── destroy-app.js │ ├── module-for-acceptance.js │ ├── resolver.js │ └── start-app.js ├── index.html ├── integration │ └── components │ │ ├── github-org-test.js │ │ └── github-repo-test.js ├── test-helper.js └── unit │ ├── .gitkeep │ ├── adapters │ └── application-test.js │ ├── helpers │ └── nice-number-test.js │ ├── models │ ├── org-test.js │ └── repo-test.js │ ├── routes │ ├── index-test.js │ ├── org-test.js │ ├── org │ │ ├── index-test.js │ │ ├── notfound-test.js │ │ ├── repo-test.js │ │ ├── repo │ │ │ ├── contributors-test.js │ │ │ ├── index-test.js │ │ │ └── issues-test.js │ │ └── repos-test.js │ └── orgs-test.js │ ├── serializers │ └── application-test.js │ ├── services │ └── favorites-test.js │ └── utils │ └── is-in-array-test.js └── vendor └── .gitkeep /.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 | parser: "babel-eslint", 4 | parserOptions: { 5 | ecmaVersion: 6, 6 | sourceType: 'module' 7 | }, 8 | indent: ['error', 2], 9 | extends: [ 10 | 'eslint:recommended', 11 | 'plugin:ember-suave/recommended' 12 | ], 13 | env: { 14 | 'browser': true 15 | }, 16 | plugins: ['babel', 'promise'], 17 | rules: { 18 | "key-spacing": 0, 19 | "object-curly-spacing": 0, 20 | "space-infix-ops": 0, 21 | "no-var": 0, 22 | "no-console": 0, 23 | "no-debugger": 0, 24 | "camelcase": 0, 25 | "keyword-spacing": 0, 26 | "no-multiple-empty-lines": 0, 27 | "space-before-function-paren": 0, 28 | "object-shorthand": 0, 29 | "space-before-blocks": 0, 30 | "spaced-comment": 0, 31 | "arrow-parens": 0, 32 | "no-unused-vars": 0, 33 | "quotes": 0, 34 | "comma-spacing": 0, 35 | "ember-suave/no-const-outside-module-scope": 0, 36 | "ember-suave/no-direct-property-access": 0, 37 | "no-undef": 0, 38 | "strict": 0, 39 | 'babel/arrow-parens': 0, 40 | 'no-fallthrough': 0, 41 | "promise/always-return": "error", 42 | "promise/no-return-wrap": "error", 43 | "promise/param-names": "error", 44 | "promise/catch-or-return": "error", 45 | "promise/no-native": "off", 46 | "promise/no-nesting": "warn", 47 | "promise/no-promise-in-callback": "warn", 48 | "promise/no-callback-in-promise": "warn", 49 | "promise/avoid-new": "warn" 50 | } 51 | }; -------------------------------------------------------------------------------- /.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 | testem.log 18 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise" 6 | ], 7 | "browser": true, 8 | "boss": true, 9 | "curly": true, 10 | "debug": false, 11 | "devel": true, 12 | "eqeqeq": true, 13 | "evil": true, 14 | "forin": false, 15 | "immed": false, 16 | "laxbreak": false, 17 | "newcap": true, 18 | "noarg": true, 19 | "noempty": false, 20 | "nonew": false, 21 | "nomen": false, 22 | "onevar": false, 23 | "plusplus": false, 24 | "regexp": false, 25 | "undef": true, 26 | "sub": true, 27 | "strict": false, 28 | "white": false, 29 | "eqnull": true, 30 | "esnext": true, 31 | "unused": true 32 | } 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | - "6" 5 | 6 | sudo: false 7 | 8 | cache: 9 | directories: 10 | - $HOME/.npm 11 | - $HOME/.cache # includes bowers cache 12 | 13 | before_install: 14 | - npm config set spin false 15 | - npm install -g bower phantomjs-prebuilt 16 | - bower --version 17 | - phantomjs --version 18 | 19 | install: 20 | - npm install 21 | - bower install 22 | 23 | script: 24 | - npm test 25 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # github-ui 2 | 3 | This README outlines the details of collaborating on this Ember application. 4 | 5 | ## Prerequisites 6 | 7 | You will need the following things properly installed on your computer. 8 | 9 | * [Git](https://git-scm.com/) 10 | * [Node.js](https://nodejs.org/) (with NPM) 11 | * [Bower](https://bower.io/) 12 | * [Ember CLI](https://ember-cli.com/) 13 | * [PhantomJS](http://phantomjs.org/) 14 | 15 | ## Installation 16 | 17 | * `git clone ` this repository 18 | * `cd github-ui` 19 | * `npm install` 20 | * `bower install` 21 | 22 | ## Running / Development 23 | 24 | * `ember serve` 25 | * Visit your app at [http://localhost:4200](http://localhost:4200). 26 | 27 | ### Code Generators 28 | 29 | Make use of the many generators for code, try `ember help generate` for more details 30 | 31 | ### Running Tests 32 | 33 | * `ember test` 34 | * `ember test --server` 35 | 36 | ### Building 37 | 38 | * `ember build` (development) 39 | * `ember build --environment production` (production) 40 | 41 | ### Deploying 42 | 43 | Specify what it takes to deploy your app. 44 | 45 | ## Following Along with the Course 46 | 47 | The application was built out in stages ([see the git commits](https://github.com/FrontendMasters/ember-github-ui/commits/master)) in the [Ember 2.x course on Frontend Masters](https://frontendmasters.com/courses/ember-2/). 48 | 49 | To follow along with the course, [reset to an earlier commit](http://stackoverflow.com/questions/4114095/revert-git-repository-to-a-previous-commit/4114122#4114122) and build from there following the videos. 50 | 51 | ## Further Reading / Useful Links 52 | 53 | * [ember.js](http://emberjs.com/) 54 | * [ember-cli](https://ember-cli.com/) 55 | * Development Browser Extensions 56 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) 57 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) 58 | -------------------------------------------------------------------------------- /app/adapters/application.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.RESTAdapter.extend({ 4 | host: 'https://api.github.com', 5 | 6 | urlForQueryRecord(query, modelName) { 7 | switch(modelName) { 8 | case 'repo': 9 | return `https://api.github.com/repos/${query.orgId}/${query.repoId}?access_token=99d4a35f7c58ecf4bacf8a730206869a6c92c4cf`; 10 | default: 11 | return this._super(...arguments); 12 | } 13 | }, 14 | 15 | urlForQuery (query, modelName) { 16 | switch(modelName) { 17 | case 'repo': 18 | return `${this.get('host')}/orgs/${query.orgId}/repos`; 19 | default: 20 | return this._super(...arguments); 21 | } 22 | } 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /app/app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | let App; 7 | 8 | Ember.MODEL_FACTORY_INJECTIONS = true; 9 | 10 | App = Ember.Application.extend({ 11 | modulePrefix: config.modulePrefix, 12 | podModulePrefix: config.podModulePrefix, 13 | Resolver 14 | }); 15 | 16 | loadInitializers(App, config.modulePrefix); 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/app/components/.gitkeep -------------------------------------------------------------------------------- /app/components/github-org.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import isInArray from 'github-ui/utils/is-in-array'; 3 | 4 | export default Ember.Component.extend({ 5 | tagName: 'li', 6 | favorites: Ember.inject.service(), 7 | classNames: ['github-org'], 8 | isFavorited: isInArray('org', 'favorites.items'), 9 | actions: { 10 | favoriteWasClicked() { 11 | this.sendAction('on-fav-clicked', this.get('org')); 12 | } 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /app/components/github-repo.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | tagName: 'li' 5 | }); 6 | -------------------------------------------------------------------------------- /app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/app/controllers/.gitkeep -------------------------------------------------------------------------------- /app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/app/helpers/.gitkeep -------------------------------------------------------------------------------- /app/helpers/nice-number.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export function niceNumber(params/*, hash*/) { 4 | if (!params) { 5 | return ''; 6 | } 7 | const [num] = params; 8 | if (parseInt(num, 10) > 1000) { 9 | return `${Math.round(num * 0.01) * 0.1}K`; 10 | } else { 11 | return `${num}`; 12 | } 13 | } 14 | 15 | export default Ember.Helper.helper(niceNumber); 16 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | GithubUi 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 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/app/models/.gitkeep -------------------------------------------------------------------------------- /app/models/org.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr } = DS; 4 | 5 | export default DS.Model.extend({ 6 | login: attr('string'), 7 | name: attr('string') 8 | }); 9 | -------------------------------------------------------------------------------- /app/models/repo.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { attr } = DS; 4 | 5 | export default DS.Model.extend({ 6 | name: attr('string'), 7 | forks_count: attr('number'), 8 | watchers_count: attr('number') 9 | }); 10 | -------------------------------------------------------------------------------- /app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /app/router.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import config from './config/environment'; 3 | 4 | const { Router } = Ember; 5 | 6 | const AppRouter = Router.extend({ 7 | location: config.locationType, 8 | rootURL: config.rootURL 9 | }); 10 | 11 | 12 | AppRouter.map(function() { 13 | // LIST OF ORGS 14 | this.route('orgs', {}); // /orgs 15 | 16 | // INDIVIDUAL ORG 17 | this.route('org', { path: 'org/:id' }, function() { 18 | // org/emberjs 19 | 20 | // LIST OF REPOS 21 | this.route('repos', {}); 22 | 23 | // INDIVIDUAL REPO 24 | // org/jquery/jquery-ui 25 | this.route('repo', { path: ':repoid' }, function() { 26 | this.route('contributors', {}); 27 | this.route('issues', {}); 28 | }); 29 | this.route('notfound', {}); 30 | }); 31 | this.route('notfound', { path: '*path' }); 32 | }); 33 | 34 | export default AppRouter; 35 | -------------------------------------------------------------------------------- /app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/app/routes/.gitkeep -------------------------------------------------------------------------------- /app/routes/index.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | beforeModel() { 5 | this._super(...arguments); 6 | this.replaceWith('orgs'); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /app/routes/org.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | 5 | actions: { 6 | error(jqxhr) { 7 | if (jqxhr.status === 404) { 8 | this.intermediateTransitionTo('org.notfound'); 9 | } else { 10 | return true; // bubble up 11 | } 12 | } 13 | }, 14 | 15 | model(params) { 16 | return $.get(`https://api.github.com/orgs/${params.id}?access_token=99d4a35f7c58ecf4bacf8a730206869a6c92c4cf`).then(rawOrg => { 17 | // backing up github's numeric ID 18 | rawOrg.oldId = rawOrg.id; 19 | // use the name of the repo as our ID 20 | rawOrg.id = rawOrg.name; 21 | return rawOrg; 22 | }); 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /app/routes/org/index.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | beforeModel() { 5 | this._super(...arguments); 6 | this.transitionTo('org.repos'); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /app/routes/org/notfound.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /app/routes/org/repo.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model(params) { 5 | let orgId = Ember.get(this.modelFor('org'), 'login'); 6 | return this.store.queryRecord('repo', { 7 | orgId, 8 | repoId: params.repoid 9 | }); 10 | // return $.get(`https://api.github.com/repos/${org.login}/${params.repoid}?access_token=99d4a35f7c58ecf4bacf8a730206869a6c92c4cf`).then(rawRepo => { 11 | // // backing up github's numeric ID 12 | // rawRepo.oldId = rawRepo.id; 13 | // // use the name of the repo as our ID 14 | // rawRepo.id = rawRepo.name; 15 | // return rawRepo; 16 | // }); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /app/routes/org/repo/contributors.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model() { 5 | let orgId = Ember.get(this.modelFor('org'), 'login'); 6 | let repoId = Ember.get(this.modelFor('org.repo'), 'name'); 7 | return $.get(`https://api.github.com/repos/${orgId}/${repoId}/contributors?access_token=99d4a35f7c58ecf4bacf8a730206869a6c92c4cf`).then(rawContributors => { 8 | return rawContributors.map(rawContributor => { 9 | rawContributor.oldId = rawContributor.id; 10 | rawContributor.id = rawContributor.name; 11 | return rawContributor; 12 | }); 13 | }); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /app/routes/org/repo/index.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | beforeModel() { 5 | this._super(...arguments); 6 | this.transitionTo('org.repo.issues'); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /app/routes/org/repo/issues.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model() { 5 | let orgId = Ember.get(this.modelFor('org'), 'login'); 6 | let repoId = Ember.get(this.modelFor('org.repo'), 'name'); 7 | return $.get(`https://api.github.com/repos/${orgId}/${repoId}/issues?access_token=99d4a35f7c58ecf4bacf8a730206869a6c92c4cf`).then(rawIssues => { 8 | return rawIssues.map(rawIssue => { 9 | rawIssue.oldId = rawIssue.id; 10 | rawIssue.id = rawIssue.name; 11 | return rawIssue; 12 | }); 13 | }); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /app/routes/org/repos.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | model(params) { 5 | let orgId = Ember.get(this.modelFor('org'), 'login'); 6 | return this.store.query('repo', { 7 | orgId 8 | }); 9 | // return $.get(`https://api.github.com/orgs/${orgId}/repos?access_token=99d4a35f7c58ecf4bacf8a730206869a6c92c4cf`).then(rawRepos => { 10 | // return rawRepos.map(rawRepo => { 11 | // rawRepo.oldId = rawRepo.id; 12 | // rawRepo.id = rawRepo.name; 13 | // return rawRepo; 14 | // }); 15 | // }); 16 | 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /app/routes/orgs.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | 5 | favorites: Ember.inject.service(), 6 | actions: { 7 | favoriteClicked(org) { 8 | if (this.get('favorites.items').indexOf(org) < 0) { 9 | this.get('favorites').favoriteItem(org); 10 | } else { 11 | this.get('favorites').unfavoriteItem(org); 12 | } 13 | } 14 | }, 15 | model() { 16 | return [{ 17 | id: "emberjs" 18 | }, { 19 | id: "ember-cli" 20 | }, { 21 | id: "microsoft" 22 | }, { 23 | id: "yahoo" 24 | }, { 25 | id: "netflix" 26 | }, { 27 | id: "facebook" 28 | }]; 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /app/serializers/application.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.RESTSerializer.extend({ 4 | normalizeResponse (store, primaryModelClass, payload, 5 | id, requestType) { 6 | 7 | let tlk; 8 | switch(requestType) { 9 | case 'query': 10 | tlk = Ember.Inflector.inflector.pluralize(primaryModelClass.modelName); 11 | payload = payload.map((rawItem) => { 12 | rawItem.oldId = rawItem.id; 13 | rawItem.id = rawItem.login || rawItem.name; 14 | return rawItem; 15 | }); 16 | break; 17 | case 'queryRecord': 18 | tlk = Ember.Inflector.inflector.singularize(primaryModelClass.modelName); 19 | payload.oldId = payload.id; 20 | payload.id = payload.login || payload.name; 21 | break; 22 | default: 23 | debugger; 24 | } 25 | 26 | return this._super(store, primaryModelClass, 27 | {[`${tlk}`]: payload}, id, requestType); 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /app/services/favorites.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Service.extend({ 4 | items: [], 5 | log() { 6 | console.log( 7 | this.get('items') 8 | .map(x => x.id) 9 | .join(', ') 10 | ); 11 | }, 12 | favoriteItem(item) { 13 | this.get('items').addObject(item); 14 | this.log(); 15 | }, 16 | unfavoriteItem(item) { 17 | this.get('items').removeObject(item); 18 | this.log(); 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /app/styles/app.scss: -------------------------------------------------------------------------------- 1 | @import "bourbon"; 2 | 3 | .repo-nav { 4 | list-style: none; 5 | li { 6 | display: inline-block; 7 | a { 8 | font-weight: thin; 9 | text-decoration: none; 10 | } 11 | a.active { 12 | font-weight: bolder; 13 | text-decoration: underline; 14 | } 15 | } 16 | } 17 | 18 | .spinner { 19 | width: 40px; 20 | height: 40px; 21 | background-color: #333; 22 | 23 | margin: 100px auto; 24 | -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out; 25 | animation: sk-rotateplane 1.2s infinite ease-in-out; 26 | } 27 | 28 | @-webkit-keyframes sk-rotateplane { 29 | 0% { -webkit-transform: perspective(120px) } 30 | 50% { -webkit-transform: perspective(120px) rotateY(180deg) } 31 | 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } 32 | } 33 | 34 | @keyframes sk-rotateplane { 35 | 0% { 36 | transform: perspective(120px) rotateX(0deg) rotateY(0deg); 37 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg) 38 | } 50% { 39 | transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); 40 | -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg) 41 | } 100% { 42 | transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 43 | -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 44 | } 45 | } 46 | 47 | .grey-text { 48 | color: #999; 49 | } 50 | -------------------------------------------------------------------------------- /app/templates/application.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /app/templates/components/github-org.hbs: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | {{unless isFavorited 'Favorite' 'Unfavorite'}} 4 | ] 5 | 6 | {{link-to org.id 'org' org.id}} -------------------------------------------------------------------------------- /app/templates/components/github-repo.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{#link-to 'org.repo.issues' repo.name}} 3 | 4 | {{#if hasBlock}} 5 | {{yield}} 6 | {{else}} 7 | {{repo.name}} 8 | {{/if}} 9 | {{/link-to}} 10 | 11 | 12 | ( 13 | Forks: {{nice-number repo.forks_count}} 14 | Watchers: {{nice-number repo.watchers_count}} 15 | ) 16 | -------------------------------------------------------------------------------- /app/templates/error.hbs: -------------------------------------------------------------------------------- 1 |

Error

2 | 3 |

{{model.statusText}}

4 | -------------------------------------------------------------------------------- /app/templates/index.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /app/templates/notfound.hbs: -------------------------------------------------------------------------------- 1 |

Oops!!!

-------------------------------------------------------------------------------- /app/templates/org-loading.hbs: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /app/templates/org.hbs: -------------------------------------------------------------------------------- 1 | {{link-to 'Back to list of orgs' 'orgs'}} 2 | 3 |

4 | 5 | {{content.name}}

6 | 7 | {{outlet}} 8 | -------------------------------------------------------------------------------- /app/templates/org/index.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{outlet}} 3 | -------------------------------------------------------------------------------- /app/templates/org/notfound.hbs: -------------------------------------------------------------------------------- 1 |

Org not found

2 | 3 | {{outlet}} 4 | -------------------------------------------------------------------------------- /app/templates/org/repo.hbs: -------------------------------------------------------------------------------- 1 |
{{model.id}}
2 | 3 | 4 | 8 | {{outlet}} 9 | -------------------------------------------------------------------------------- /app/templates/org/repo/contributors.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | 3 | 4 |

Contributors

5 | 6 | -------------------------------------------------------------------------------- /app/templates/org/repo/index.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /app/templates/org/repo/issues.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | 3 |

Issues

4 | 5 | -------------------------------------------------------------------------------- /app/templates/org/repos.hbs: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | {{outlet}} 13 | -------------------------------------------------------------------------------- /app/templates/orgs.hbs: -------------------------------------------------------------------------------- 1 |

My Favorite Orgs

2 | 3 | 11 | 12 | {{outlet}} 13 | -------------------------------------------------------------------------------- /app/utils/is-in-array.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { computed } = Ember; 4 | 5 | export default function isInArray(itemKey, listKey /*favorites.items*/) { 6 | return computed(itemKey, `${listKey}.[]`, function() { 7 | // Do the computation; 8 | const item = this.get(itemKey); 9 | const list = this.get(listKey); 10 | return list.indexOf(item) >= 0; 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-ui", 3 | "dependencies": { 4 | "bourbon": "4.2.3" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | module.exports = function(environment) { 4 | var ENV = { 5 | modulePrefix: 'github-ui', 6 | environment: 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 | contentSecurityPolicy: { 20 | 'connect-src': 'https://api.github.com', 21 | 'img-src': 'https://avatars.githubusercontent.com' 22 | }, 23 | APP: { 24 | // Here you can pass flags/options to your application instance 25 | // when it is created 26 | } 27 | }; 28 | 29 | if (environment === 'development') { 30 | // ENV.APP.LOG_RESOLVER = true; 31 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 32 | // ENV.APP.LOG_TRANSITIONS = true; 33 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 34 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 35 | } 36 | 37 | if (environment === 'test') { 38 | // Testem prefers this... 39 | ENV.locationType = 'none'; 40 | 41 | // keep test console output quieter 42 | ENV.APP.LOG_ACTIVE_GENERATION = false; 43 | ENV.APP.LOG_VIEW_LOOKUPS = false; 44 | 45 | ENV.APP.rootElement = '#ember-testing'; 46 | } 47 | 48 | if (environment === 'production') { 49 | 50 | } 51 | 52 | return ENV; 53 | }; 54 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | const EmberApp = require('ember-cli/lib/broccoli/ember-app'); 3 | 4 | module.exports = function(defaults) { 5 | var app = new EmberApp(defaults, { 6 | // Add options here 7 | }); 8 | 9 | // Use `app.import` to add additional libraries to the generated 10 | // output files. 11 | // 12 | // If you need to use different assets in different 13 | // environments, specify an object as the first parameter. That 14 | // object's keys should be the environment name and the values 15 | // should be the asset to use in that environment. 16 | // 17 | // If the library that you are including contains AMD or ES6 18 | // modules that you would like to import into your application 19 | // please specify an object with the list of modules as keys 20 | // along with the exports of each module as its value. 21 | 22 | return app.toTree(); 23 | }; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-ui", 3 | "version": "0.0.0", 4 | "description": "Small description for github-ui goes here", 5 | "private": true, 6 | "directories": { 7 | "doc": "doc", 8 | "test": "tests" 9 | }, 10 | "scripts": { 11 | "build": "ember build", 12 | "start": "ember server", 13 | "test": "ember test" 14 | }, 15 | "repository": "", 16 | "engines": { 17 | "node": ">= 4" 18 | }, 19 | "author": "", 20 | "license": "MIT", 21 | "devDependencies": { 22 | "babel-eslint": "^7.1.0", 23 | "broccoli-asset-rev": "^2.4.5", 24 | "ember-cli": "2.12.1", 25 | "ember-cli-app-version": "^2.0.0", 26 | "ember-cli-babel": "^5.1.7", 27 | "ember-cli-bourbon": "1.1.0", 28 | "ember-cli-content-security-policy": "0.4.0", 29 | "ember-cli-dependency-checker": "^1.3.0", 30 | "ember-cli-eslint": "^3.0.0", 31 | "ember-cli-htmlbars": "^1.1.1", 32 | "ember-cli-htmlbars-inline-precompile": "^0.3.6", 33 | "ember-cli-ic-ajax": "0.2.1", 34 | "ember-cli-inject-live-reload": "^1.4.1", 35 | "ember-cli-qunit": "^3.1.0", 36 | "ember-cli-release": "0.2.3", 37 | "ember-cli-sass": "6.1.2", 38 | "ember-cli-shims": "^1.0.2", 39 | "ember-cli-sri": "^2.1.0", 40 | "ember-cli-uglify": "^1.2.0", 41 | "ember-data": "^2.12.0", 42 | "ember-disable-proxy-controllers": "^1.0.0", 43 | "ember-export-application-global": "^1.0.5", 44 | "ember-load-initializers": "^0.6.0", 45 | "ember-resolver": "^2.0.3", 46 | "ember-source": "~2.12.0", 47 | "eslint-plugin-babel": "^3.3.0", 48 | "eslint-plugin-ember-suave": "^1.0.0", 49 | "eslint-plugin-promise": "^3.4.0", 50 | "loader.js": "^4.2.3" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | module.exports = { 3 | "test_page": "tests/index.html?hidepassed", 4 | "disable_watching": true, 5 | "launch_in_ci": [ 6 | "PhantomJS" 7 | ], 8 | "launch_in_dev": [ 9 | "PhantomJS", 10 | "Chrome" 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "tests/index.html?hidepassed", 4 | "disable_watching": true, 5 | "launch_in_ci": [ 6 | "PhantomJS" 7 | ], 8 | "launch_in_dev": [ 9 | "PhantomJS", 10 | "Chrome" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | embertest: true 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "define", 10 | "console", 11 | "visit", 12 | "exists", 13 | "fillIn", 14 | "click", 15 | "keyEvent", 16 | "triggerEvent", 17 | "find", 18 | "findWithAssert", 19 | "wait", 20 | "DS", 21 | "andThen", 22 | "currentURL", 23 | "currentPath", 24 | "currentRouteName" 25 | ], 26 | "node": false, 27 | "browser": false, 28 | "boss": true, 29 | "curly": true, 30 | "debug": false, 31 | "devel": false, 32 | "eqeqeq": true, 33 | "evil": true, 34 | "forin": false, 35 | "immed": false, 36 | "laxbreak": false, 37 | "newcap": true, 38 | "noarg": true, 39 | "noempty": false, 40 | "nonew": false, 41 | "nomen": false, 42 | "onevar": false, 43 | "plusplus": false, 44 | "regexp": false, 45 | "undef": true, 46 | "sub": true, 47 | "strict": false, 48 | "white": false, 49 | "eqnull": true, 50 | "esnext": true, 51 | "unused": true 52 | } 53 | -------------------------------------------------------------------------------- /tests/acceptance/index-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import { module, test } from 'qunit'; 3 | import startApp from 'github-ui/tests/helpers/start-app'; 4 | import Pretender from 'pretender'; 5 | 6 | function json(obj, status=200) { 7 | return [status, { 'Content-Type' : 'text/json'}, JSON.stringify(obj)]; 8 | } 9 | 10 | let server; 11 | 12 | 13 | module('Acceptance | index', { 14 | beforeEach: function() { 15 | this.application = startApp(); 16 | server = new Pretender(function(){ 17 | this.get('https://api.github.com/orgs/:id', 18 | () => json({ 19 | id: 99, 20 | login: 'emberjs', 21 | name: 'Ember.js' 22 | })); 23 | 24 | this.get('https://api.github.com/orgs/:id/:repoid', 25 | () => json([{ 26 | id: 123, 27 | name: 'data' 28 | }])); 29 | 30 | this.get('https://api.github.com/repos/:id/:repoid', 31 | () => json({ 32 | id: 123, 33 | name: 'data' 34 | })); 35 | 36 | this.get('https://api.github.com/repos/:id/:repoid/issues', 37 | () => json([ 38 | {id: 1, title: 'Issue 1'}, 39 | {id: 2, title: 'Issue 2'} 40 | ])); 41 | 42 | this.get('https://api.github.com/repos/:id/:repoid/contributors', 43 | () => json([ 44 | {id: 1, login: 'contributor1'}, 45 | {id: 2, login: 'contributor2'} 46 | ])); 47 | }); 48 | }, 49 | 50 | afterEach: function() { 51 | server.shutdown(); 52 | Ember.run(this.application, 'destroy'); 53 | } 54 | }); 55 | 56 | test('visiting /index', function(assert) { 57 | visit('/'); 58 | 59 | andThen(function() { 60 | assert.equal(currentRouteName(), 'orgs', 'at orgs route'); 61 | }); 62 | 63 | click('a[href*="org/emberjs"]'); 64 | 65 | andThen(() => { 66 | assert.equal(currentURL(), '/org/emberjs/repos', 'at repos page'); 67 | }); 68 | 69 | click('a[href*="org/emberjs/data"]'); 70 | 71 | andThen(() => { 72 | assert.equal(currentURL(), '/org/emberjs/data/issues', 'at issues page'); 73 | assert.ok($('.issues li').length > 0, 'some issues'); 74 | }); 75 | 76 | click('a[href*="org/emberjs/data/contributors"]'); 77 | 78 | andThen(() => { 79 | assert.equal(currentURL(), '/org/emberjs/data/contributors', 'at contributors page'); 80 | assert.ok($('.contributors li').length > 0, 'some contributors'); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /tests/helpers/destroy-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default function destroyApp(application) { 4 | Ember.run(application, 'destroy'); 5 | } 6 | -------------------------------------------------------------------------------- /tests/helpers/module-for-acceptance.js: -------------------------------------------------------------------------------- 1 | import { module } from 'qunit'; 2 | import Ember from 'ember'; 3 | import startApp from '../helpers/start-app'; 4 | import destroyApp from '../helpers/destroy-app'; 5 | 6 | const { RSVP: { Promise } } = Ember; 7 | 8 | export default function(name, options = {}) { 9 | module(name, { 10 | beforeEach() { 11 | this.application = startApp(); 12 | 13 | if (options.beforeEach) { 14 | return options.beforeEach.apply(this, arguments); 15 | } 16 | }, 17 | 18 | afterEach() { 19 | let afterEach = options.afterEach && options.afterEach.apply(this, arguments); 20 | return Promise.resolve(afterEach).then(() => destroyApp(this.application)); 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /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 Ember from 'ember'; 2 | import Application from '../../app'; 3 | import config from '../../config/environment'; 4 | 5 | export default function startApp(attrs) { 6 | let attributes = Ember.merge({}, config.APP); 7 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; 8 | 9 | return Ember.run(() => { 10 | let application = Application.create(attributes); 11 | application.setupForTesting(); 12 | application.injectTestHelpers(); 13 | return application; 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | GithubUi 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/components/github-org-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForComponent, test } from 'ember-qunit'; 2 | import hbs from 'htmlbars-inline-precompile'; 3 | 4 | moduleForComponent('github-org', 'Integration | Component | github org', { 5 | integration: true 6 | }); 7 | 8 | test('it renders', function(assert) { 9 | assert.expect(2); 10 | 11 | // Set any properties with this.set('myProperty', 'value'); 12 | // Handle any actions with this.on('myAction', function(val) { ... }); 13 | 14 | this.render(hbs`{{github-org}}`); 15 | 16 | assert.equal(this.$().text().trim(), `[ 17 | Favorite 18 | ]`, 'Inline syntax, basic rendering'); 19 | 20 | // Template block usage: 21 | this.render(hbs` 22 | {{#github-org}} 23 | template block text 24 | {{/github-org}} 25 | `); 26 | 27 | assert.equal(this.$().text().trim(), `[ 28 | Favorite 29 | ]`, 'Block syntax, basic rendering'); 30 | }); 31 | 32 | test('bindings update data', function(assert) { 33 | 34 | // Set any properties with this.set('myProperty', 'value'); 35 | // Handle any actions with this.on('myAction', function(val) { ... }); 36 | 37 | assert.expect(2); 38 | 39 | const org = Ember.Object.create({ 40 | id: 'my-org', 41 | favorites: { 42 | items: [] 43 | } 44 | }); 45 | 46 | 47 | this.set('o', org); 48 | this.render(hbs`{{github-org org=o on-fav-clicked=on-fav-clicked}}`); 49 | 50 | assert.equal(Ember.$('.github-org a').text(), 'my-org'); 51 | 52 | 53 | // Ember.run(() => { 54 | // org.set('id', 'other'); 55 | // assert.equal(Ember.$('.github-org a').text(), 'other'); 56 | // }); 57 | 58 | let actionCount = 0; 59 | this.set('on-fav-clicked', function () { 60 | actionCount++; 61 | }); 62 | 63 | Ember.$('.github-org span').click(); 64 | 65 | assert.equal(actionCount, 1, 'Action was fired once'); 66 | }); 67 | -------------------------------------------------------------------------------- /tests/integration/components/github-repo-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForComponent, test } from 'ember-qunit'; 2 | import hbs from 'htmlbars-inline-precompile'; 3 | 4 | moduleForComponent('github-repo', 'Integration | Component | github repo', { 5 | integration: true 6 | }); 7 | 8 | test('it renders', function(assert) { 9 | assert.expect(2); 10 | 11 | // Set any properties with this.set('myProperty', 'value'); 12 | // Handle any actions with this.on('myAction', function(val) { ... }); 13 | 14 | const repo = Ember.Object.create({ 15 | forks_count: 32, 16 | watchers_count: 99, 17 | name: 'repoooo' 18 | }); 19 | this.set('repo', repo); 20 | 21 | this.render(hbs`{{github-repo repo=repo}}`); 22 | 23 | assert.equal(this.$().text().trim(), `repoooo 24 | 25 | 26 | ( 27 | Forks: 32 28 | Watchers: 99 29 | )`); 30 | 31 | // Template block usage: 32 | this.render(hbs` 33 | {{#github-repo repo=repo}} 34 | ABC 35 | {{/github-repo}} 36 | `); 37 | 38 | assert.equal(this.$().text().trim(), `ABC 39 | 40 | 41 | 42 | ( 43 | Forks: 32 44 | Watchers: 99 45 | )`); 46 | }); 47 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import { 3 | setResolver 4 | } from 'ember-qunit'; 5 | 6 | setResolver(resolver); 7 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/adapters/application-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('adapter:application', 'Unit | Adapter | application', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['serializer:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | var adapter = this.subject(); 11 | assert.ok(adapter); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/unit/helpers/nice-number-test.js: -------------------------------------------------------------------------------- 1 | import { niceNumber } from '../../../helpers/nice-number'; 2 | import { module, test } from 'qunit'; 3 | 4 | module('Unit | Helper | nice number'); 5 | 6 | // Replace this with your real tests. 7 | test('it works', function(assert) { 8 | assert.equal(niceNumber(), '', 'Empty'); 9 | assert.equal(niceNumber([42]), '42', 'A number < 1000'); 10 | assert.equal(niceNumber([4199]), '4.2K', 'A number > 1000'); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/models/org-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('org', 'Unit | Model | org', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var model = this.subject(); 10 | // var store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/unit/models/repo-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('repo', 'Unit | Model | repo', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var model = this.subject(); 10 | // var store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/unit/routes/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:index', 'Unit | Route | index', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org', 'Unit | Route | org', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/index', 'Unit | Route | org/index', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/notfound-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/notfound', 'Unit | Route | org/notfound', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/repo-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/repo', 'Unit | Route | org/repo', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/repo/contributors-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/repo/contributors', 'Unit | Route | org/repo/contributors', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/repo/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/repo/index', 'Unit | Route | org/repo/index', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/repo/issues-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/repo/issues', 'Unit | Route | org/repo/issues', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/org/repos-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:org/repos', 'Unit | Route | org/repos', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/routes/orgs-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:orgs', 'Unit | Route | orgs', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['controller:foo'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | var route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /tests/unit/serializers/application-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('application', 'Unit | Serializer | application', { 4 | // Specify the other units that are required for this test. 5 | needs: ['serializer:application'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it serializes records', function(assert) { 10 | var record = this.subject(); 11 | 12 | var serializedRecord = record.serialize(); 13 | 14 | assert.ok(serializedRecord); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/unit/services/favorites-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('service:favorites', 'Unit | Service | favorites', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['service:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | var service = this.subject(); 11 | assert.ok(service); 12 | }); 13 | -------------------------------------------------------------------------------- /tests/unit/utils/is-in-array-test.js: -------------------------------------------------------------------------------- 1 | import isInArray from 'github-ui/utils/is-in-array'; 2 | import { module, test } from 'qunit'; 3 | 4 | module('Unit | Utility | is in array'); 5 | 6 | // Replace this with your real tests. 7 | test('it works', function(assert) { 8 | 9 | const Type = Ember.Object.extend({ 10 | item: 6, 11 | list: [1,2,3], 12 | isItemInList: isInArray('item', 'list') 13 | }); 14 | 15 | const obj = Type.create(); 16 | 17 | assert.equal(obj.get('isItemInList'), false, 'Initial check for not-in-list'); 18 | 19 | obj.get('list').addObject(6); 20 | 21 | assert.equal(obj.get('isItemInList'), true, 'check for is-in-list'); 22 | 23 | obj.set('item', 52); 24 | 25 | assert.equal(obj.get('isItemInList'), false, 'After changing the item, is not in the list anymore'); 26 | }); 27 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrontendMasters/ember-github-ui/63ae8b4cba582c442a10670182b11d2505aa0f61/vendor/.gitkeep --------------------------------------------------------------------------------