modjs-architecture 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.travis.yml +2 -0
  2. data/Gemfile +9 -3
  3. data/Gemfile.lock +49 -13
  4. data/{README.rdoc → README.md} +6 -4
  5. data/Rakefile +25 -4
  6. data/VERSION +1 -1
  7. data/lib/modjs-architecture.rb +122 -0
  8. data/lib/modjs-architecture/core/application.js +29 -0
  9. data/lib/modjs-architecture/core/dom.js +84 -0
  10. data/lib/modjs-architecture/core/module.js +65 -0
  11. data/lib/modjs-architecture/extensions/events.js +84 -0
  12. data/lib/modjs-architecture/helpers/existence.js +62 -0
  13. data/lib/modjs-architecture/jasmine/MIT.LICENSE +20 -0
  14. data/lib/modjs-architecture/jasmine/index.html +50 -0
  15. data/lib/modjs-architecture/jasmine/jasmine-html.js +190 -0
  16. data/lib/modjs-architecture/jasmine/jasmine.css +166 -0
  17. data/lib/modjs-architecture/jasmine/jasmine.js +2476 -0
  18. data/lib/modjs-architecture/jasmine/jasmine_favicon.png +0 -0
  19. data/lib/modjs-architecture/lib/mod.js +320 -0
  20. data/lib/modjs-architecture/modjs.architecture +6 -0
  21. data/lib/modjs-architecture/src/mod.js +9 -0
  22. data/modjs-architecture.gemspec +92 -0
  23. data/spec/fixtures/myapp.architecture +8 -0
  24. data/spec/fixtures/myapp.js +322 -0
  25. data/spec/fixtures/test.js +1 -0
  26. data/spec/fixtures/test.module.js +1 -0
  27. data/spec/fixtures/update.architecture +8 -0
  28. data/spec/fixtures/update.js +329 -0
  29. data/spec/javascripts/application_spec.js +23 -0
  30. data/spec/javascripts/dom_spec.js +49 -0
  31. data/spec/javascripts/existence_spec.js +143 -0
  32. data/spec/javascripts/module_spec.js +76 -0
  33. data/spec/javascripts/support/jasmine.css +229 -0
  34. data/spec/javascripts/support/jasmine.yml +73 -0
  35. data/spec/javascripts/support/jasmine_config.rb +23 -0
  36. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  37. data/spec/modjs-architecture_spec.rb +97 -4
  38. data/spec/spec_helper.rb +39 -8
  39. metadata +61 -22
@@ -0,0 +1 @@
1
+ var test = 'test';
@@ -0,0 +1 @@
1
+ var test = 'test';
@@ -0,0 +1,8 @@
1
+ framework: modjs
2
+ src_dir: modules
3
+ build_dir: application
4
+ asset_root: ../
5
+ output: expanded
6
+ dependencies: ["../modules/test.module"]
7
+ autoload: ["../modules/test.module"]
8
+ name: myapp
@@ -0,0 +1,329 @@
1
+ /*---------- ModJS dependency ../modules/test.module ----------*/
2
+ var test = 'test';
3
+
4
+ /*---------- ModJS ../lib/mod.js ----------*/
5
+ is_defined = function(suspect) {
6
+ return typeof suspect == "undefined" ? false : true;
7
+ };
8
+
9
+ is_undefined = function(suspect) {
10
+ return typeof suspect == "undefined" ? true : false;
11
+ };
12
+
13
+ is_typeof = function(type, suspect) {
14
+ if (is_undefined(type)) {
15
+ throw new Error("is_typeof(Type, suspect): type is undefined");
16
+ }
17
+
18
+ if (is_undefined(suspect)) {
19
+ throw new Error("is_typeof(Type, suspect): suspect is undefined");
20
+ }
21
+
22
+ return suspect.constructor == type ? true : false;
23
+ };
24
+
25
+ is_numeric = function(suspect) {
26
+ if (isNaN(suspect)) {
27
+ return false;
28
+ }
29
+ return !isNaN(parseFloat(suspect)) && isFinite(suspect);
30
+ };
31
+
32
+ is_string = function(suspect) {
33
+ return is_typeof(String, suspect);
34
+ };
35
+
36
+ is_array = function(suspect) {
37
+ return is_typeof(Array, suspect);
38
+ };
39
+
40
+ is_number = function(suspect) {
41
+ return is_typeof(Number, suspect);
42
+ };
43
+
44
+ is_date = function(suspect) {
45
+ return is_typeof(Date, suspect);
46
+ };
47
+
48
+ is_bool = function(suspect) {
49
+ return is_typeof(Boolean, suspect);
50
+ };
51
+
52
+ is_regex = function(suspect) {
53
+ return is_typeof(RegExp, suspect);
54
+ };
55
+
56
+ is_empty = function(suspect) {
57
+ if (is_undefined(suspect)) {
58
+ return true;
59
+ }
60
+
61
+ return suspect.length === 0;
62
+ };
63
+
64
+ is_not_empty = function(suspect) {
65
+ return suspect.length >= 1;
66
+ };
67
+ if (!Element.prototype.addEventListener) {
68
+ var oListeners = {};
69
+
70
+ function runListeners(oEvent) {
71
+ if (!oEvent) {
72
+ oEvent = window.event;
73
+ }
74
+
75
+ for (var iLstId = 0, iElId = 0, oEvtListeners = oListeners[oEvent.type]; iElId < oEvtListeners.aEls.length; iElId++) {
76
+ if (oEvtListeners.aEls[iElId] === this) {
77
+ for (iLstId; iLstId < oEvtListeners.aEvts[iElId].length; iLstId++) {
78
+ oEvtListeners.aEvts[iElId][iLstId].call(this, oEvent);
79
+ }
80
+
81
+ break;
82
+ }
83
+ }
84
+ }
85
+
86
+ Element.prototype.addEventListener = function (sEventType, fListener) {
87
+ if (oListeners.hasOwnProperty(sEventType)) {
88
+ var oEvtListeners = oListeners[sEventType];
89
+
90
+ for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
91
+ if (oEvtListeners.aEls[iElId] === this) {
92
+ nElIdx = iElId; break;
93
+ }
94
+ }
95
+
96
+ if (nElIdx === -1) {
97
+ oEvtListeners.aEls.push(this);
98
+ oEvtListeners.aEvts.push([fListener]);
99
+ this["on" + sEventType] = runListeners;
100
+ }
101
+ else {
102
+ var aElListeners = oEvtListeners.aEvts[nElIdx];
103
+
104
+ if (this["on" + sEventType] !== runListeners) {
105
+ aElListeners.splice(0);
106
+ this["on" + sEventType] = runListeners;
107
+ }
108
+
109
+ for (var iLstId = 0; iLstId < aElListeners.length; iLstId++) {
110
+ if (aElListeners[iLstId] === fListener) {
111
+ return;
112
+ }
113
+ }
114
+
115
+ aElListeners.push(fListener);
116
+ }
117
+ }
118
+ else {
119
+ oListeners[sEventType] = {
120
+ aEls: [this],
121
+ aEvts: [[fListener]]
122
+ };
123
+
124
+ this["on" + sEventType] = runListeners;
125
+ }
126
+ };
127
+
128
+ Element.prototype.removeEventListener = function (sEventType) {
129
+ if (!oListeners.hasOwnProperty(sEventType)) {
130
+ return;
131
+ }
132
+
133
+ var oEvtListeners = oListeners[sEventType];
134
+
135
+ for (var nElIdx = -1, iElId = 0; iElId < oEvtListeners.aEls.length; iElId++) {
136
+ if (oEvtListeners.aEls[iElId] === this) {
137
+ nElIdx = iElId;
138
+ break;
139
+ }
140
+ }
141
+
142
+ if (nElIdx === -1) {
143
+ return;
144
+ }
145
+
146
+ for (var iLstId = 0, aElListeners = oEvtListeners.aEvts[nElIdx]; iLstId < aElListeners.length; iLstId++) {
147
+ aElListeners.splice(iLstId, 1);
148
+ }
149
+ };
150
+ }
151
+
152
+ var Mod = {};
153
+
154
+ Mod.DOM = (function() {
155
+
156
+ var timer,
157
+ queue = [];
158
+
159
+ function DOM() {
160
+ this.cache = {};
161
+ this.is_ready = false;
162
+ }
163
+
164
+ DOM.prototype.add_event = function(element, type, fn, capture) {
165
+ if (is_undefined(capture)) {
166
+ capture = false;
167
+ }
168
+
169
+ if (is_string(element)) {
170
+ element = this.cache[element];
171
+ }
172
+
173
+ element.addEventListener(type, fn, capture);
174
+ };
175
+
176
+ DOM.prototype.remove_event = function(element, type, fn, capture) {
177
+ if (is_undefined(capture)) {
178
+ capture = false;
179
+ }
180
+
181
+ if (is_string(element)) {
182
+ element = this.cache[element];
183
+ }
184
+
185
+ element.removeEventListener(type, fn, capture);
186
+ };
187
+
188
+ DOM.prototype.call_when_ready = function(func) {
189
+ if (this.is_ready) {
190
+ return func();
191
+ }
192
+
193
+ if (timer) {
194
+ queue.push(func);
195
+ }
196
+ else {
197
+ this.add_event(window, 'load', this.execute_ready_queue);
198
+ queue.push(func);
199
+ timer = setInterval(this.execute_ready_queue, 13);
200
+ }
201
+ };
202
+
203
+ DOM.prototype.execute_ready_queue = function() {
204
+ if (this.is_ready) {
205
+ return false;
206
+ }
207
+
208
+ if (document && document.getElementsByTagName && document.getElementById && document.body) {
209
+ clearInterval(timer);
210
+ timer = null;
211
+ for(var i = 0, j = queue.length; i < j; i++) {
212
+ queue[i]();
213
+ }
214
+
215
+ queue = [];
216
+ this.is_ready = true;
217
+ }
218
+ };
219
+
220
+ DOM.prototype.add_elements = function(elements) {
221
+ for(var key in elements) {
222
+ if (elements.hasOwnProperty(key)) {
223
+ this.add_element(key, elements[key]);
224
+ }
225
+ }
226
+ };
227
+
228
+ DOM.prototype.add_element = function(key, element) {
229
+ this.cache[key] = element;
230
+ };
231
+
232
+ return DOM;
233
+ })();
234
+ Mod.Module = (function() {
235
+
236
+ function Module(name) {
237
+ if (is_undefined(name)) {
238
+ throw new Error("Mod.Module(name): name is undefined");
239
+ }
240
+
241
+ this.dom = new Mod.DOM;
242
+ this.data = {};
243
+ this.name = name;
244
+ }
245
+
246
+ Module.prototype.actions = function() {};
247
+
248
+ Module.prototype.run = function() {
249
+ var mod = this;
250
+ this.dom.call_when_ready(function() {
251
+ mod.execute();
252
+ });
253
+ };
254
+
255
+ Module.prototype.execute = function() {
256
+ this.actions();
257
+ };
258
+
259
+ Module.prototype.elements = function(elements) {
260
+ if (is_undefined(elements)) {
261
+ return this.dom.cache;
262
+ }
263
+
264
+ if (is_string(elements)) {
265
+ var name = elements;
266
+ return this.dom.cache[name];
267
+ }
268
+ else {
269
+ this.dom.add_elements(elements);
270
+ }
271
+ };
272
+
273
+ Module.prototype.set_data = function(key, value) {
274
+ if (is_undefined(key)) {
275
+ throw new Error(this.name + '.set_data(key, value): key is undefined');
276
+ }
277
+
278
+ if (is_typeof(String, key) && is_undefined(value)) {
279
+ throw new SyntaxError(this.name + 'Module.set_data(key, value): value is undefined');
280
+ }
281
+
282
+ if (is_typeof(String, key)) {
283
+ this.data[key] = value;
284
+ }
285
+ else if (is_typeof(Object, key)) {
286
+ var data = key;
287
+ for(var property in data) {
288
+ this.data[property] = data[property];
289
+ }
290
+ }
291
+
292
+ return this;
293
+ };
294
+
295
+ return Module;
296
+ })();
297
+ Mod.Application = (function() {
298
+
299
+ function Application(name) {
300
+ if (is_undefined(name)) {
301
+ throw new Error("new Mod.Application(name): name is undefined");
302
+ }
303
+
304
+ this.name = name
305
+ };
306
+
307
+ Application.prototype.add_module = function(name) {
308
+ if (is_undefined(name)) {
309
+ throw new Error("Mod.Application.add_module(name): name is undefined");
310
+ }
311
+
312
+ if (is_defined(this[name])) {
313
+ throw new Error("Mod.Application.add_module('" + name + "'): '" + name + "' already declared");
314
+ }
315
+
316
+ if (this.name === name) {
317
+ throw new Error("Mod.Application.add_module('" + name + "'): a module cannot have the same name as the application. It's bad idea. Do you really want to write " + name + "." + name + "? It's confusing.'");
318
+ }
319
+
320
+ return this[name] = new Mod.Module(name);
321
+ };
322
+
323
+ return Application;
324
+ })();
325
+
326
+ var myapp = new Mod.Application('myapp');
327
+
328
+ /*---------- ModJS autoload ../modules/test.module ----------*/
329
+
@@ -0,0 +1,23 @@
1
+ describe("Mod.Application", function() {
2
+
3
+ it("should require a name attribute", function() {
4
+ expect(function() {
5
+ var app = new Mod.Application;
6
+ }).toThrow("new Mod.Application(name): name is undefined");
7
+
8
+ });
9
+
10
+ it("should create a new application instance", function() {
11
+ var app = new Mod.Application('app');
12
+ expect(app).toBeTruthy();
13
+ expect(app.name).toEqual('app');
14
+ });
15
+
16
+ it("should have a module factory method", function() {
17
+ var app = new Mod.Application('app');
18
+ app.add_module('foo');
19
+ expect(app.foo).toBeTruthy();
20
+ expect(app.foo.name).toEqual('foo');
21
+ });
22
+
23
+ });
@@ -0,0 +1,49 @@
1
+ describe("Mod.DOM", function() {
2
+ var dom;
3
+
4
+ beforeEach(function() {
5
+ dom = new Mod.DOM;
6
+ });
7
+
8
+ it("should have a cache", function() {
9
+ expect(dom.cache).toEqual({});
10
+ });
11
+
12
+ it("should have an is_ready property", function() {
13
+ expect(is_bool(dom.is_ready)).toBeTruthy();
14
+ });
15
+
16
+ it("should add an element to the cache", function() {
17
+ dom.add_element('foo', document.getElementById('body'));
18
+ expect(dom.cache.foo).toEqual(document.getElementById('body'));
19
+ });
20
+
21
+ it("should add a hash of elements to the cache", function() {
22
+ dom.add_elements({
23
+ bar: document.getElementsByTagName('html')[0],
24
+ baz: document.getElementsByTagName('head')[0]
25
+ });
26
+
27
+ expect(dom.cache.bar).toEqual(document.getElementsByTagName('html')[0]);
28
+ expect(dom.cache.baz).toEqual(document.getElementsByTagName('head')[0]);
29
+ });
30
+
31
+ it("should have an add_event method", function() {
32
+ expect(dom.add_event).toBeTruthy();
33
+ });
34
+
35
+ it("should have a remove_event method", function() {
36
+ expect(dom.remove_event).toBeTruthy();
37
+ });
38
+
39
+ it("should have a call_when_ready method", function() {
40
+ dom.call_when_ready(function() {
41
+ var body = document.getElementsByTagName('body')[0],
42
+ h1 = document.createElement('h1');
43
+
44
+ h1.setAttribute('id', 'foo');
45
+ body.appendChild(h1);
46
+ expect(document.getElementById('foo')).toBeTruthy();
47
+ });
48
+ });
49
+ });
@@ -0,0 +1,143 @@
1
+ describe("Mod.js", function() {
2
+ function CustomClass() {};
3
+ var undef,
4
+ empty_string = "",
5
+ whitespace = " ",
6
+ tabs = "\t\t",
7
+ string = "Hello World",
8
+ alpha = "xabcdefx",
9
+ alpha_num = "abcdefghijklm1234567890",
10
+ empty_array = [],
11
+ array = ['one', 'two', 'three'],
12
+ custom_object = new CustomClass,
13
+ number_string = "42",
14
+ mix_string_num = "bcfed5.2",
15
+ oct_int_string = "040",
16
+ oct_int = 0144,
17
+ hex_int_string = "0xFF",
18
+ hex_int = 0xFFF,
19
+ number = 42,
20
+ neg_int = -16,
21
+ neg_int_string = "-10",
22
+ neg_float_string = "-1.6",
23
+ pos_float_string = "4.536",
24
+ neg_float = -2.6,
25
+ pos_float = 3.1415,
26
+ exp = 8e5,
27
+ exp_string = "123e-2",
28
+ zero_string = "0",
29
+ obj = {},
30
+ func = function() {},
31
+ date = new Date,
32
+ bool_true = true,
33
+ bool_false = false,
34
+ one = 1,
35
+ zero = 0,
36
+ pattern = /regex/;
37
+
38
+ it("should test for existence with is_defined", function() {
39
+ expect(is_defined).toBeTruthy();
40
+ expect(is_defined(undef)).toBeFalsy();
41
+ expect(is_defined(empty_string)).toBeTruthy();
42
+ });
43
+
44
+ it("should test for existence with is_undefined", function() {
45
+ expect(is_undefined).toBeTruthy();
46
+ expect(is_undefined(undef)).toBeTruthy();
47
+ expect(is_undefined(empty_string)).toBeFalsy();
48
+ });
49
+
50
+ it("should check for strict types with is_typeof", function() {
51
+ expect(is_typeof).toBeTruthy();
52
+ expect(is_typeof(String, empty_string)).toBeTruthy();
53
+ expect(is_typeof(Array, empty_array)).toBeTruthy();
54
+ expect(is_typeof(CustomClass, custom_object)).toBeTruthy();
55
+ });
56
+
57
+ it("should test for numeric values with is_numeric", function() {
58
+ expect(is_numeric(neg_int_string)).toBeTruthy();
59
+ expect(is_numeric(zero_string)).toBeTruthy();
60
+ expect(is_numeric(number)).toBeTruthy();
61
+ expect(is_numeric(neg_int)).toBeTruthy();
62
+ expect(is_numeric(zero)).toBeTruthy();
63
+ expect(is_numeric(oct_int_string)).toBeTruthy();
64
+ expect(is_numeric(oct_int)).toBeTruthy();
65
+ expect(is_numeric(hex_int)).toBeTruthy();
66
+ expect(is_numeric(neg_float)).toBeTruthy();
67
+ expect(is_numeric(pos_float)).toBeTruthy();
68
+ expect(is_numeric(exp)).toBeTruthy();
69
+ expect(is_numeric(exp_string)).toBeTruthy();
70
+
71
+ expect(is_numeric(empty_string)).toBeFalsy();
72
+ expect(is_numeric(whitespace)).toBeFalsy();
73
+ expect(is_numeric(tabs)).toBeFalsy();
74
+ expect(is_numeric(alpha_num)).toBeFalsy();
75
+ expect(is_numeric(alpha)).toBeFalsy();
76
+ expect(is_numeric(bool_true)).toBeFalsy();
77
+ expect(is_numeric(bool_false)).toBeFalsy();
78
+ expect(is_numeric(mix_string_num)).toBeFalsy();
79
+ expect(is_numeric(NaN)).toBeFalsy();
80
+ expect(is_numeric(Infinity)).toBeFalsy();
81
+ expect(is_numeric(Number.POSITIVE_INFINITY)).toBeFalsy();
82
+ expect(is_numeric(Number.NEGATIVE_INFINITY)).toBeFalsy();
83
+ expect(is_numeric(date)).toBeFalsy();
84
+ expect(is_numeric(obj)).toBeFalsy();
85
+ expect(is_numeric(func)).toBeFalsy();
86
+ });
87
+
88
+ it("should test for strings with is_string", function() {
89
+ expect(is_string).toBeTruthy();
90
+ expect(is_string(empty_string)).toBeTruthy();
91
+ expect(is_string(empty_array)).toBeFalsy();
92
+ expect(is_string(custom_object)).toBeFalsy();
93
+ });
94
+
95
+ it("should test for arrays with is_array", function() {
96
+ expect(is_array).toBeTruthy();
97
+ expect(is_array(empty_array)).toBeTruthy();
98
+ expect(is_array(empty_string)).toBeFalsy();
99
+ });
100
+
101
+ it("should test for numbers with is_number", function() {
102
+ expect(is_number).toBeTruthy();
103
+ expect(is_number(number)).toBeTruthy();
104
+ expect(is_number(number_string)).toBeFalsy();
105
+ expect(is_number(empty_string)).toBeFalsy();
106
+ });
107
+
108
+ it("should test for date objects with is_date", function() {
109
+ expect(is_date).toBeTruthy();
110
+ expect(is_date(date)).toBeTruthy();
111
+ expect(is_date(empty_string)).toBeFalsy();
112
+ });
113
+
114
+ it("should test for boolean values with is_bool", function() {
115
+ expect(is_bool).toBeTruthy();
116
+ expect(is_bool(bool_true)).toBeTruthy();
117
+ expect(is_bool(bool_false)).toBeTruthy();
118
+ expect(is_bool(one)).toBeFalsy();
119
+ expect(is_bool(zero)).toBeFalsy();
120
+ });
121
+
122
+ it("should test for RegEx objects with is_regex", function() {
123
+ expect(is_regex).toBeTruthy();
124
+ expect(is_regex(pattern)).toBeTruthy();
125
+ expect(is_regex(empty_string)).toBeFalsy();
126
+ });
127
+
128
+ it("should test for emptiness with is_empty", function() {
129
+ expect(is_empty).toBeTruthy();
130
+ expect(is_empty(empty_string)).toBeTruthy();
131
+ expect(is_empty(empty_array)).toBeTruthy();
132
+ expect(is_empty(array)).toBeFalsy();
133
+ expect(is_empty(string)).toBeFalsy();
134
+ });
135
+
136
+ it("should test for emptiness with is_not_empty", function() {
137
+ expect(is_not_empty).toBeTruthy();
138
+ expect(is_not_empty(empty_string)).toBeFalsy();
139
+ expect(is_not_empty(empty_array)).toBeFalsy();
140
+ expect(is_not_empty(array)).toBeTruthy();
141
+ expect(is_not_empty(string)).toBeTruthy();
142
+ });
143
+ });