Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet.
Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc.
Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor.
Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit.
',
17 | thumbnailUrl: '/images/thug-life-hamster.jpg',
18 | previousArticle: 1,
19 | nextArticle: 3
20 | },
21 | {
22 | id: 3,
23 | header: 'Angular 2.0 will be renamed to RoundedScript!',
24 | body: 'Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui.
Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet.
Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor.
',
25 | thumbnailUrl: '/images/concentric-maze.jpg',
26 | previousArticle: 2,
27 | nextArticle: 4
28 | },
29 | {
30 | id: 4,
31 | header: 'Breaking: HTMLBars are the parents',
32 | body: 'Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui.
Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet.
Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim.
Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui.
Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet.
Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus. Ut ultrices ultrices enim.
Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor.
',
41 | thumbnailUrl: '/images/gorbipuff-coding.jpg',
42 | previousArticle: 4,
43 | nextArticle: null
44 | },
45 | ]
46 |
47 |
48 | articlesRouter.get('/', function(req, res) {
49 | setTimeout(function() {
50 | res.send({ 'articles': articlesFixtures });
51 | }, 500);
52 | });
53 |
54 | articlesRouter.post('/', function(req, res) {
55 | res.status(201).end();
56 | });
57 |
58 | articlesRouter.get('/:id', function(req, res) {
59 | var article = articlesFixtures.filter(function(art) { return art.id == req.params.id })[0];
60 | if (article) {
61 | setTimeout(function() {
62 | res.send({ 'articles': article });
63 | }, 500);
64 | } else {
65 | res.status(404).end();
66 | }
67 | });
68 |
69 | articlesRouter.put('/:id', function(req, res) {
70 | res.send({
71 | 'articles': {
72 | id: req.params.id
73 | }
74 | });
75 | });
76 |
77 | articlesRouter.delete('/:id', function(req, res) {
78 | res.status(204).end();
79 | });
80 |
81 | app.use('/api/articles', articlesRouter);
82 | };
83 |
--------------------------------------------------------------------------------
/testem.json:
--------------------------------------------------------------------------------
1 | {
2 | "framework": "qunit",
3 | "test_page": "tests/index.html?hidepassed",
4 | "launch_in_ci": [
5 | "PhantomJS"
6 | ],
7 | "launch_in_dev": [
8 | "PhantomJS",
9 | "Chrome"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/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": false,
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 | }
52 |
--------------------------------------------------------------------------------
/tests/helpers/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember/resolver';
2 | import config from '../../config/environment';
3 |
4 | var 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 Router from '../../router';
4 | import config from '../../config/environment';
5 |
6 | export default function startApp(attrs) {
7 | var application;
8 |
9 | var attributes = Ember.merge({}, config.APP);
10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
11 |
12 | Ember.run(function() {
13 | application = Application.create(attributes);
14 | application.setupForTesting();
15 | application.injectTestHelpers();
16 | });
17 |
18 | return application;
19 | }
20 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | MobilePatterns 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 |
22 | {{content-for 'body'}}
23 | {{content-for 'test-body'}}
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for 'body-footer'}}
31 | {{content-for 'test-body-footer'}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import resolver from './helpers/resolver';
2 | import {
3 | setResolver
4 | } from 'ember-qunit';
5 |
6 | setResolver(resolver);
7 |
--------------------------------------------------------------------------------
/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cibernox/mobile-patterns/1041e661a802ed31bb714974aa79f77d1ef49f3b/tests/unit/.gitkeep
--------------------------------------------------------------------------------
/tests/unit/adapters/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('adapter:application', 'ApplicationAdapter', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['serializer:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var adapter = this.subject();
14 | assert.assert.ok(adapter);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/components/animated-card-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('animated-card', 'AnimatedCardComponent', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(2);
13 |
14 | // creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | // appends the component to the page
19 | this.render();
20 | assert.equal(component._state, 'inDOM');
21 | });
22 |
--------------------------------------------------------------------------------
/tests/unit/components/animated-deck-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('animated-deck', 'AnimatedDeckComponent', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | needs: ['component:animated-card']
10 | });
11 |
12 | test('it renders', function(assert) {
13 | assert.expect(2);
14 |
15 | // creates the component instance
16 | var component = this.subject();
17 | assert.equal(component._state, 'preRender');
18 |
19 | // appends the component to the page
20 | this.render();
21 | assert.equal(component._state, 'inDOM');
22 | });
23 |
--------------------------------------------------------------------------------
/tests/unit/components/content-overlay-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('content-overlay', 'ContentOverlayComponent', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(2);
13 |
14 | // creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | // appends the component to the page
19 | this.render();
20 | assert.equal(component._state, 'inDOM');
21 | });
22 |
--------------------------------------------------------------------------------
/tests/unit/components/toggle-menu-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('toggle-menu', 'ToggleMenuComponent', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(2);
13 |
14 | // creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | // appends the component to the page
19 | this.render();
20 | assert.equal(component._state, 'inDOM');
21 | });
22 |
--------------------------------------------------------------------------------
/tests/unit/controllers/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('controller:application', 'ApplicationController', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var controller = this.subject();
14 | assert.ok(controller);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/controllers/news/show-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('controller:news/show', 'NewsShowController', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var controller = this.subject();
14 | assert.ok(controller);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/initializers/offline-support-test.js:
--------------------------------------------------------------------------------
1 | import { test, module } from 'ember-qunit';
2 | import Ember from 'ember';
3 | import { initialize } from 'mobile-patterns/initializers/offline-support';
4 |
5 | var container, application;
6 |
7 | module('OfflineSupportInitializer', {
8 | setup: function() {
9 | Ember.run(function() {
10 | application = Ember.Application.create();
11 | container = application.__container__;
12 | application.deferReadiness();
13 | });
14 | }
15 | });
16 |
17 | // Replace this with your real tests.
18 | test('it works', function(assert) {
19 | initialize(container, application);
20 |
21 | // you would normally confirm the results of the initializer here
22 | assert.ok(true);
23 | });
24 |
25 |
--------------------------------------------------------------------------------
/tests/unit/mixins/gesture-listener-test.js:
--------------------------------------------------------------------------------
1 | import { test, module } from 'ember-qunit';
2 | import Ember from 'ember';
3 | import GestureListenerMixin from 'mobile-patterns/mixins/gesture-listener';
4 |
5 | module('GestureListenerMixin');
6 |
7 | // Replace this with your real tests.
8 | test('it works', function(assert) {
9 | var GestureListenerObject = Ember.Object.extend(GestureListenerMixin);
10 | var subject = GestureListenerObject.create();
11 | assert.ok(subject);
12 | });
13 |
--------------------------------------------------------------------------------
/tests/unit/models/article-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForModel,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForModel('article', 'Article', {
7 | // Specify the other units that are required for this test.
8 | needs: []
9 | });
10 |
11 |
--------------------------------------------------------------------------------
/tests/unit/routes/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:application', 'ApplicationRoute', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/tests/unit/routes/news-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:news', 'NewsRoute', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/tests/unit/services/browser-detector-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('service:browser-detector', 'BrowserDetectorService', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['service:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var service = this.subject();
14 | assert.ok(service);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/services/config-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('service:config', 'ConfigService', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['service:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var service = this.subject();
14 | assert.ok(service);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/services/network-monitor-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('service:network-monitor', 'NetworkMonitorService', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['service:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var service = this.subject();
14 | assert.ok(service);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/utils/gesture-test.js:
--------------------------------------------------------------------------------
1 | import { test, module } from 'ember-qunit';
2 | import Gesture from 'mobile-patterns/utils/gesture';
3 |
4 | var gesture;
5 |
6 | module('Gesture - constructor');
7 |
8 | test('sets the proper default values', function(assert) {
9 | gesture = new Gesture({abc: 123});
10 | assert.deepEqual(gesture.events, [], 'it has no events');
11 | assert.ok(!gesture.defaultPrevented, 'defaultPrevented is false');
12 | assert.ok(!gesture.propagationStopped, 'propagationStopped is false');
13 | assert.equal(gesture.abc, 123, 'Any property given in the initializer is setted');
14 | });
15 |
16 | module('Gesture - push');
17 |
18 | test('appends the given event to the gesture', function(assert) {
19 | gesture = new Gesture();
20 |
21 | assert.equal(gesture.events.length, 0);
22 | assert.equal(gesture.last, null);
23 | gesture.push({timeStamp: 123, touches: [{pageX: 1, pageY: 2}]});
24 | assert.equal(gesture.events.length, 1);
25 | assert.deepEqual(gesture.last, { timeStamp: 123, x: 1, y: 2 });
26 | });
27 |
28 | test('calls preventDefault on the given element when defaultPrevented is set to true', function(assert) {
29 | gesture = new Gesture();
30 | var evtNotPrevented = {
31 | timeStamp: 123,
32 | touches: [{ pageX: 1, pageY: 2 }],
33 | preventDefault: function() {
34 | assert.ok(false, 'This event must not be prevented');
35 | }
36 | };
37 | gesture.push(evtNotPrevented);
38 |
39 | gesture.defaultPrevented = true;
40 | var evtPrevented = {
41 | timeStamp: 123,
42 | touches: [{ pageX: 1, pageY: 2 }],
43 | preventDefault: function() {
44 | assert.ok(true, 'This event must be prevented');
45 | }
46 | };
47 | gesture.push(evtPrevented);
48 | });
49 |
50 | test('calls stopPropagation on the given element when propagationStopped is set to true', function(assert) {
51 | gesture = new Gesture();
52 | var evtNotStopped = {
53 | timeStamp: 123,
54 | touches: [{ pageX: 1, pageY: 2 }],
55 | stopPropagation: function() {
56 | assert.ok(false, 'The propagation of this event must not be stopped');
57 | }
58 | };
59 | gesture.push(evtNotStopped);
60 |
61 | gesture.propagationStopped = true;
62 | var evtStopped = {
63 | timeStamp: 123,
64 | touches: [{ pageX: 1, pageY: 2 }],
65 | stopPropagation: function() {
66 | assert.ok(true, 'The propagation of this event must be stopped');
67 | }
68 | };
69 | gesture.push(evtStopped);
70 | });
71 |
72 | test('returns the gesture so we can chain calls', function(assert) {
73 | gesture = new Gesture();
74 | var returnValue = gesture.push({timeStamp: 123, touches: [{pageX: 1, pageY: 2}]});
75 | assert.equal(returnValue, gesture, 'push returns the gesture itself');
76 | });
77 |
78 | module('Gesture - first and last', {
79 | setup: function() {
80 | gesture = new Gesture();
81 | gesture.push({ timeStamp: 123, touches: [{ pageX: 1, pageY: 2 }] });
82 | gesture.push({ timeStamp: 234, touches: [{ pageX: 5, pageY: 6 }] });
83 | }
84 | });
85 |
86 | test('first contains the first captured event', function(assert) {
87 | assert.deepEqual(gesture.first, { timeStamp: 123, x: 1, y: 2 });
88 | });
89 |
90 | test('last contains the last captured event', function(assert) {
91 | assert.deepEqual(gesture.last, { timeStamp: 234, x: 5, y: 6 });
92 | });
93 |
94 | module('Gesture - coordinates', {
95 | setup: function() {
96 | gesture = new Gesture();
97 | gesture.push({ timeStamp: 123, touches: [{ pageX: 1, pageY: 2 }] });
98 | gesture.push({ timeStamp: 234, touches: [{ pageX: 5, pageY: 6 }] });
99 | }
100 | });
101 |
102 | test('x contains the pageX of the last event', function(assert) {
103 | assert.equal(gesture.x, 5);
104 | });
105 |
106 | test('y contains the pageY of the last event', function(assert) {
107 | assert.equal(gesture.y, 6);
108 | });
109 |
110 | test('initX contains the pageX of the first event', function(assert) {
111 | assert.equal(gesture.initX, 1);
112 | });
113 |
114 | test('initY contains the pageX of the first event', function(assert) {
115 | assert.equal(gesture.initY, 2);
116 | });
117 |
118 | module('Gesture - deltas', {
119 | setup: function() {
120 | gesture = new Gesture();
121 | gesture.push({ touches: [{pageX: 100, pageY: 250}], timeStamp: 1419263004600 });
122 | gesture.push({ touches: [{pageX: 110, pageY: 270}], timeStamp: 1419263004610 });
123 | gesture.push({ touches: [{pageX: 120, pageY: 290}], timeStamp: 1419263004620 });
124 | }
125 | });
126 |
127 | test('deltaX contains the X delta between the beginning and the current point of the gesture', function(assert) {
128 | assert.equal(gesture.deltaX, 20);
129 | });
130 |
131 | test('deltaY contains the X delta between the beginning and the current point of the gesture', function(assert) {
132 | assert.equal(gesture.deltaY, 40);
133 | });
134 |
135 | test('delta contains the distance in px between the beginning and the current point of the gesture', function(assert) {
136 | assert.ok(gesture.delta - 44.731359 < 0.0001, 'Calculates the delta using Pythagoras theorem');
137 | });
138 |
139 | module('Gesture - direction');
140 |
141 | test('returns the direction of the gesture in degrees (0-360)', function(assert) {
142 | // Gesture to the 1st cuandrant
143 | var gesture1 = new Gesture();
144 | gesture1.push({ touches: [{pageX: 100, pageY: 270}] });
145 | gesture1.push({ touches: [{pageX: 110, pageY: 250}] });
146 | assert.equal(gesture1.direction, 26.56505117707799);
147 |
148 | // Gesture to the 2st cuandrant
149 | var gesture2 = new Gesture();
150 | gesture2.push({ touches: [{pageX: 100, pageY: 250}] });
151 | gesture2.push({ touches: [{pageX: 110, pageY: 270}] });
152 | assert.equal(gesture2.direction, 153.43494882292202);
153 |
154 | // Gesture to the 3rd cuandrant
155 | var gesture3 = new Gesture();
156 | gesture3.push({ touches: [{pageX: 110, pageY: 250}] });
157 | gesture3.push({ touches: [{pageX: 100, pageY: 270}] });
158 | assert.equal(gesture3.direction, 206.56505117707799);
159 |
160 | // Gesture to the 4th cuandrant
161 | var gesture4 = new Gesture();
162 | gesture4.push({ touches: [{pageX: 110, pageY: 270}] });
163 | gesture4.push({ touches: [{pageX: 100, pageY: 250}] });
164 | assert.equal(gesture4.direction, 333.43494882292202);
165 | });
166 |
167 | module('Gesture - isHorizontal');
168 |
169 | test('returns true if the gesture is horizontal with a error margin smaller than the given one', function(assert) {
170 | var gesture = new Gesture();
171 | gesture.push({ touches: [{pageX: 100, pageY: 250}] });
172 | gesture.push({ touches: [{pageX: 140, pageY: 255}] });
173 | gesture.push({ touches: [{pageX: 180, pageY: 260}] });
174 | assert.ok(gesture.isHorizontal(), 'The gesture is horizontal with an error margin of 15deg'); // The error margin defalts to ± 15°
175 | assert.ok(!gesture.isHorizontal(2), 'The gesture is not horizontal with an error margin of 2deg'); // The error margin is set to ± 2°
176 |
177 | var gesture2 = new Gesture();
178 | gesture2.push({ touches: [{pageX: 250, pageY: 100}] });
179 | gesture2.push({ touches: [{pageX: 255, pageY: 140}] });
180 | gesture2.push({ touches: [{pageX: 260, pageY: 180}] });
181 | assert.ok(!gesture2.isHorizontal(), 'The new gesture is not horizontal');
182 | });
183 |
184 | module('Gesture - speed', {
185 | setup: function() {
186 | gesture = new Gesture();
187 | gesture.push({ touches: [{pageX: 100, pageY: 250}], timeStamp: 1419263004600 });
188 | gesture.push({ touches: [{pageX: 110, pageY: 270}], timeStamp: 1419263004610 });
189 | gesture.push({ touches: [{pageX: 120, pageY: 290}], timeStamp: 1419263004620 });
190 | }
191 | });
192 |
193 | test('speedX contains the speed of the gesture in the X axis', function(assert) {
194 | assert.equal(gesture.speedX, 1000);
195 | });
196 |
197 | test('speedY contains the speed of the gesture in the X axis', function(assert) {
198 | assert.equal(gesture.speedY, 2000);
199 | });
200 |
201 | module('Gesture - duration', {
202 | setup: function() {
203 | gesture = new Gesture();
204 | gesture.push({ touches: [{pageX: 100, pageY: 250}], timeStamp: 1419263004600 });
205 | gesture.push({ touches: [{pageX: 110, pageY: 270}], timeStamp: 1419263004610 });
206 | gesture.push({ touches: [{pageX: 120, pageY: 290}], timeStamp: 1419263004620 });
207 | }
208 | });
209 |
210 | test('contains the duration of the gesture in milliseconds', function(assert) {
211 | assert.equal(gesture.duration, 20);
212 | });
213 |
214 | module('Gesture - clear', {
215 | setup: function() {
216 | gesture = new Gesture({abc: 123});
217 | gesture.push({ touches: [{pageX: 100, pageY: 250}], timeStamp: 1419263004600 });
218 | gesture.push({ touches: [{pageX: 110, pageY: 270}], timeStamp: 1419263004610 });
219 | gesture.push({ touches: [{pageX: 120, pageY: 290}], timeStamp: 1419263004620 });
220 | gesture.abc = 234;
221 | }
222 | });
223 |
224 | test('returns the gesture to the state it had when it was initialized', function(assert) {
225 | gesture.clear();
226 | assert.deepEqual(gesture.events, [], 'There is not events');
227 | assert.ok(!gesture.defaultPrevented);
228 | assert.ok(!gesture.propagationStopped);
229 | assert.ok(!gesture.first, null, 'There is no first event');
230 | assert.ok(!gesture.last, null, 'There is no last event');
231 | assert.equal(gesture.abc, 123, 'Other properties are restored l');
232 | });
233 |
234 | // test('`Gesture#preventDefault` sets the defaultPrevented flag to true if the given condition is met', function(assert) {
235 | // var gesture = new Gesture();
236 | // assert.ok(!gesture.defaultPrevented, 'Newly created gestures are not default prevented');
237 | // gesture.preventDefault();
238 | // assert.ok(gesture.defaultPrevented, 'When not condition is passed, preventDefault() sets the the flag to true');
239 |
240 | // var gesture2 = new Gesture();
241 | // var conditionFn = function(g) {
242 | // assert.equal(g.constructor, Gesture, 'The condition function receives the gesture');
243 | // return true;
244 | // };
245 | // var falseyConditionFn = function(g) {
246 | // return false;
247 | // };
248 | // assert.ok(!gesture2.preventDefault(falseyConditionFn), 'preventDefault() returns false if the gesture was not prevented');
249 | // assert.ok(!gesture2.defaultPrevented, 'When the condition function returns false, the gesture is not prevented');
250 | // assert.ok(gesture2.preventDefault(conditionFn), 'preventDefault() returns true if the gesture was prevented');
251 | // assert.ok(gesture2.defaultPrevented, 'When the condition function returns true, the gesture is prevented');
252 |
253 | // var gesture3 = new Gesture();
254 | // gesture3.preventDefault('given-context', function(g) {
255 | // assert.equal(this, 'given-context', 'Inside the function, the context has been bound correctly');
256 | // assert.equal(g.constructor, Gesture, 'The condition function receives the gesture');
257 | // });
258 | // });
259 |
260 | // test('`Gesture#stopPropagation` sets the propagationStopped flag to true if the given condition is met', function(assert) {
261 | // var gesture = new Gesture();
262 | // assert.ok(!gesture.propagationStopped, 'Newly created gestures have not its propagation stopped');
263 | // gesture.stopPropagation();
264 | // assert.ok(gesture.propagationStopped, 'When not condition is passed, stopPropagation() sets the flag to true');
265 |
266 | // var gesture2 = new Gesture();
267 | // var conditionFn = function(g) {
268 | // assert.equal(g.constructor, Gesture, 'The condition function receives the gesture');
269 | // return true;
270 | // };
271 | // var falseyConditionFn = function(g) {
272 | // return false;
273 | // };
274 | // assert.ok(!gesture2.stopPropagation(falseyConditionFn), 'stopPropagation() returns false if the gesture propagation was not stopped');
275 | // assert.ok(!gesture2.propagationStopped, 'When the condition function returns false, the gesture ipropagation s not stopped');
276 | // assert.ok(gesture2.stopPropagation(conditionFn), 'stopPropagation() returns true if the gesture propagation was stopped');
277 | // assert.ok(gesture2.propagationStopped, 'When the condition function returns true, the gesture propagation is stopped');
278 |
279 | // var gesture3 = new Gesture();
280 | // gesture3.stopPropagation('given-context', function(g) {
281 | // assert.equal(this, 'given-context', 'Inside the function, the context has been bound correctly');
282 | // assert.equal(g.constructor, Gesture, 'The condition function receives the gesture');
283 | // });
284 | // });
285 |
286 | // test('`Gesture#adquire` sets both `defaultPrevented` and `propagationStopped` to true if the given condition is met', function(assert) {
287 | // var gesture = new Gesture();
288 | // gesture.adquire();
289 | // assert.ok(gesture.defaultPrevented, 'When not condition is passed, adquire() sets the flags to true');
290 | // assert.ok(gesture.propagationStopped, 'When not condition is passed, adquire() sets the flags to true');
291 |
292 | // var gesture2 = new Gesture();
293 | // var counter = 0;
294 | // var conditionFn = function(g) {
295 | // assert.equal(g.constructor, Gesture, 'The condition function receives the gesture');
296 | // assert.ok(++counter < 2, 'This method is only invoked once');
297 | // return true;
298 | // };
299 | // var falseyConditionFn = function(g) {
300 | // return false;
301 | // };
302 | // assert.ok(!gesture2.adquire(falseyConditionFn), 'adquire() returns false if the gesture propagation was not stopped');
303 | // assert.ok(!gesture2.defaultPrevented, 'When the condition function returns false, the gesture is default not prevented');
304 | // assert.ok(!gesture2.propagationStopped, 'When the condition function returns false, the gesture propagation is not stopped');
305 | // assert.ok(gesture2.adquire(conditionFn), 'adquire() returns true if the gesture propagation was stopped');
306 | // assert.ok(gesture2.defaultPrevented, 'When the condition function returns true, the gesture is default prevented');
307 | // assert.ok(gesture2.propagationStopped, 'When the condition function returns true, the gesture propagation is stopped');
308 |
309 | // var gesture3 = new Gesture();
310 | // gesture3.adquire('given-context', function(g) {
311 | // assert.equal(this, 'given-context', 'Inside the function, the context has been bound correctly');
312 | // assert.equal(g.constructor, Gesture, 'The condition function receives the gesture');
313 | // });
314 | // });
315 |
--------------------------------------------------------------------------------
/tests/unit/utils/swipe-gesture-test.js:
--------------------------------------------------------------------------------
1 | import { test, module } from 'ember-qunit';
2 | import SwipeGesture from 'mobile-patterns/utils/swipe-gesture';
3 |
4 | var swipe;
5 |
6 | module('SwipeGesture - constructor');
7 |
8 | test('initializes the default values', function(assert) {
9 | swipe = new SwipeGesture();
10 | assert.equal(swipe.minLength, 20, 'minLength is 20 by default');
11 | assert.equal(swipe.warnLength, 10, 'warnLength is 10 by default');
12 | assert.equal(swipe.errorMargin, 20, 'errorMargin is 10 by default');
13 | assert.ok(swipe.exclusive, 'exclusive is true by default');
14 | assert.ok(!swipe.defaultPrevented, 'defaultPrevented is false by default');
15 | assert.ok(!swipe.propagationStopped, 'propagationStopped is false by default');
16 | });
17 |
18 | module('SwipeGesture - push');
19 |
20 | test('returns the swipe so we can chain calls', function(assert) {
21 | swipe = new SwipeGesture();
22 | var returnValue = swipe.push({timeStamp: 123, touches: [{pageX: 1, pageY: 2}]});
23 | assert.equal(returnValue, swipe, 'push returns the swipe gesture itself');
24 | });
25 |
26 | module('SwipeGesture - warn event');
27 |
28 | test('is fired once for horizontal gestures when the warn length is surpassed', function(assert) {
29 | assert.expect(2);
30 | var eventsCount = 0;
31 | swipe = new SwipeGesture();
32 |
33 | swipe.on('warn', function(gesture) {
34 | assert.equal(++eventsCount, 1, 'The warn event is fired once');
35 | assert.equal(gesture.x, 10, 'The gesture contains the last event');
36 | setTimeout(assert.async, 1);
37 | });
38 |
39 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
40 | swipe.push({ timeStamp: 234, touches: [{ pageX: 5, pageY: 10 }] });
41 | swipe.push({ timeStamp: 345, touches: [{ pageX: 9, pageY: 10 }] });
42 | swipe.push({ timeStamp: 456, touches: [{ pageX: 10, pageY: 10 }] });
43 | swipe.push({ timeStamp: 567, touches: [{ pageX: 15, pageY: 10 }] });
44 | });
45 |
46 | test('is never fired if the gesture is not horizontal', function(assert) {
47 | assert.expect(0);
48 | swipe = new SwipeGesture();
49 |
50 | swipe.on('warn', function(gesture) {
51 | assert.ok(false, 'no warn event is emitted');
52 | });
53 |
54 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
55 | swipe.push({ timeStamp: 234, touches: [{ pageX: 5, pageY: 20 }] });
56 | swipe.push({ timeStamp: 345, touches: [{ pageX: 9, pageY: 30 }] });
57 | swipe.push({ timeStamp: 456, touches: [{ pageX: 10, pageY: 40 }] });
58 | swipe.push({ timeStamp: 567, touches: [{ pageX: 15, pageY: 50 }] });
59 | setTimeout(assert.async, 1);
60 | });
61 |
62 | test('if the gesture is not horizontal by the time the warnLength is surpassed but it gets corrected before surpassing the minLength the event is fired', function(assert) {
63 | assert.expect(2);
64 | swipe = new SwipeGesture();
65 |
66 | swipe.on('warn', function(gesture) {
67 | assert.ok(true, 'the event is emitted');
68 | assert.equal(gesture.x, 15, 'The gesture contains the last event');
69 | });
70 |
71 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
72 | swipe.push({ timeStamp: 234, touches: [{ pageX: 5, pageY: 20 }] });
73 | swipe.push({ timeStamp: 345, touches: [{ pageX: 9, pageY: 30 }] });
74 | swipe.push({ timeStamp: 456, touches: [{ pageX: 10, pageY: 40 }] });
75 | swipe.push({ timeStamp: 567, touches: [{ pageX: 15, pageY: 10 }] });
76 | setTimeout(assert.async, 1);
77 | });
78 |
79 | module('SwipeGesture - start event');
80 |
81 | test('is fired once for horizontal gestures when the minimum length is surpassed', function(assert) {
82 | assert.expect(2);
83 | var eventsCount = 0;
84 | swipe = new SwipeGesture();
85 |
86 | swipe.on('start', function(gesture) {
87 | assert.equal(++eventsCount, 1, 'The start event is fired once');
88 | assert.equal(gesture.x, 30, 'The gesture contains the last event');
89 | setTimeout(assert.async, 1);
90 | });
91 |
92 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
93 | swipe.push({ timeStamp: 234, touches: [{ pageX: 10, pageY: 10 }] });
94 | swipe.push({ timeStamp: 345, touches: [{ pageX: 19, pageY: 10 }] });
95 | swipe.push({ timeStamp: 456, touches: [{ pageX: 30, pageY: 10 }] });
96 | swipe.push({ timeStamp: 567, touches: [{ pageX: 35, pageY: 10 }] });
97 | });
98 |
99 | test('is never fired if the gesture is not horizontal', function(assert) {
100 | assert.expect(0);
101 | swipe = new SwipeGesture();
102 |
103 | swipe.on('start', function(gesture) {
104 | assert.ok(false, 'no start event is emitted');
105 | });
106 |
107 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
108 | swipe.push({ timeStamp: 234, touches: [{ pageX: 10, pageY: 20 }] });
109 | swipe.push({ timeStamp: 345, touches: [{ pageX: 19, pageY: 30 }] });
110 | swipe.push({ timeStamp: 456, touches: [{ pageX: 30, pageY: 40 }] });
111 | swipe.push({ timeStamp: 567, touches: [{ pageX: 35, pageY: 50 }] });
112 | setTimeout(assert.async, 1);
113 | });
114 |
115 | test('if the gesture is not horizontal by the time the minLength is surpassed, the event is not emitted even if the gesture becomes horizontal', function(assert) {
116 | assert.expect(0);
117 | swipe = new SwipeGesture();
118 |
119 | swipe.on('start', function(gesture) {
120 | assert.ok(false, 'no start event is emitted');
121 | });
122 |
123 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
124 | swipe.push({ timeStamp: 234, touches: [{ pageX: 10, pageY: 20 }] });
125 | swipe.push({ timeStamp: 345, touches: [{ pageX: 19, pageY: 30 }] });
126 | swipe.push({ timeStamp: 456, touches: [{ pageX: 30, pageY: 40 }] });
127 | swipe.push({ timeStamp: 567, touches: [{ pageX: 35, pageY: 10 }] });
128 | setTimeout(assert.async, 1);
129 | });
130 |
131 | module('SwipeGesture - progress event');
132 |
133 | test('is fired when an event is added to a tracked gesture', function(assert) {
134 | assert.expect(2);
135 | var eventsCount = 0;
136 | swipe = new SwipeGesture();
137 |
138 | swipe.on('progress', function(gesture) {
139 | assert.equal(++eventsCount, 1, 'The event that triggers the start event does not trigger a progress event');
140 | assert.equal(gesture.x, 35, 'The gesture contains the last event');
141 | setTimeout(assert.async, 1);
142 | });
143 |
144 | swipe.push({ timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
145 | swipe.push({ timeStamp: 234, touches: [{ pageX: 10, pageY: 10 }] });
146 | swipe.push({ timeStamp: 345, touches: [{ pageX: 19, pageY: 10 }] });
147 | swipe.push({ timeStamp: 456, touches: [{ pageX: 30, pageY: 10 }] });
148 | swipe.push({ timeStamp: 567, touches: [{ pageX: 35, pageY: 10 }] });
149 | });
150 |
151 | module('SwipeGesture - end event');
152 |
153 | test('is fired when a tracked event finalized', function(assert) {
154 | assert.expect(2);
155 | var eventsCount = 0;
156 | swipe = new SwipeGesture();
157 |
158 | swipe.on('end', function(gesture) {
159 | assert.equal(++eventsCount, 1, 'The event that triggers the start event does not trigger a progress event');
160 | assert.equal(gesture.x, 31, 'The last event is the previous one');
161 | setTimeout(assert.async, 1);
162 | });
163 |
164 | swipe.push({ type: 'touchstart', timeStamp: 123, touches: [{ pageX: 0, pageY: 10 }] });
165 | swipe.push({ type: 'touchmove', timeStamp: 234, touches: [{ pageX: 30, pageY: 10 }] });
166 | swipe.push({ type: 'touchmove', timeStamp: 345, touches: [{ pageX: 31, pageY: 11 }] });
167 | swipe.push({ type: 'touchend', timeStamp: 456, touches: [{ pageX: 35, pageY: 10}] });
168 | });
169 |
--------------------------------------------------------------------------------
/tests/unit/views/application-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('view:application', 'ApplicationView');
7 |
8 | // Replace this with your real tests.
9 | test('it exists', function(assert) {
10 | var view = this.subject();
11 | assert.ok(view);
12 | });
13 |
--------------------------------------------------------------------------------
/vendor/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cibernox/mobile-patterns/1041e661a802ed31bb714974aa79f77d1ef49f3b/vendor/.gitkeep
--------------------------------------------------------------------------------
/workers/offline-support.js:
--------------------------------------------------------------------------------
1 | var CACHE_NAME = 'mobile-patterns-v1';
2 |
3 | self.addEventListener('fetch', function(event) {
4 | var fetchRequest = event.request.clone();
5 | var cacheRequest = event.request.clone();
6 |
7 | // Respond with content from fetch or cache
8 | event.respondWith(
9 |
10 | // Try fetch
11 | fetch(fetchRequest)
12 | .then(function(response) {
13 | // when fetch is successful, we update the cache
14 |
15 | // A response is a stream and can be consumed only once.
16 | // Because we want the browser to consume the response,
17 | // as well as cache to consume the response, we need to
18 | // clone it so we have 2 streams
19 | var responseToCache = response.clone();
20 |
21 | // and update the cache
22 | caches.open(self.CACHE_NAME).then(function(cache) {
23 | // Clone the request again to use it
24 | // as the key for our cache
25 | var cacheSaveRequest = event.request.clone();
26 | cache.put(cacheSaveRequest, responseToCache);
27 | });
28 |
29 | // Return the response stream to be consumed by browser
30 | return response;
31 |
32 | }).catch(function(err) {
33 | // when fetch times out or fails
34 |
35 | var cachedResponse = caches.match(cacheRequest);
36 |
37 | if (/\/api\//.test(cacheRequest.url)) {
38 | return cachedResponse.then(function(response) {
39 | return response.json().then(function(json) {
40 | json.meta = json.meta || {};
41 | json.meta.offlineSupportWorker = true;
42 | var blob = new Blob([JSON.stringify(json)], { type: 'application/json' })
43 | return new Response(blob, { headers: response.headers });
44 | })
45 | });
46 | } else {
47 | return cachedResponse;
48 | }
49 |
50 | })
51 | );
52 | });
53 |
54 | // Now we need to clean up resources in the previous versions
55 | // of Service Worker scripts
56 | self.addEventListener('activate', function(event) {
57 | // Destroy the cache
58 | event.waitUntil(caches.delete(self.CACHE_NAME));
59 | });
60 |
--------------------------------------------------------------------------------