underscore_extensions 0.0.6 → 0.0.7

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/config/jshint.yml CHANGED
@@ -54,6 +54,7 @@ passfail: false # true if the scan should stop on first error (per file)
54
54
  # following are relevant only if undef = true
55
55
  predef:
56
56
  - _
57
+ - InflectionJS
57
58
  browser: true # true if the standard browser globals should be predefined
58
59
  rhino: false # true if the Rhino environment globals should be predefined
59
60
  windows: false # true if Windows-specific globals should be predefined
@@ -60,11 +60,21 @@
60
60
  } else {
61
61
  return only.apply(_, Array.prototype.slice.call(arguments, 1));
62
62
  }
63
- },
64
- pluralize: function(string, number, options) {
65
- options = options || {};
66
- var result = parseInt(number, 10);
67
- return result + (options.includeSpace ? ' ' : '') + string + (result === 1 ? '' : 's');
68
63
  }
69
64
  });
65
+
66
+ if (InflectionJS) {
67
+ _.mixin({
68
+ pluralize: function(obj, options) {
69
+ options = options || {};
70
+ options.skip = options.skip || '';
71
+ return InflectionJS.apply_rules(obj, InflectionJS.plural_rules, options.skip);
72
+ },
73
+ singularize: function(obj, options) {
74
+ options = options || {};
75
+ options.skip = options.skip || '';
76
+ return InflectionJS.apply_rules(obj, InflectionJS.singular_rules, options.skip);
77
+ }
78
+ });
79
+ }
70
80
  })(_);
@@ -1,5 +1,5 @@
1
1
  module UnderscoreExtensions
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.7'
3
3
  UNDERSCORE_VERSION = '1.3.3'
4
4
  UNDERSCORE_STRING_VERSION = '2.0.0'
5
5
  end
@@ -1,6 +1,7 @@
1
1
  src_files:
2
2
  - vendor/assets/javascripts/underscore.js
3
3
  - vendor/assets/javascripts/underscore.string.js
4
+ - lib/assets/javascripts/inflection.js
4
5
  - lib/assets/javascripts/underscore.extensions.js
5
6
  stylesheets:
6
7
  helpers:
@@ -91,14 +91,24 @@ describe('_', function() {
91
91
  });
92
92
 
93
93
  describe('#pluralize', function() {
94
- it('should use a space when includeSpace is passed in the options', function() {
95
- expect(_('point').pluralize(2, {includeSpace: true})).toEqual('2 points');
94
+ it("should pluralize a model name", function() {
95
+ expect(_('point').pluralize()).toEqual('points');
96
+ expect(_('story').pluralize()).toEqual('stories');
96
97
  });
97
98
 
98
- it('should return a pluralized string based on the number', function() {
99
- expect(_('point').pluralize(0)).toEqual('0points');
100
- expect(_('point').pluralize(1)).toEqual('1point');
101
- expect(_('point').pluralize(2)).toEqual('2points');
99
+ it("should pass the skip option", function() {
100
+ expect(_('foo').pluralize({skip: 'foo'})).toEqual('foo');
101
+ });
102
+ });
103
+
104
+ describe('#singularize', function() {
105
+ it("should singularize a model name", function() {
106
+ expect(_('octopi').singularize()).toEqual('octopus');
107
+ expect(_('stories').singularize()).toEqual('story');
108
+ });
109
+
110
+ it("should pass the skip option", function() {
111
+ expect(_('foos').singularize({skip: 'foos'})).toEqual('foos');
102
112
  });
103
113
  });
104
114
  });
@@ -0,0 +1,139 @@
1
+ /*
2
+ This sets up a container for some constants in its own namespace
3
+ We use the window (if available) to enable dynamic loading of this script
4
+ Window won't necessarily exist for non-browsers.
5
+ */
6
+ if (window && !window.InflectionJS)
7
+ {
8
+ window.InflectionJS = null;
9
+ }
10
+
11
+ /*
12
+ This sets up some constants for later use
13
+ This should use the window namespace variable if available
14
+ */
15
+ InflectionJS =
16
+ {
17
+ /*
18
+ This is a list of nouns that use the same form for both singular and plural.
19
+ This list should remain entirely in lower case to correctly match Strings.
20
+ */
21
+ uncountable_words: [
22
+ 'equipment', 'information', 'rice', 'money', 'species', 'series',
23
+ 'fish', 'sheep', 'moose', 'deer', 'news'
24
+ ],
25
+
26
+ /*
27
+ These rules translate from the singular form of a noun to its plural form.
28
+ */
29
+ plural_rules: [
30
+ [new RegExp('(m)an$', 'gi'), '$1en'],
31
+ [new RegExp('(pe)rson$', 'gi'), '$1ople'],
32
+ [new RegExp('(child)$', 'gi'), '$1ren'],
33
+ [new RegExp('^(ox)$', 'gi'), '$1en'],
34
+ [new RegExp('(ax|test)is$', 'gi'), '$1es'],
35
+ [new RegExp('(octop|vir)us$', 'gi'), '$1i'],
36
+ [new RegExp('(alias|status)$', 'gi'), '$1es'],
37
+ [new RegExp('(bu)s$', 'gi'), '$1ses'],
38
+ [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],
39
+ [new RegExp('([ti])um$', 'gi'), '$1a'],
40
+ [new RegExp('sis$', 'gi'), 'ses'],
41
+ [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'],
42
+ [new RegExp('(hive)$', 'gi'), '$1s'],
43
+ [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'],
44
+ [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'],
45
+ [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'],
46
+ [new RegExp('([m|l])ouse$', 'gi'), '$1ice'],
47
+ [new RegExp('(quiz)$', 'gi'), '$1zes'],
48
+ [new RegExp('s$', 'gi'), 's'],
49
+ [new RegExp('$', 'gi'), 's']
50
+ ],
51
+
52
+ /*
53
+ These rules translate from the plural form of a noun to its singular form.
54
+ */
55
+ singular_rules: [
56
+ [new RegExp('(m)en$', 'gi'), '$1an'],
57
+ [new RegExp('(pe)ople$', 'gi'), '$1rson'],
58
+ [new RegExp('(child)ren$', 'gi'), '$1'],
59
+ [new RegExp('([ti])a$', 'gi'), '$1um'],
60
+ [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'],
61
+ [new RegExp('(hive)s$', 'gi'), '$1'],
62
+ [new RegExp('(tive)s$', 'gi'), '$1'],
63
+ [new RegExp('(curve)s$', 'gi'), '$1'],
64
+ [new RegExp('([lr])ves$', 'gi'), '$1f'],
65
+ [new RegExp('([^fo])ves$', 'gi'), '$1fe'],
66
+ [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'],
67
+ [new RegExp('(s)eries$', 'gi'), '$1eries'],
68
+ [new RegExp('(m)ovies$', 'gi'), '$1ovie'],
69
+ [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'],
70
+ [new RegExp('([m|l])ice$', 'gi'), '$1ouse'],
71
+ [new RegExp('(bus)es$', 'gi'), '$1'],
72
+ [new RegExp('(o)es$', 'gi'), '$1'],
73
+ [new RegExp('(shoe)s$', 'gi'), '$1'],
74
+ [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'],
75
+ [new RegExp('(octop|vir)i$', 'gi'), '$1us'],
76
+ [new RegExp('(alias|status)es$', 'gi'), '$1'],
77
+ [new RegExp('^(ox)en', 'gi'), '$1'],
78
+ [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'],
79
+ [new RegExp('(matr)ices$', 'gi'), '$1ix'],
80
+ [new RegExp('(quiz)zes$', 'gi'), '$1'],
81
+ [new RegExp('s$', 'gi'), '']
82
+ ],
83
+
84
+ /*
85
+ This is a list of words that should not be capitalized for title case
86
+ */
87
+ non_titlecased_words: [
88
+ 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',
89
+ 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',
90
+ 'with', 'for'
91
+ ],
92
+
93
+ /*
94
+ These are regular expressions used for converting between String formats
95
+ */
96
+ id_suffix: new RegExp('(_ids|_id)$', 'g'),
97
+ underbar: new RegExp('_', 'g'),
98
+ space_or_underbar: new RegExp('[\ _]', 'g'),
99
+ uppercase: new RegExp('([A-Z])', 'g'),
100
+ underbar_prefix: new RegExp('^_'),
101
+
102
+ /*
103
+ This is a helper method that applies rules based replacement to a String
104
+ Signature:
105
+ InflectionJS.apply_rules(str, rules, skip, override) == String
106
+ Arguments:
107
+ str - String - String to modify and return based on the passed rules
108
+ rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement
109
+ skip - Array: [String] - Strings to skip if they match
110
+ override - String (optional) - String to return as though this method succeeded (used to conform to APIs)
111
+ Returns:
112
+ String - passed String modified by passed rules
113
+ Examples:
114
+ InflectionJS.apply_rules("cows", InflectionJs.singular_rules) === 'cow'
115
+ */
116
+ apply_rules: function(str, rules, skip, override)
117
+ {
118
+ if (override)
119
+ {
120
+ str = override;
121
+ }
122
+ else
123
+ {
124
+ var ignore = (skip.indexOf(str.toLowerCase()) > -1);
125
+ if (!ignore)
126
+ {
127
+ for (var x = 0; x < rules.length; x++)
128
+ {
129
+ if (str.match(rules[x][0]))
130
+ {
131
+ str = str.replace(rules[x][0], rules[x][1]);
132
+ break;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ return str;
138
+ }
139
+ };
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: underscore_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-20 00:00:00.000000000 Z
12
+ date: 2012-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fuubar
@@ -130,6 +130,7 @@ files:
130
130
  - spec/javascripts/support/spec_helper.js
131
131
  - spec/javascripts/underscore.extensions_spec.js
132
132
  - underscore_extensions.gemspec
133
+ - vendor/assets/javascripts/inflection.js
133
134
  - vendor/assets/javascripts/underscore.js
134
135
  - vendor/assets/javascripts/underscore.string.js
135
136
  homepage: http://github.com/rdy/underscore_extensions