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 +1 -0
- data/lib/assets/javascripts/underscore.extensions.js +15 -5
- data/lib/underscore_extensions/version.rb +1 -1
- data/spec/javascripts/support/jasmine.yml +1 -0
- data/spec/javascripts/underscore.extensions_spec.js +16 -6
- data/vendor/assets/javascripts/inflection.js +139 -0
- metadata +3 -2
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
|
})(_);
|
@@ -91,14 +91,24 @@ describe('_', function() {
|
|
91
91
|
});
|
92
92
|
|
93
93
|
describe('#pluralize', function() {
|
94
|
-
it(
|
95
|
-
expect(_('point').pluralize(
|
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(
|
99
|
-
expect(_('
|
100
|
-
|
101
|
-
|
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.
|
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
|
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
|