brainstem-js 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +8 -0
  2. data/.pairs +21 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.tm_properties +1 -0
  6. data/.travis.yml +12 -0
  7. data/Assetfile +79 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +50 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +143 -0
  12. data/Rakefile +25 -0
  13. data/brainstemjs.gemspec +24 -0
  14. data/lib/brainstem/js/engine.rb +5 -0
  15. data/lib/brainstem/js/version.rb +5 -0
  16. data/lib/brainstem/js.rb +10 -0
  17. data/spec/brainstem-collection-spec.coffee +141 -0
  18. data/spec/brainstem-model-spec.coffee +283 -0
  19. data/spec/brainstem-sync-spec.coffee +22 -0
  20. data/spec/brainstem-utils-spec.coffee +12 -0
  21. data/spec/brianstem-expectation-spec.coffee +209 -0
  22. data/spec/helpers/builders.coffee +80 -0
  23. data/spec/helpers/jquery-matchers.js +137 -0
  24. data/spec/helpers/models/post.coffee +14 -0
  25. data/spec/helpers/models/project.coffee +13 -0
  26. data/spec/helpers/models/task.coffee +14 -0
  27. data/spec/helpers/models/time-entry.coffee +13 -0
  28. data/spec/helpers/models/user.coffee +8 -0
  29. data/spec/helpers/spec-helper.coffee +79 -0
  30. data/spec/storage-manager-spec.coffee +613 -0
  31. data/spec/support/.DS_Store +0 -0
  32. data/spec/support/console-runner.js +103 -0
  33. data/spec/support/headless.coffee +47 -0
  34. data/spec/support/headless.html +60 -0
  35. data/spec/support/runner.html +85 -0
  36. data/spec/vendor/backbone-factory.js +62 -0
  37. data/spec/vendor/backbone.js +1571 -0
  38. data/spec/vendor/inflection.js +448 -0
  39. data/spec/vendor/jquery-1.7.js +9300 -0
  40. data/spec/vendor/jquery.cookie.js +47 -0
  41. data/spec/vendor/minispade.js +67 -0
  42. data/spec/vendor/sinon-1.3.4.js +3561 -0
  43. data/spec/vendor/underscore.js +1221 -0
  44. data/vendor/assets/.DS_Store +0 -0
  45. data/vendor/assets/javascripts/.DS_Store +0 -0
  46. data/vendor/assets/javascripts/brainstem/brainstem-collection.coffee +53 -0
  47. data/vendor/assets/javascripts/brainstem/brainstem-expectation.coffee +65 -0
  48. data/vendor/assets/javascripts/brainstem/brainstem-inflections.js +449 -0
  49. data/vendor/assets/javascripts/brainstem/brainstem-model.coffee +141 -0
  50. data/vendor/assets/javascripts/brainstem/brainstem-sync.coffee +76 -0
  51. data/vendor/assets/javascripts/brainstem/index.js +1 -0
  52. data/vendor/assets/javascripts/brainstem/iso8601.js +41 -0
  53. data/vendor/assets/javascripts/brainstem/loading-mixin.coffee +13 -0
  54. data/vendor/assets/javascripts/brainstem/storage-manager.coffee +275 -0
  55. data/vendor/assets/javascripts/brainstem/utils.coffee +35 -0
  56. metadata +198 -0
@@ -0,0 +1,448 @@
1
+ /*
2
+ Copyright (c) 2010 Ryan Schuft (ryan.schuft@gmail.com)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+
23
+ // MODIFIED: Mavenlink removed some functions from this file that we aren't using.
24
+
25
+ /*
26
+ This code is based in part on the work done in Ruby to support
27
+ infection as part of Ruby on Rails in the ActiveSupport's Inflector
28
+ and Inflections classes. It was initally ported to Javascript by
29
+ Ryan Schuft (ryan.schuft@gmail.com) in 2007.
30
+
31
+ The code is available at http://code.google.com/p/inflection-js/
32
+
33
+ The basic usage is:
34
+ 1. Include this script on your web page.
35
+ 2. Call functions on any String object in Javascript
36
+
37
+ Currently implemented functions:
38
+
39
+ String.pluralize(plural) == String
40
+ renders a singular English language noun into its plural form
41
+ normal results can be overridden by passing in an alternative
42
+
43
+ String.singularize(singular) == String
44
+ renders a plural English language noun into its singular form
45
+ normal results can be overridden by passing in an alterative
46
+
47
+ String.camelize(lowFirstLetter) == String
48
+ renders a lower case underscored word into camel case
49
+ the first letter of the result will be upper case unless you pass true
50
+ also translates "/" into "::" (underscore does the opposite)
51
+
52
+ String.underscore() == String
53
+ renders a camel cased word into words seperated by underscores
54
+ also translates "::" back into "/" (camelize does the opposite)
55
+
56
+ String.capitalize() == String
57
+ renders all characters to lower case and then makes the first upper
58
+
59
+ String.titleize() == String
60
+ renders words into title casing (as for book titles)
61
+ */
62
+
63
+ /*
64
+ This sets up a container for some constants in its own namespace
65
+ We use the window (if available) to enable dynamic loading of this script
66
+ Window won't necessarily exist for non-browsers.
67
+ */
68
+ if (window && !window.InflectionJS)
69
+ {
70
+ window.InflectionJS = null;
71
+ }
72
+
73
+ /*
74
+ This sets up some constants for later use
75
+ This should use the window namespace variable if available
76
+ */
77
+ InflectionJS =
78
+ {
79
+ /*
80
+ This is a list of nouns that use the same form for both singular and plural.
81
+ This list should remain entirely in lower case to correctly match Strings.
82
+ */
83
+ uncountable_words: [
84
+ 'equipment', 'information', 'rice', 'money', 'species', 'series',
85
+ 'fish', 'sheep', 'moose', 'deer', 'news'
86
+ ],
87
+
88
+ /*
89
+ These rules translate from the singular form of a noun to its plural form.
90
+ */
91
+ plural_rules: [
92
+ [new RegExp('(m)an$', 'gi'), '$1en'],
93
+ [new RegExp('(pe)rson$', 'gi'), '$1ople'],
94
+ [new RegExp('(child)$', 'gi'), '$1ren'],
95
+ [new RegExp('^(ox)$', 'gi'), '$1en'],
96
+ [new RegExp('(ax|test)is$', 'gi'), '$1es'],
97
+ [new RegExp('(octop|vir)us$', 'gi'), '$1i'],
98
+ [new RegExp('(alias|status)$', 'gi'), '$1es'],
99
+ [new RegExp('(bu)s$', 'gi'), '$1ses'],
100
+ [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],
101
+ [new RegExp('([ti])um$', 'gi'), '$1a'],
102
+ [new RegExp('sis$', 'gi'), 'ses'],
103
+ [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'],
104
+ [new RegExp('(hive)$', 'gi'), '$1s'],
105
+ [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'],
106
+ [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'],
107
+ [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'],
108
+ [new RegExp('([m|l])ouse$', 'gi'), '$1ice'],
109
+ [new RegExp('(quiz)$', 'gi'), '$1zes'],
110
+ [new RegExp('s$', 'gi'), 's'],
111
+ [new RegExp('$', 'gi'), 's']
112
+ ],
113
+
114
+ /*
115
+ These rules translate from the plural form of a noun to its singular form.
116
+ */
117
+ singular_rules: [
118
+ [new RegExp('(m)en$', 'gi'), '$1an'],
119
+ [new RegExp('(pe)ople$', 'gi'), '$1rson'],
120
+ [new RegExp('(child)ren$', 'gi'), '$1'],
121
+ [new RegExp('([ti])a$', 'gi'), '$1um'],
122
+ [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'],
123
+ [new RegExp('(hive)s$', 'gi'), '$1'],
124
+ [new RegExp('(tive)s$', 'gi'), '$1'],
125
+ [new RegExp('(curve)s$', 'gi'), '$1'],
126
+ [new RegExp('([lr])ves$', 'gi'), '$1f'],
127
+ [new RegExp('([^fo])ves$', 'gi'), '$1fe'],
128
+ [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'],
129
+ [new RegExp('(s)eries$', 'gi'), '$1eries'],
130
+ [new RegExp('(m)ovies$', 'gi'), '$1ovie'],
131
+ [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'],
132
+ [new RegExp('([m|l])ice$', 'gi'), '$1ouse'],
133
+ [new RegExp('(bus)es$', 'gi'), '$1'],
134
+ [new RegExp('(o)es$', 'gi'), '$1'],
135
+ [new RegExp('(shoe)s$', 'gi'), '$1'],
136
+ [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'],
137
+ [new RegExp('(octop|vir)i$', 'gi'), '$1us'],
138
+ [new RegExp('(alias|status)es$', 'gi'), '$1'],
139
+ [new RegExp('^(ox)en', 'gi'), '$1'],
140
+ [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'],
141
+ [new RegExp('(matr)ices$', 'gi'), '$1ix'],
142
+ [new RegExp('(quiz)zes$', 'gi'), '$1'],
143
+ [new RegExp('s$', 'gi'), '']
144
+ ],
145
+
146
+ /*
147
+ This is a list of words that should not be capitalized for title case
148
+ */
149
+ non_titlecased_words: [
150
+ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',
151
+ 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',
152
+ 'with', 'for'
153
+ ],
154
+
155
+ /*
156
+ These are regular expressions used for converting between String formats
157
+ */
158
+ underbar: new RegExp('_', 'g'),
159
+ space_or_underbar: new RegExp('[\ _]', 'g'),
160
+ uppercase: new RegExp('([A-Z])', 'g'),
161
+ underbar_prefix: new RegExp('^_'),
162
+
163
+ /*
164
+ This is a helper method that applies rules based replacement to a String
165
+ Signature:
166
+ InflectionJS.apply_rules(str, rules, skip, override) == String
167
+ Arguments:
168
+ str - String - String to modify and return based on the passed rules
169
+ rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement
170
+ skip - Array: [String] - Strings to skip if they match
171
+ override - String (optional) - String to return as though this method succeeded (used to conform to APIs)
172
+ Returns:
173
+ String - passed String modified by passed rules
174
+ Examples:
175
+ InflectionJS.apply_rules("cows", InflectionJs.singular_rules) === 'cow'
176
+ */
177
+ apply_rules: function(str, rules, skip, override)
178
+ {
179
+ if (override)
180
+ {
181
+ str = override;
182
+ }
183
+ else
184
+ {
185
+ var ignore = (skip.indexOf(str.toLowerCase()) > -1);
186
+ if (!ignore)
187
+ {
188
+ for (var x = 0; x < rules.length; x++)
189
+ {
190
+ if (str.match(rules[x][0]))
191
+ {
192
+ str = str.replace(rules[x][0], rules[x][1]);
193
+ break;
194
+ }
195
+ }
196
+ }
197
+ }
198
+ return str;
199
+ }
200
+ };
201
+
202
+ /*
203
+ This lets us detect if an Array contains a given element
204
+ Signature:
205
+ Array.indexOf(item, fromIndex, compareFunc) == Integer
206
+ Arguments:
207
+ item - Object - object to locate in the Array
208
+ fromIndex - Integer (optional) - starts checking from this position in the Array
209
+ compareFunc - Function (optional) - function used to compare Array item vs passed item
210
+ Returns:
211
+ Integer - index position in the Array of the passed item
212
+ Examples:
213
+ ['hi','there'].indexOf("guys") === -1
214
+ ['hi','there'].indexOf("hi") === 0
215
+ */
216
+ if (!Array.prototype.indexOf)
217
+ {
218
+ Array.prototype.indexOf = function(item, fromIndex, compareFunc)
219
+ {
220
+ if (!fromIndex)
221
+ {
222
+ fromIndex = -1;
223
+ }
224
+ var index = -1;
225
+ for (var i = fromIndex; i < this.length; i++)
226
+ {
227
+ if (this[i] === item || compareFunc && compareFunc(this[i], item))
228
+ {
229
+ index = i;
230
+ break;
231
+ }
232
+ }
233
+ return index;
234
+ };
235
+ }
236
+
237
+ /*
238
+ You can override this list for all Strings or just one depending on if you
239
+ set the new values on prototype or on a given String instance.
240
+ */
241
+ if (!String.prototype._uncountable_words)
242
+ {
243
+ String.prototype._uncountable_words = InflectionJS.uncountable_words;
244
+ }
245
+
246
+ /*
247
+ You can override this list for all Strings or just one depending on if you
248
+ set the new values on prototype or on a given String instance.
249
+ */
250
+ if (!String.prototype._plural_rules)
251
+ {
252
+ String.prototype._plural_rules = InflectionJS.plural_rules;
253
+ }
254
+
255
+ /*
256
+ You can override this list for all Strings or just one depending on if you
257
+ set the new values on prototype or on a given String instance.
258
+ */
259
+ if (!String.prototype._singular_rules)
260
+ {
261
+ String.prototype._singular_rules = InflectionJS.singular_rules;
262
+ }
263
+
264
+ /*
265
+ You can override this list for all Strings or just one depending on if you
266
+ set the new values on prototype or on a given String instance.
267
+ */
268
+ if (!String.prototype._non_titlecased_words)
269
+ {
270
+ String.prototype._non_titlecased_words = InflectionJS.non_titlecased_words;
271
+ }
272
+
273
+ /*
274
+ This function adds plurilization support to every String object
275
+ Signature:
276
+ String.pluralize(plural) == String
277
+ Arguments:
278
+ plural - String (optional) - overrides normal output with said String
279
+ Returns:
280
+ String - singular English language nouns are returned in plural form
281
+ Examples:
282
+ "person".pluralize() == "people"
283
+ "octopus".pluralize() == "octopi"
284
+ "Hat".pluralize() == "Hats"
285
+ "person".pluralize("guys") == "guys"
286
+ */
287
+ if (!String.prototype.pluralize)
288
+ {
289
+ String.prototype.pluralize = function(plural)
290
+ {
291
+ return InflectionJS.apply_rules(
292
+ this,
293
+ this._plural_rules,
294
+ this._uncountable_words,
295
+ plural
296
+ );
297
+ };
298
+ }
299
+
300
+ /*
301
+ This function adds singularization support to every String object
302
+ Signature:
303
+ String.singularize(singular) == String
304
+ Arguments:
305
+ singular - String (optional) - overrides normal output with said String
306
+ Returns:
307
+ String - plural English language nouns are returned in singular form
308
+ Examples:
309
+ "people".singularize() == "person"
310
+ "octopi".singularize() == "octopus"
311
+ "Hats".singularize() == "Hat"
312
+ "guys".singularize("person") == "person"
313
+ */
314
+ if (!String.prototype.singularize)
315
+ {
316
+ String.prototype.singularize = function(singular)
317
+ {
318
+ return InflectionJS.apply_rules(
319
+ this,
320
+ this._singular_rules,
321
+ this._uncountable_words,
322
+ singular
323
+ );
324
+ };
325
+ }
326
+
327
+ /*
328
+ This function adds camelization support to every String object
329
+ Signature:
330
+ String.camelize(lowFirstLetter) == String
331
+ Arguments:
332
+ lowFirstLetter - boolean (optional) - default is to capitalize the first
333
+ letter of the results... passing true will lowercase it
334
+ Returns:
335
+ String - lower case underscored words will be returned in camel case
336
+ additionally '/' is translated to '::'
337
+ Examples:
338
+ "message_properties".camelize() == "MessageProperties"
339
+ "message_properties".camelize(true) == "messageProperties"
340
+ */
341
+ if (!String.prototype.camelize)
342
+ {
343
+ String.prototype.camelize = function(lowFirstLetter)
344
+ {
345
+ var str = this.toLowerCase();
346
+ var str_path = str.split('/');
347
+ for (var i = 0; i < str_path.length; i++)
348
+ {
349
+ var str_arr = str_path[i].split('_');
350
+ var initX = ((lowFirstLetter && i + 1 === str_path.length) ? (1) : (0));
351
+ for (var x = initX; x < str_arr.length; x++)
352
+ {
353
+ str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1);
354
+ }
355
+ str_path[i] = str_arr.join('');
356
+ }
357
+ str = str_path.join('::');
358
+ return str;
359
+ };
360
+ }
361
+
362
+ /*
363
+ This function adds underscore support to every String object
364
+ Signature:
365
+ String.underscore() == String
366
+ Arguments:
367
+ N/A
368
+ Returns:
369
+ String - camel cased words are returned as lower cased and underscored
370
+ additionally '::' is translated to '/'
371
+ Examples:
372
+ "MessageProperties".camelize() == "message_properties"
373
+ "messageProperties".underscore() == "message_properties"
374
+ */
375
+ if (!String.prototype.underscore)
376
+ {
377
+ String.prototype.underscore = function()
378
+ {
379
+ var str = this;
380
+ var str_path = str.split('::');
381
+ for (var i = 0; i < str_path.length; i++)
382
+ {
383
+ str_path[i] = str_path[i].replace(InflectionJS.uppercase, '_$1');
384
+ str_path[i] = str_path[i].replace(InflectionJS.underbar_prefix, '');
385
+ }
386
+ str = str_path.join('/').toLowerCase();
387
+ return str;
388
+ };
389
+ }
390
+
391
+ /*
392
+ This function adds capitalization support to every String object
393
+ Signature:
394
+ String.capitalize() == String
395
+ Arguments:
396
+ N/A
397
+ Returns:
398
+ String - all characters will be lower case and the first will be upper
399
+ Examples:
400
+ "message_properties".capitalize() == "Message_properties"
401
+ "message properties".capitalize() == "Message properties"
402
+ */
403
+ if (!String.prototype.capitalize)
404
+ {
405
+ String.prototype.capitalize = function()
406
+ {
407
+ var str = this.toLowerCase();
408
+ str = str.substring(0, 1).toUpperCase() + str.substring(1);
409
+ return str;
410
+ };
411
+ }
412
+
413
+ /*
414
+ This function adds titleize support to every String object
415
+ Signature:
416
+ String.titleize() == String
417
+ Arguments:
418
+ N/A
419
+ Returns:
420
+ String - capitalizes words as you would for a book title
421
+ Examples:
422
+ "message_properties".titleize() == "Message Properties"
423
+ "message properties to keep".titleize() == "Message Properties to Keep"
424
+ */
425
+ if (!String.prototype.titleize)
426
+ {
427
+ String.prototype.titleize = function()
428
+ {
429
+ var str = this.toLowerCase();
430
+ str = str.replace(InflectionJS.underbar, ' ');
431
+ var str_arr = str.split(' ');
432
+ for (var x = 0; x < str_arr.length; x++)
433
+ {
434
+ var d = str_arr[x].split('-');
435
+ for (var i = 0; i < d.length; i++)
436
+ {
437
+ if (this._non_titlecased_words.indexOf(d[i].toLowerCase()) < 0)
438
+ {
439
+ d[i] = d[i].capitalize();
440
+ }
441
+ }
442
+ str_arr[x] = d.join('-');
443
+ }
444
+ str = str_arr.join(' ');
445
+ str = str.substring(0, 1).toUpperCase() + str.substring(1);
446
+ return str;
447
+ };
448
+ }