underscore_extensions 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|