From f5b47d07e33427dbe0e089a6f6620df74f7def7b Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Tue, 1 Mar 2016 14:08:08 -0500 Subject: [PATCH 1/4] Create route for revisions --- app/adapters/gist-revision.js | 8 ++++++++ app/gist/controller.js | 4 ++++ app/gist/edit/revision/route.js | 20 ++++++++++++++++++++ app/gist/edit/route.js | 2 +- app/models/gist-revision.js | 7 +------ app/router.js | 3 ++- app/serializers/gist-revision.js | 1 + app/serializers/gist.js | 16 ++++++++-------- 8 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 app/adapters/gist-revision.js create mode 100644 app/gist/edit/revision/route.js create mode 100644 app/serializers/gist-revision.js diff --git a/app/adapters/gist-revision.js b/app/adapters/gist-revision.js new file mode 100644 index 00000000..6f8487c6 --- /dev/null +++ b/app/adapters/gist-revision.js @@ -0,0 +1,8 @@ +import ApplicationAdapter from './application'; + +export default ApplicationAdapter.extend({ + urlForQuery: function(query) { + console.log(query); + return `${this.host}/gists/${query.gistId}/${query.revId}`; + } +}); diff --git a/app/gist/controller.js b/app/gist/controller.js index 90297f03..78bb1999 100644 --- a/app/gist/controller.js +++ b/app/gist/controller.js @@ -156,12 +156,16 @@ export default Ember.Controller.extend({ const numColumns = this.get('realNumColumns'); let j = 0; + const len = files.get('length'); for (let i = 1; i <= numColumns; ++i) { if (!this.getColumnFile(i)) { if (files) { j = 0; while (!this.isOpen(files.objectAt(j))) { j++; + if (j >= len) { + return; + } } let file = files.objectAt(j); if (file) { diff --git a/app/gist/edit/revision/route.js b/app/gist/edit/revision/route.js new file mode 100644 index 00000000..df8ea1fd --- /dev/null +++ b/app/gist/edit/revision/route.js @@ -0,0 +1,20 @@ +import Ember from "ember"; +import GistRoute from "../route"; + +export default GistRoute.extend({ + + controllerName: 'gist', + templateName: 'gist', + + model(params) { + this.get('store').unloadAll('gistFile'); + const gistParams = this.paramsFor('gist.edit'); + + return this.get('store').query('gist-revision', { + gistId: gistParams.gistId, + revId: params.revId + }).then((response) => { + return response.get('firstObject'); + }); + } +}); diff --git a/app/gist/edit/route.js b/app/gist/edit/route.js index 329a461e..38ed2450 100644 --- a/app/gist/edit/route.js +++ b/app/gist/edit/route.js @@ -5,7 +5,7 @@ export default GistRoute.extend({ model (params) { this.get('store').unloadAll('gistFile'); - return this.get('store').find('gist', params.id); + return this.get('store').find('gist', params.gistId); }, setupController() { diff --git a/app/models/gist-revision.js b/app/models/gist-revision.js index 32d8429a..65e409a4 100644 --- a/app/models/gist-revision.js +++ b/app/models/gist-revision.js @@ -1,6 +1 @@ -import DS from 'ember-data'; - -export default DS.Model.extend({ - committedAt: DS.attr('date'), - shortId: DS.attr('string') -}); \ No newline at end of file +export { default } from "./gist"; diff --git a/app/router.js b/app/router.js index 753aebe5..2e8e8da3 100644 --- a/app/router.js +++ b/app/router.js @@ -8,8 +8,9 @@ const Router = Ember.Router.extend({ Router.map(function() { this.route('gist', {path: '/'}, function() { this.route('new', {path: '/'}); - this.route('edit', {path: '/:id'}, function() { + this.route('edit', {path: '/:gistId'}, function() { this.route('copy'); + this.route('revision', {path: '/:revId'}); }); }); this.route('twiddles'); diff --git a/app/serializers/gist-revision.js b/app/serializers/gist-revision.js new file mode 100644 index 00000000..65e409a4 --- /dev/null +++ b/app/serializers/gist-revision.js @@ -0,0 +1 @@ +export { default } from "./gist"; diff --git a/app/serializers/gist.js b/app/serializers/gist.js index 60205a6f..b648a4d7 100644 --- a/app/serializers/gist.js +++ b/app/serializers/gist.js @@ -12,23 +12,23 @@ export default ApplicationSerializer.extend({ }, normalizeSingleResponse: function(store, primaryModelClass, payload, id, requestType) { - if (primaryModelClass.modelName === "gist") { - this.normalizeGist(payload, false); - } + this.normalizeGist(payload, false); return this._super(store, primaryModelClass, payload, id, requestType); }, normalizeArrayResponse: function(store, primaryModelClass, payload, id, requestType) { - if (primaryModelClass.modelName === "gist") { - payload.forEach(function(hash) { - this.normalizeGist(hash, true); - }.bind(this)); - } + payload.forEach(function(hash) { + this.normalizeGist(hash, true); + }.bind(this)); return this._super(store, primaryModelClass, payload, id, requestType); }, + normalizeQueryResponse: function(store, primaryModelClass, payload, id, requestType) { + return this._super(store, primaryModelClass, [payload], id, requestType); + }, + normalizeGist: function(payload, isArray) { this.normalizeFiles(payload, isArray); this.normalizeHistory(payload); From 9dfc6db7d867a6ca1b3dc73edc098e634eea007f Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Tue, 1 Mar 2016 16:53:55 -0500 Subject: [PATCH 2/4] Add a test --- app/adapters/gist-revision.js | 4 +- app/gist/edit/revision/route.js | 5 +- app/mirage/config.js | 5 + app/mirage/factories/gist-revision.js | 153 ++++++++++++++++++++++++++ tests/acceptance/git-revision-test.js | 34 ++++++ tests/helpers/run-gist.js | 13 +++ 6 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 app/mirage/factories/gist-revision.js create mode 100644 tests/acceptance/git-revision-test.js diff --git a/app/adapters/gist-revision.js b/app/adapters/gist-revision.js index 6f8487c6..a4bb73a0 100644 --- a/app/adapters/gist-revision.js +++ b/app/adapters/gist-revision.js @@ -2,7 +2,7 @@ import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ urlForQuery: function(query) { - console.log(query); - return `${this.host}/gists/${query.gistId}/${query.revId}`; + const host = this.host || ""; + return `${host}/gists/${query.gistId}/${query.revId}`; } }); diff --git a/app/gist/edit/revision/route.js b/app/gist/edit/revision/route.js index df8ea1fd..825e29b9 100644 --- a/app/gist/edit/revision/route.js +++ b/app/gist/edit/revision/route.js @@ -1,7 +1,6 @@ -import Ember from "ember"; -import GistRoute from "../route"; +import GistEditRoute from "../route"; -export default GistRoute.extend({ +export default GistEditRoute.extend({ controllerName: 'gist', templateName: 'gist', diff --git a/app/mirage/config.js b/app/mirage/config.js index 864d48ff..54df2979 100644 --- a/app/mirage/config.js +++ b/app/mirage/config.js @@ -14,6 +14,11 @@ export function testConfig() { return db.gists.find(id); }); + this.get('/gists/:id/:rev_id', function(db, request) { + let id = request.params.id; + return db["gist-revisions"].find(id); + }); + this.get('/user', function(db) { return db.users.find(1); }); diff --git a/app/mirage/factories/gist-revision.js b/app/mirage/factories/gist-revision.js new file mode 100644 index 00000000..05db42fe --- /dev/null +++ b/app/mirage/factories/gist-revision.js @@ -0,0 +1,153 @@ +/** + * This is a factory definition for a gist revision. + */ +import Mirage/*, {faker} */ from 'ember-cli-mirage'; + +export default Mirage.Factory.extend({ + url() { + return `https://api.github.com/gists/${this.id}/${this.revId}`; + }, + forks_url() { + return `https://api.github.com/gists/${this.id}/forks`; + }, + commits_url() { + return `https://api.github.com/gists/${this.id}/commits`; + }, + git_pull_url() { + return `https://gist.github.com/${this.id}.git`; + }, + git_push_url() { + return `https://gist.github.com/${this.id}.git`; + }, + html_url() { + return "https://gist.github.com/" + this.id; + }, + //files, + public: true, + created_at: "2015-07-23T22:30:30Z", + updated_at: "2015-07-23T22:49:45Z", + description: "New Twiddle", + comments: 0, + user: null, + comments_url() { + return `https://api.github.com/gists/${this.id}/comments`; + }, + //owner, + forks: [], + history: [] +}); + +/* Sample +{ + "url": "https://api.github.com/gists/a9d365962ab98c2e12cd/3421e6dde701325b5da67ba06dc150b7ad7e0547", + "forks_url": "https://api.github.com/gists/a9d365962ab98c2e12cd/forks", + "commits_url": "https://api.github.com/gists/a9d365962ab98c2e12cd/commits", + "id": "a9d365962ab98c2e12cd", + "git_pull_url": "https://gist.github.com/a9d365962ab98c2e12cd.git", + "git_push_url": "https://gist.github.com/a9d365962ab98c2e12cd.git", + "html_url": "https://gist.github.com/a9d365962ab98c2e12cd", + "files": { + "application.controller.js": { + "filename": "application.controller.js", + "type": "application/javascript", + "language": "JavaScript", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/a9d365962ab98c2e12cd/raw/a5591f634f02783af0de26c2a0799e2a6c2deb1d/application.controller.js", + "size": 247, + "truncated": false, + "content": "import Ember from 'ember';\nimport JsonProxy from '../json-proxy';\n\nexport default Ember.Controller.extend({\n appName: 'Ember Twiddle',\n \n init(...args) {\n this._super(...args);\n this.set('somevar', JsonProxy.build([1, 2, 3]));\n\t}\n});\n" + }, + "application.template.hbs": { + "filename": "application.template.hbs", + "type": "text/plain", + "language": "Handlebars", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/a9d365962ab98c2e12cd/raw/95de1498ec47fced63bb38e5a2ec69ef9f1620a5/application.template.hbs", + "size": 108, + "truncated": false, + "content": "

Welcome to {{appName}}

\n
\n\n
" + }, + "json-proxy.js": { + "filename": "json-proxy.js", + "type": "application/javascript", + "language": "JavaScript", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/a9d365962ab98c2e12cd/raw/7f218e6a2788227292b99fca84772fb4885a3287/json-proxy.js", + "size": 188, + "truncated": false, + "content": "import Ember from \"ember\";\n\nvar JsonProxy = Ember.ArrayProxy.extend({});\nJsonProxy.build = function(ary) {\n return Ember.ArrayProxy.create({ content: ary });\n};\n\nexport default JsonProxy;" + }, + "twiddle.json": { + "filename": "twiddle.json", + "type": "application/json", + "language": "JSON", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/a9d365962ab98c2e12cd/raw/87a00ec9acd16432438a70288db99b87371a9aeb/twiddle.json", + "size": 511, + "truncated": false, + "content": "{\n \"version\": \"0.6.0\",\n \"EmberENV\": {\n \"FEATURES\": {}\n },\n \"options\": {\n \"enable-testing\": false\n },\n \"dependencies\": {\n \"jquery\": \"https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js\",\n \"ember\": \"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.3.1/ember.debug.js\",\n \"ember-data\": \"https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/2.3.3/ember-data.js\",\n \"ember-template-compiler\": \"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.2.0/ember-template-compiler.js\"\n }\n}\n" + } + }, + "public": true, + "created_at": "2016-02-25T22:26:03Z", + "updated_at": "2016-02-25T22:28:29Z", + "description": "JsonProxy", + "comments": 0, + "user": null, + "comments_url": "https://api.github.com/gists/a9d365962ab98c2e12cd/comments", + "owner": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false + }, + "forks": [ + + ], + "history": [ + { + "user": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false + }, + "version": "3421e6dde701325b5da67ba06dc150b7ad7e0547", + "committed_at": "2016-02-25T22:26:03Z", + "change_status": { + "total": 42, + "additions": 42, + "deletions": 0 + }, + "url": "https://api.github.com/gists/a9d365962ab98c2e12cd/3421e6dde701325b5da67ba06dc150b7ad7e0547" + } + ], + "truncated": false +} + +*/ + + + diff --git a/tests/acceptance/git-revision-test.js b/tests/acceptance/git-revision-test.js new file mode 100644 index 00000000..1af50182 --- /dev/null +++ b/tests/acceptance/git-revision-test.js @@ -0,0 +1,34 @@ +import Ember from 'ember'; +import { module, test } from 'qunit'; +import startApp from 'ember-twiddle/tests/helpers/start-app'; + +module('Acceptance | gist-revision', { + beforeEach: function() { + this.application = startApp(); + }, + + afterEach: function() { + Ember.run(this.application, 'destroy'); + } +}); + +test('Able to load a previous revision of a gist', function(assert) { + + const files = [ + { + filename: "application.template.hbs", + content: "Hello, World!" + } + ]; + + runGist({ + type: "revision", + files + }); + + andThen(function() { + const outputDiv = 'div'; + + assert.equal(outputContents(outputDiv), 'Hello, World!', 'Previous version of a gist is displayed'); + }); +}); diff --git a/tests/helpers/run-gist.js b/tests/helpers/run-gist.js index 09fd02cc..b43ba932 100644 --- a/tests/helpers/run-gist.js +++ b/tests/helpers/run-gist.js @@ -11,6 +11,7 @@ export default function(app, options) { const gist_id = options.gist_id || "35de43cb81fc35ddffb2"; const commit = options.commit || "f354c6698b02fe3243656c8dc5aa0303cc7ae81c"; const initialRoute = options.initialRoute || "/"; + const isGitRevision = options.type === "revision"; let files = options.files || []; files.push({ @@ -43,6 +44,15 @@ export default function(app, options) { server.create('user', {login: login}); const owner = server.create('owner', {login: login}); + + if (isGitRevision) { + server.create('gist-revision', { + id: gist_id, + revId: commit, + owner: owner, + files: gistFiles + }); + } server.create('gist', { id: gist_id, owner: owner, @@ -50,6 +60,9 @@ export default function(app, options) { }); let url = "/" + gist_id; + if (isGitRevision) { + url += "/" + commit; + } if (initialRoute !== "/") { url += "?route=" + initialRoute; } From 4e152c97d88198809a82c4d4fd2b81e3a16411c9 Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Wed, 2 Mar 2016 09:44:05 -0500 Subject: [PATCH 3/4] Small refactor --- app/mirage/factories/gist-revision.js | 34 +++------------------------ app/serializers/gist-revision.js | 8 ++++++- app/serializers/gist.js | 4 ---- 3 files changed, 10 insertions(+), 36 deletions(-) diff --git a/app/mirage/factories/gist-revision.js b/app/mirage/factories/gist-revision.js index 05db42fe..a033db35 100644 --- a/app/mirage/factories/gist-revision.js +++ b/app/mirage/factories/gist-revision.js @@ -1,40 +1,12 @@ /** * This is a factory definition for a gist revision. */ -import Mirage/*, {faker} */ from 'ember-cli-mirage'; +import GistFactory from './gist'; -export default Mirage.Factory.extend({ +export default GistFactory.extend({ url() { return `https://api.github.com/gists/${this.id}/${this.revId}`; - }, - forks_url() { - return `https://api.github.com/gists/${this.id}/forks`; - }, - commits_url() { - return `https://api.github.com/gists/${this.id}/commits`; - }, - git_pull_url() { - return `https://gist.github.com/${this.id}.git`; - }, - git_push_url() { - return `https://gist.github.com/${this.id}.git`; - }, - html_url() { - return "https://gist.github.com/" + this.id; - }, - //files, - public: true, - created_at: "2015-07-23T22:30:30Z", - updated_at: "2015-07-23T22:49:45Z", - description: "New Twiddle", - comments: 0, - user: null, - comments_url() { - return `https://api.github.com/gists/${this.id}/comments`; - }, - //owner, - forks: [], - history: [] + } }); /* Sample diff --git a/app/serializers/gist-revision.js b/app/serializers/gist-revision.js index 65e409a4..11976400 100644 --- a/app/serializers/gist-revision.js +++ b/app/serializers/gist-revision.js @@ -1 +1,7 @@ -export { default } from "./gist"; +import GistSerializer from "./gist"; + +export default GistSerializer.extend({ + normalizeQueryResponse: function(store, primaryModelClass, payload, id, requestType) { + return this._super(store, primaryModelClass, [payload], id, requestType); + } +}); diff --git a/app/serializers/gist.js b/app/serializers/gist.js index b648a4d7..22455052 100644 --- a/app/serializers/gist.js +++ b/app/serializers/gist.js @@ -25,10 +25,6 @@ export default ApplicationSerializer.extend({ return this._super(store, primaryModelClass, payload, id, requestType); }, - normalizeQueryResponse: function(store, primaryModelClass, payload, id, requestType) { - return this._super(store, primaryModelClass, [payload], id, requestType); - }, - normalizeGist: function(payload, isArray) { this.normalizeFiles(payload, isArray); this.normalizeHistory(payload); From 0883c3b4ad422e5d86322cfa10e2cb64e20df29d Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Thu, 3 Mar 2016 09:41:07 -0500 Subject: [PATCH 4/4] Create new helper specifically for running a revision --- tests/.jshintrc | 1 + tests/acceptance/git-revision-test.js | 5 +---- tests/helpers/run-revision.js | 14 ++++++++++++++ tests/test-helper.js | 3 ++- 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 tests/helpers/run-revision.js diff --git a/tests/.jshintrc b/tests/.jshintrc index 46f62d09..2dce0546 100644 --- a/tests/.jshintrc +++ b/tests/.jshintrc @@ -24,6 +24,7 @@ "currentPath", "currentRouteName", "runGist", + "runRevision", "waitForLoadedIFrame", "outputPane", "outputContents" diff --git a/tests/acceptance/git-revision-test.js b/tests/acceptance/git-revision-test.js index 1af50182..6702717a 100644 --- a/tests/acceptance/git-revision-test.js +++ b/tests/acceptance/git-revision-test.js @@ -21,10 +21,7 @@ test('Able to load a previous revision of a gist', function(assert) { } ]; - runGist({ - type: "revision", - files - }); + runRevision(files); andThen(function() { const outputDiv = 'div'; diff --git a/tests/helpers/run-revision.js b/tests/helpers/run-revision.js new file mode 100644 index 00000000..883e8cc8 --- /dev/null +++ b/tests/helpers/run-revision.js @@ -0,0 +1,14 @@ +import Ember from "ember"; +import runGist from "./run-gist"; + +const { isArray } = Ember; + +export default function(app, options) { + if (isArray(options)) { + options = {files: options}; + } + + options.type = "revision"; + + return runGist(app, options); +} diff --git a/tests/test-helper.js b/tests/test-helper.js index 7bd7b04f..677ae8c5 100644 --- a/tests/test-helper.js +++ b/tests/test-helper.js @@ -4,6 +4,7 @@ import { setResolver } from 'ember-qunit'; import runGist from "./helpers/run-gist"; +import runRevision from "./helpers/run-revision"; import waitForLoadedIFrame from './helpers/wait-for-loaded-iframe'; setResolver(resolver); @@ -20,5 +21,5 @@ Ember.Test.registerHelper('outputContents', function(app, selector) { }); Ember.Test.registerAsyncHelper('runGist', runGist); - +Ember.Test.registerAsyncHelper('runRevision', runRevision); Ember.Test.registerAsyncHelper('waitForLoadedIFrame', waitForLoadedIFrame);