coolerator.vision 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.2.5
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{coolerator.vision}
8
- s.version = "0.2.4"
8
+ s.version = "0.2.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Corey Innis"]
12
- s.date = %q{2009-11-13}
12
+ s.date = %q{2009-11-16}
13
13
  s.description = %q{A Rails plugin}
14
14
  s.email = %q{corey@coolerator.net}
15
15
  s.extra_rdoc_files = [
@@ -1,5 +1,4 @@
1
1
  (function($) {
2
- // VERSION 0.1.0
3
2
  // $.noConflict();
4
3
 
5
4
  Coolerator = {
@@ -1,57 +1,107 @@
1
1
  (function($) {
2
2
  $.extend(Coolerator, {
3
3
  Filters : {
4
- global : [],
5
- scoped : {},
4
+ count : function count() {
5
+ return __count__;
6
+ },
6
7
 
7
- get : function get(scope) {
8
- return $.merge($.makeArray(this.global), $.makeArray(this.scoped[scope]));
9
- }
10
- },
8
+ clear : function clear() {
9
+ __database__ = {};
10
+ __count__ = 0;
11
+ },
11
12
 
12
- Filter : function Filter() {
13
- var scope = ['*'];
14
- var filter = this;
13
+ prepare : function prepare() {
14
+ if(2 !== arguments.length) {
15
+ throw("InvalidArgumentException");
16
+ }
15
17
 
16
- if(arguments.length) {
17
- var first = arguments[0];
18
+ var view = arguments[0];
19
+ var scope = arguments[1];
18
20
 
19
- if('object' === typeof first) {
20
- scope = $.isArray(first.scope) ? first.scope : [first.scope || '*'];
21
+ if('object' !== typeof view || 'string' !== typeof scope) {
22
+ throw("InvalidArgumentException");
23
+ }
24
+
25
+ $.each(view, function prepare_views(name, content) {
26
+ view[name] = $(content);
27
+ });
21
28
 
22
- filter = {
23
- label : first.label,
24
- before : (first.before || function no_op() {}),
25
- after : (first.after || function no_op() {})
26
- };
29
+ var filters = retrieve(scope);
30
+ function before() {
31
+ $.each(filters, function(i, filter) {
32
+ filter.before(view);
33
+ });
34
+
35
+ return { after : after };
27
36
  }
28
- else {
29
- scope = arguments;
37
+
38
+ function after() {
39
+ $.each(filters, function(i, filter) {
40
+ filter.after(view);
41
+ });
42
+
43
+ return { before : before };
30
44
  }
45
+
46
+ return {
47
+ before : before,
48
+ after : after
49
+ };
31
50
  }
51
+ },
32
52
 
33
- $.each(scope, function(i, selector) {
34
- if(selector === '*') {
35
- Coolerator.Filters.global.push(filter);
36
- }
37
- else {
38
- Coolerator.Filters.scoped[selector || '*'] = $.merge(Coolerator.Filters.scoped[selector || '*'] || [], [filter]);
39
- }
53
+ Filter : function Filter() {
54
+ var scopes = arguments.length ? arguments : ['*'];
55
+ var filter = {
56
+ before : no_op,
57
+ after : no_op
58
+ }
59
+
60
+ $.each(scopes, function(i, scope) {
61
+ store(scope, filter);
40
62
  });
41
- }
42
- });
43
63
 
44
- $.extend(Coolerator.Filter.prototype, {
45
- before : function before(fn) {
46
- if('function' == typeof fn) {
47
- this.before = fn;
64
+ function before(fn) {
65
+ filter.before = fn;
66
+ return { after : after };
48
67
  }
49
- },
50
68
 
51
- after : function after(fn) {
52
- if('function' == typeof fn) {
53
- this.after = fn;
69
+ function after(fn) {
70
+ filter.after = fn;
71
+ return { before : before };
54
72
  }
73
+
74
+ return {
75
+ before : before,
76
+ after : after
77
+ };
55
78
  }
56
79
  });
80
+
81
+
82
+ // private...................................................................
83
+
84
+ var __count__ = 0;
85
+ var __database__ = {};
86
+
87
+ function no_op() {}
88
+
89
+ function store(scope, filter) {
90
+ if('object' === typeof scope) {
91
+ filter = scope;
92
+ scope = '*';
93
+ }
94
+
95
+ __database__[scope] = __database__[scope] || [];
96
+ __database__[scope].push(filter);
97
+ __count__ += 1;
98
+ }
99
+
100
+ function retrieve(scope) {
101
+ if('*' === scope) {
102
+ return __database__['*'] || [];
103
+ }
104
+
105
+ return $.merge(__database__['*'] || [], __database__[scope] || []);
106
+ }
57
107
  })(jQuery);
@@ -1,85 +1,83 @@
1
1
  (function($) {
2
+ var __database__ = {
3
+ collections : {},
4
+ instances : {}
5
+ };
6
+
2
7
  $.extend(Coolerator, {
3
- Views : {},
8
+ Views : {
9
+ get : function get(classifier) {
10
+ if( ! classifier || /\s+/.test(classifier)) {
11
+ throw("InvalidArgumentException");
12
+ }
13
+
14
+ return __database__.collections[classifier];
15
+ }
16
+ },
4
17
 
5
18
  View : function View(classifier) {
19
+ if( ! classifier || /\s+/.test(classifier)) {
20
+ throw("InvalidArgumentException");
21
+ }
22
+
6
23
  this.classifier = classifier;
7
24
 
8
- $.extend(this, {
9
- instance : {
10
- content : function content(builder, attributes) {
11
- var html_attributes = attributes.classifier ? { 'class' : attributes.classifier } : {};
25
+ __database__.collections[this.classifier] = this;
26
+ __database__.instances [this.classifier] = {
27
+ content : function content(builder, attributes) {
28
+ var html_attributes = attributes.classifier ? { 'class' : attributes.classifier } : {};
12
29
 
13
- with(builder) {
14
- div(html_attributes);
15
- }
16
- },
30
+ with(builder) {
31
+ div(html_attributes);
32
+ }
33
+ },
17
34
 
18
- methods : {
19
- initialize : function initialize() {
20
- if(this.content) {
21
- this.html(this.content);
22
- }
35
+ methods : {
36
+ initialize : function initialize() {
37
+ if(this.content) {
38
+ this.html(this.content);
23
39
  }
24
40
  }
25
41
  }
26
- });
27
-
28
- Coolerator.Views[classifier] = this;
42
+ };
29
43
  }
30
44
  });
31
45
 
32
46
  $.extend(Coolerator.View.prototype, {
33
- cache : {},
47
+ subscribe : function subscribe(fn) {
48
+ Coolerator.Registrar.subscribe(this, fn);
49
+ },
34
50
 
35
51
  extend : function extend(extension) {
36
- var self = this;
52
+ var instance = extension.instance || {};
53
+ var existing = __database__.instances[this.classifier];
54
+ delete extension.instance;
37
55
 
38
- $.each(extension.instance.methods, function(name, fn) {
39
- if(self.instance.methods[name]) {
40
- var superb = self.instance.methods[name];
56
+ $.each(instance.methods || {}, function(name, fn) {
57
+ var superb = existing.methods[name];
58
+
59
+ if(superb) {
41
60
  function sup() {
42
61
  var args = $.makeArray(arguments);
43
62
  superb.apply(args.shift(), args);
44
63
  }
64
+
45
65
  $.extend(fn, { 'super' : sup });
46
66
  }
47
67
  });
48
68
 
49
- $.extend(true, this.instance, extension.instance);
50
- if(extension.collection) {
51
- $.extend(true, this, extension.collection.methods, extension.collection.configuration);
52
- }
53
- },
54
-
55
- subscribe : function subscribe(callback) {
56
- var self = this;
57
- callback = callback.toString().match(Coolerator.REGEX.FUNCTION_BODY)[1];
58
- callback = new Function('registrar', 'with(registrar) { ' + callback + ' } ;');
59
-
60
- Coolerator.Registrar.subscribe(self, callback);
69
+ $.extend(true, __database__.instances[this.classifier], instance);
70
+ $.extend(true, this, extension);
61
71
  },
62
72
 
63
73
  build : function build(attributes) {
64
- if(this.cache.instance) {
65
- return this.cache.instance;
66
- }
67
-
68
- var result = Prez.build(this.instance, $.extend({ collection: this, classifier : this.classifier }, (attributes || {})));
69
-
70
- // TODO: consider making a call to view.subscribe
71
- function subscribe(callback) {
72
- if(callback) {
73
- callback = callback.toString().match(Coolerator.REGEX.FUNCTION_BODY)[1];
74
- callback = new Function('registrar', 'with(registrar) { ' + callback + ' } ;');
75
- Coolerator.Registrar.subscribe(result, callback);
76
- }
77
- }
74
+ // TODO: provide a template cacheing mechanism.
78
75
 
79
- subscribe(result.subscribe);
76
+ var instance = __database__.instances[this.classifier];
77
+ var result = Prez.build(instance, $.extend({ classifier : this.classifier }, (attributes || {})));
80
78
 
81
- if(this.singleton) {
82
- this.cache.instance = result;
79
+ if(result.subscribe) {
80
+ Coolerator.Registrar.subscribe(result, result.subscribe);
83
81
  }
84
82
 
85
83
  return result;
@@ -1,20 +1,274 @@
1
1
  //= require <support/spec_helper>
2
2
 
3
3
  Screw.Unit(function(c) { with(c) {
4
+ after(function() {
5
+ Coolerator.Filters.clear();
6
+ });
7
+
8
+ describe("an example", function() {
9
+ before(function() {
10
+ Coolerator.Filter('scope/one', 'scope/two')
11
+ .before(function(view) {
12
+ $.each(view, function(key, partial) {
13
+ partial.css('border', 'yellow');
14
+ });
15
+ })
16
+ .after(function(view) {
17
+ $.each(view, function(key, partial) {
18
+ partial.css('border', 'green');
19
+ });
20
+ });
21
+ });
22
+
23
+ it("behaves", function() {
24
+ var templates = { show : '<div>content</div>' };
25
+ var filters = Coolerator.Filters.prepare(templates, 'scope/one');
26
+ expect(templates.show.jquery).to_not(be_undefined);
27
+
28
+ filters.before();
29
+ expect(templates.show.css('border')).to(match, 'yellow');
30
+
31
+ filters.after();
32
+ expect(templates.show.css('border')).to(match, 'green');
33
+ });
34
+ });
35
+
36
+ describe("Coolerator.Filters", function() {
37
+ it("is added to the Coolerator namespace", function() {
38
+ expect(typeof Coolerator.Filters).to(equal, 'object');
39
+ });
40
+
41
+ describe("methods", function() {
42
+ describe(".count", function() {
43
+ before(function() {
44
+ Coolerator.Filter({});
45
+ Coolerator.Filter({ scope : 'scope 1' });
46
+ Coolerator.Filter({ scope : 'scope 1' });
47
+ Coolerator.Filter({ scope : 'scope 2' });
48
+ });
49
+
50
+ it("returns the count of filters, regardless of scope", function() {
51
+ expect(Coolerator.Filters.count()).to(equal, 4);
52
+ });
53
+ });
54
+
55
+ describe(".clear", function() {
56
+ before(function() {
57
+ Coolerator.Filter({ label : 'clear' });
58
+ });
59
+
60
+ it("sets 'count' to 0", function() {
61
+ expect(Coolerator.Filters.count()).to(equal, 1);
62
+
63
+ Coolerator.Filters.clear();
64
+ expect(Coolerator.Filters.count()).to(equal, 0);
65
+ });
66
+ });
67
+
68
+ describe(".prepare", function() {
69
+ var view;
70
+
71
+ before(function() {
72
+ view = { show : '<div>content</div>' };
73
+ });
74
+
75
+ describe("argument handling", function() {
76
+ var filters;
77
+
78
+ context("with appropriate arguments", function() {
79
+ before(function() {
80
+ filters = Coolerator.Filters.prepare(view, '*');
81
+ });
82
+
83
+ it("converts the view 'partials' to jQuery objects", function() {
84
+ expect(view.show.jquery).to_not(be_undefined);
85
+ });
86
+
87
+ describe("the returned filter helper", function() {
88
+ it("defines #before", function() {
89
+ expect(filters.before).to_not(throw_exception);
90
+ });
91
+
92
+ it("defines #after", function() {
93
+ expect(filters.after).to_not(throw_exception);
94
+ });
95
+ });
96
+ });
97
+
98
+ context("with fewer than two", function() {
99
+ before(function() {
100
+ fn = function fn() {
101
+ Coolerator.Filters.prepare({});
102
+ };
103
+ });
104
+
105
+ it("throws an exception", function() {
106
+ expect(fn).to(throw_exception);
107
+ });
108
+ });
109
+
110
+ context("with more than two", function() {
111
+ before(function() {
112
+ fn = function fn() {
113
+ Coolerator.Filters.prepare({}, 'scope', 'something else');
114
+ };
115
+ });
116
+
117
+ it("throws an exception", function() {
118
+ expect(fn).to(throw_exception);
119
+ });
120
+ });
121
+
122
+ context("with an undefined 'view'", function() {
123
+ before(function() {
124
+ fn = function fn() {
125
+ Coolerator.Filters.prepare(undefined, 'scope');
126
+ };
127
+ });
128
+
129
+ it("throws an exception", function() {
130
+ expect(fn).to(throw_exception);
131
+ });
132
+ });
133
+
134
+ context("with an undefined 'scope'", function() {
135
+ before(function() {
136
+ fn = function fn() {
137
+ Coolerator.Filters.prepare({ show : '<div>content</div>' }, undefined);
138
+ };
139
+ });
140
+
141
+ it("throws an exception", function() {
142
+ expect(fn).to(throw_exception);
143
+ });
144
+ });
145
+ });
146
+ });
147
+ });
148
+ });
149
+
4
150
  describe("Coolerator.Filter", function() {
151
+ var filter;
152
+
5
153
  it("is added to the Coolerator namespace", function() {
6
154
  expect(typeof Coolerator.Filter).to(equal, 'function');
7
155
  });
8
156
 
9
- context("when created with a configuration object", function() {
10
- context("when the configuration :label exists", function() {
11
- var filter = new Coolerator.Filter({
12
- label : 'so cool!',
13
- scope : 'everywhere'
157
+ describe("the returned object", function() {
158
+ before(function() {
159
+ filter = Coolerator.Filter();
160
+ });
161
+
162
+ it("is defined", function() {
163
+ expect(filter).to_not(be_undefined);
164
+ });
165
+
166
+ it("defines #before", function() {
167
+ expect(filter.before).to_not(be_undefined);
168
+ });
169
+
170
+ it("defines #after", function() {
171
+ expect(filter.after).to_not(be_undefined);
172
+ });
173
+ });
174
+
175
+ describe("argument handling", function() {
176
+ var called;
177
+
178
+ before(function() {
179
+ called = {
180
+ before : false,
181
+ after : false
182
+ }
183
+ });
184
+
185
+ context("called with no scope", function() {
186
+ before(function() {
187
+ Coolerator.Filter()
188
+ .before(function(view) {
189
+ called.before = true;
190
+ })
191
+ .after(function(view) {
192
+ called.after = true;
193
+ });
194
+ });
195
+
196
+ it("adds the filter to the 'global' scope", function() {
197
+ Coolerator.Filters.prepare({}, '*')
198
+ .before()
199
+ .after();
200
+
201
+ expect(called.before).to(be_true);
202
+ expect(called.after ).to(be_true);
14
203
  });
204
+ });
205
+
206
+ context("called with a single scope", function() {
207
+ before(function() {
208
+ Coolerator.Filter('one')
209
+ .before(function(view) {
210
+ called.before = true;
211
+ })
212
+ .after(function(view) {
213
+ called.after = true;
214
+ });
215
+ });
216
+
217
+ it("adds the filter to the provided scope", function() {
218
+ Coolerator.Filters.prepare({}, 'one')
219
+ .before()
220
+ .after();
221
+
222
+ expect(called.before).to(be_true);
223
+ expect(called.after ).to(be_true);
224
+ });
225
+
226
+ it("does not add the filter to the global scope", function() {
227
+ Coolerator.Filters.prepare({}, '*')
228
+ .before()
229
+ .after();
230
+
231
+ expect(called.before).to(be_false);
232
+ expect(called.after ).to(be_false);
233
+ });
234
+ });
235
+
236
+ context("called with multiple scopes", function() {
237
+ before(function() {
238
+ Coolerator.Filter('one', 'two')
239
+ .before(function(view) {
240
+ called.before = true;
241
+ })
242
+ .after(function(view) {
243
+ called.after = true;
244
+ });
245
+ });
246
+
247
+ it("adds the filter to the first provided scope", function() {
248
+ Coolerator.Filters.prepare({}, 'one')
249
+ .before()
250
+ .after();
251
+
252
+ expect(called.before).to(be_true);
253
+ expect(called.after ).to(be_true);
254
+ });
255
+
256
+ it("adds the filter to the first provided scope", function() {
257
+ Coolerator.Filters.prepare({}, 'two')
258
+ .before()
259
+ .after();
260
+
261
+ expect(called.before).to(be_true);
262
+ expect(called.after ).to(be_true);
263
+ });
264
+
265
+ it("does not add the filter to the global scope", function() {
266
+ Coolerator.Filters.prepare({}, '*')
267
+ .before()
268
+ .after();
15
269
 
16
- it("is created with a label", function() {
17
- expect(Coolerator.Filters.get('everywhere')[0].label).to(equal, 'so cool!');
270
+ expect(called.before).to(be_false);
271
+ expect(called.after ).to(be_false);
18
272
  });
19
273
  });
20
274
  });
@@ -3,96 +3,393 @@
3
3
  Screw.Unit(function(c) { with(c) {
4
4
  describe("Coolerator.Views", function() {
5
5
  it("is added to the Coolerator namespace", function() {
6
- expect(Coolerator.Views).to_not(be_undefined);
6
+ expect(typeof Coolerator.Views).to(equal, 'object');
7
7
  });
8
8
 
9
- describe("when creating a Coolerator.View", function() {
10
- it("the View is added to the collection", function() {
11
- var view = new Coolerator.View('oh, behave!');
12
- expect(Coolerator.Views['oh, behave!']).to(equal, view);
9
+ describe("methods", function() {
10
+ describe(".get", function() {
11
+ context("with 'classifier' defined appropriately", function() {
12
+ context("when there is a match", function() {
13
+ it("returns the view", function() {
14
+ var view = new Coolerator.View('defined');
15
+ expect(Coolerator.Views.get('defined')).to(equal, view);
16
+ });
17
+ });
18
+
19
+ context("when there is no match", function() {
20
+ it("returns undefined", function() {
21
+ expect(Coolerator.Views.get('undefined')).to(be_undefined);
22
+ });
23
+ });
24
+ });
25
+
26
+ context("with 'classifier' as falsy", function() {
27
+ var fn;
28
+
29
+ it("throws an exception (with undefined)", function() {
30
+ fn = function fn() {
31
+ Coolerator.Views.get();
32
+ }
33
+ expect(fn).to(throw_exception);
34
+ });
35
+
36
+ it("throws an exception (with null)", function() {
37
+ fn = function fn() {
38
+ Coolerator.Views.get(null);
39
+ }
40
+ expect(fn).to(throw_exception);
41
+ });
42
+
43
+ it("throws an exception (with empty string)", function() {
44
+ fn = function fn() {
45
+ Coolerator.Views.get('');
46
+ }
47
+ expect(fn).to(throw_exception);
48
+ });
49
+
50
+ it("throws an exception (with 0)", function() {
51
+ fn = function fn() {
52
+ Coolerator.Views.get(0);
53
+ }
54
+ expect(fn).to(throw_exception);
55
+ });
56
+ });
13
57
  });
14
58
  });
15
59
  });
16
60
 
17
61
  describe("Coolerator.View", function() {
18
62
  it("is added to the Coolerator namespace", function() {
19
- expect(Coolerator.View).to_not(be_undefined);
63
+ expect(typeof Coolerator.View).to(equal, 'function');
20
64
  });
21
65
 
22
- describe("collection", function() {
23
- it("is optional", function() {
24
- var fn = function() {
25
- var view = new Coolerator.View('one');
66
+ describe("constructor", function() {
67
+ var fn;
26
68
 
27
- view.extend({
28
- instance : {
29
- methods : {}
30
- }
69
+ context("with 'classifier' defined appropriately", function() {
70
+ var view;
71
+
72
+ before(function() {
73
+ view = new Coolerator.View('valid');
74
+ });
75
+
76
+ describe("the returned object", function() {
77
+ it("is a Coolerator.View instance", function() {
78
+ expect(view.constructor.name).to(equal, 'View');
31
79
  });
32
- };
33
80
 
34
- expect(fn).to_not(throw_exception);
35
- });
36
- });
81
+ it("defines 'classifier' as an attribute", function() {
82
+ expect(view.classifier).to(equal, 'valid');
83
+ });
84
+ });
37
85
 
38
- describe("instance", function() {
39
- describe("methods which are implemented in super and child objects", function() {
40
- var view, other;
86
+ describe("updates to Coolerator.Views", function() {
87
+ it("stores the new view", function() {
88
+ expect(Coolerator.Views.get('valid')).to(equal, view);
89
+ });
90
+
91
+ it("overwrites an existing view of the same classifier", function() {
92
+ var over = new Coolerator.View('valid');
41
93
 
94
+ expect(Coolerator.Views.get('valid') == over).to(be_true);
95
+ expect(Coolerator.Views.get('valid') == view).to(be_false);
96
+ });
97
+ });
98
+ });
99
+
100
+ context("with 'classifier' defined with space(s)", function() {
42
101
  before(function() {
43
- other = new Coolerator.View('other');
44
- view = new Coolerator.View('child');
102
+ fn = function fn() {
103
+ return new Coolerator.View('with spaces');
104
+ }
105
+ });
45
106
 
46
- view.extend({
47
- instance : {
48
- methods : {
49
- initialize : function initialize() {}
50
- }
51
- }
52
- })
107
+ it("throws an exception", function() {
108
+ expect(fn).to(throw_exception);
109
+ });
110
+ });
111
+
112
+ context("with 'classifier' defined as falsy", function() {
113
+ it("throws an exception (with undefined)", function() {
114
+ fn = function fn() {
115
+ return new Coolerator.View();
116
+ }
117
+ expect(fn).to(throw_exception);
118
+ });
119
+
120
+ it("throws an exception (with null)", function() {
121
+ fn = function fn() {
122
+ return new Coolerator.View(null);
123
+ }
124
+ expect(fn).to(throw_exception);
53
125
  });
54
126
 
55
- it("provides a mechanism for calling #super", function() {
56
- var instance = view.build();
57
- expect(instance.initialize.super).to(equal, other.instance.methods.initialize);
127
+ it("throws an exception (with empty string)", function() {
128
+ fn = function fn() {
129
+ return new Coolerator.View('');
130
+ }
131
+ expect(fn).to(throw_exception);
132
+ });
133
+
134
+ it("throws an exception (with 0)", function() {
135
+ fn = function fn() {
136
+ return new Coolerator.View(0);
137
+ }
138
+ expect(fn).to(throw_exception);
58
139
  });
59
140
  });
141
+ });
60
142
 
61
- describe("when two or more Views implement the same method", function() {
62
- var instance1, instance2;
143
+ describe("methods", function() {
144
+ var view;
63
145
 
64
- before(function() {
65
- view1 = new Coolerator.View('one');
146
+ before(function() {
147
+ view = new Coolerator.View('subscript');
148
+ });
66
149
 
67
- view1.extend({
68
- instance : {
69
- methods : {
70
- foo : function foo() {
71
- return "foo an instance of view1";
150
+ describe("#subscribe", function() {
151
+ context("given a function", function() {
152
+ it("executes the function with 'this' as the view", function() {
153
+ view.subscribe(function() {
154
+ expect(this).to(equal, view);
155
+ });
156
+ });
157
+
158
+ it("executes the function with a Coolerator.Registar subscription", function() {
159
+ view.subscribe(function(subscription) { with(subscription) {
160
+ expect(on ).to_not(be_undefined);
161
+ expect(use).to_not(be_undefined);
162
+ }});
163
+ });
164
+
165
+ it("[PENDING] executes the function after executing #extend, so other fields are available", function() {
166
+ // this does work, but it relies on jQuery's document ready event which makes it hard to test here.
167
+ });
168
+ });
169
+ });
170
+
171
+ describe("#extend", function() {
172
+ context("given an extension with non-instance arguments", function() {
173
+ it("extends the 'collection' object (the view)", function() {
174
+ function func() {};
175
+
176
+ view.extend({
177
+ conf : 'config',
178
+ func : func
179
+ });
180
+
181
+ expect(view.conf).to(equal, 'config');
182
+ expect(view.func).to(equal, func);
183
+ });
184
+
185
+ it("does not 'step on' other views", function() {
186
+ var view1 = new Coolerator.View('one');
187
+ var view2 = new Coolerator.View('two');
188
+
189
+ view1.extend({
190
+ foo : function foo() {
191
+ return 'foo on view one';
192
+ }
193
+ });
194
+
195
+ view2.extend({
196
+ foo : function foo() {
197
+ return 'foo on view two';
198
+ }
199
+ });
200
+
201
+ expect(view1.foo()).to(equal, 'foo on view one');
202
+ expect(view2.foo()).to(equal, 'foo on view two');
203
+ });
204
+ });
205
+
206
+ context("given an extension with an instance argument", function() {
207
+ it("does not extend the 'collection' object", function() {
208
+ view.extend({
209
+ instance : {
210
+ methods : {}
211
+ }
212
+ });
213
+
214
+ expect(view.instance).to(be_undefined);
215
+ });
216
+
217
+ it("extends built instances", function() {
218
+ view.extend({
219
+ instance : {
220
+ content : function content(builder) {
221
+ builder.div('content');
222
+ },
223
+
224
+ methods : {
225
+ label : function label() {
226
+ return 'an instance';
227
+ }
72
228
  }
73
229
  }
74
- }
230
+ });
231
+
232
+ expect(view.build().label()).to(equal, 'an instance');
75
233
  });
76
234
 
77
- view2 = new Coolerator.View('two');
235
+ it("does not 'step on' other views", function() {
236
+ var view1 = new Coolerator.View('one');
237
+ var view2 = new Coolerator.View('two');
78
238
 
79
- view2.extend({
80
- instance : {
81
- methods : {
82
- foo : function foo() {
83
- return "foo an instance of view2";
84
- }
85
- }
86
- }
87
- });
239
+ view1.extend({
240
+ instance : {
241
+ methods : {
242
+ foo : function foo() {
243
+ return 'foo on view one';
244
+ }
245
+ }
246
+ }
247
+ });
88
248
 
89
- instance1 = view1.build();
90
- instance2 = view2.build();
249
+ view2.extend({
250
+ instance : {
251
+ methods : {
252
+ foo : function foo() {
253
+ return 'foo on view two';
254
+ }
255
+ }
256
+ }
257
+ });
258
+
259
+ expect(view1.build().foo()).to(equal, 'foo on view one');
260
+ expect(view2.build().foo()).to(equal, 'foo on view two');
261
+ });
262
+
263
+ describe("content (for the builder)", function() {
264
+ it("is defaulted to a simple <div />", function() {
265
+ view.extend({
266
+ instance : {}
267
+ });
268
+
269
+ var wrapper = $('<div></div>');
270
+ wrapper.html(view.build());
271
+ expect(wrapper.html()).to(equal, '<div class="subscript"></div>');
272
+ });
273
+
274
+ describe("overwriting", function() {
275
+ it("is allowed", function() {
276
+ view.extend({
277
+ instance : {
278
+ content : function content(builder) {
279
+ with(builder) {
280
+ div({ id : 'custom' });
281
+ }
282
+ }
283
+ }
284
+ });
285
+
286
+ var wrapper = $('<div></div>');
287
+ wrapper.html(view.build());
288
+ expect(wrapper.html()).to(equal, '<div id="custom"></div>');
289
+ });
290
+ });
291
+ });
292
+
293
+ describe("methods", function() {
294
+ describe("#initialize", function() {
295
+ it("is called automatically", function() {
296
+ var called = false;
297
+
298
+ view.extend({
299
+ instance : {
300
+ methods : {
301
+ initialize : function initialize() {
302
+ called = true;
303
+ }
304
+ }
305
+ }
306
+ });
307
+
308
+ view.build();
309
+ expect(called).to(be_true);
310
+ });
311
+
312
+ it("is defaulted to (optionally) write provided content to the instance", function() {
313
+ view.extend({
314
+ instance : {}
315
+ });
316
+
317
+ expect(view.build().html()).to(equal, '');
318
+ expect(view.build({ content : 'hello there' }).html()).to(equal, 'hello there');
319
+ });
320
+
321
+ describe("overwriting", function() {
322
+ before(function() {
323
+ view.extend({
324
+ instance : {
325
+ methods : {
326
+ initialize : function initialize() {
327
+ this.html('overwritten');
328
+ }
329
+ }
330
+ }
331
+ });
332
+ });
333
+
334
+ it("is allowed", function() {
335
+ var instance = view.build();
336
+ expect(instance.html()).to(equal, 'overwritten');
337
+ });
338
+
339
+ it("provides a mechanism for calling #super", function() {
340
+ var instance = view.build();
341
+ expect(typeof instance.initialize.super).to(equal, 'function');
342
+ });
343
+ });
344
+ });
345
+
346
+ describe("#subscribe", function() {
347
+ it("is called automatically, with 'this' as the instance and a Coolerator.Registar subscription as an argument", function() {
348
+ var called = false;
349
+ var callee = null;
350
+
351
+ view.extend({
352
+ instance : {
353
+ methods : {
354
+ subscribe : function subscribe(subscription) {
355
+ called = true;
356
+ callee = this;
357
+
358
+ with(subscription) {
359
+ expect(on ).to_not(be_undefined);
360
+ expect(use).to_not(be_undefined);
361
+ }
362
+ }
363
+ }
364
+ }
365
+ });
366
+
367
+ var instance = view.build();
368
+ expect(called).to(be_true);
369
+ expect(callee).to(equal, instance);
370
+ });
371
+ });
372
+ });
91
373
  });
374
+ });
375
+
376
+ describe("#build", function() {
377
+ it("returns an 'instance' of the view", function() {
378
+ view.extend({
379
+ instance : {
380
+ content : function content(builder) {
381
+ builder.div('content');
382
+ },
383
+
384
+ methods : {
385
+ label : function label() {
386
+ return 'an instance';
387
+ }
388
+ }
389
+ }
390
+ });
92
391
 
93
- it("allows them to coexist", function() {
94
- expect(instance1.foo()).to(equal, "foo an instance of view1");
95
- expect(instance2.foo()).to(equal, "foo an instance of view2");
392
+ expect(view.build().label()).to(equal, 'an instance');
96
393
  });
97
394
  });
98
395
  });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coolerator.vision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Corey Innis
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-13 00:00:00 -05:00
12
+ date: 2009-11-16 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency