jinx 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/.gitignore +14 -0
  2. data/.rspec +3 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +27 -0
  6. data/History.md +6 -0
  7. data/LEGAL +5 -0
  8. data/LICENSE +22 -0
  9. data/README.md +44 -0
  10. data/Rakefile +41 -0
  11. data/examples/family/README.md +10 -0
  12. data/examples/family/ext/build.xml +35 -0
  13. data/examples/family/ext/src/family/Address.java +68 -0
  14. data/examples/family/ext/src/family/Child.java +24 -0
  15. data/examples/family/ext/src/family/DomainObject.java +26 -0
  16. data/examples/family/ext/src/family/Household.java +36 -0
  17. data/examples/family/ext/src/family/Parent.java +48 -0
  18. data/examples/family/ext/src/family/Person.java +42 -0
  19. data/examples/family/lib/family.rb +15 -0
  20. data/examples/family/lib/family/address.rb +6 -0
  21. data/examples/family/lib/family/domain_object.rb +6 -0
  22. data/examples/family/lib/family/household.rb +6 -0
  23. data/examples/family/lib/family/parent.rb +16 -0
  24. data/examples/family/lib/family/person.rb +6 -0
  25. data/examples/model/README.md +25 -0
  26. data/examples/model/ext/build.xml +35 -0
  27. data/examples/model/ext/src/domain/Child.java +192 -0
  28. data/examples/model/ext/src/domain/Dependent.java +29 -0
  29. data/examples/model/ext/src/domain/DomainObject.java +26 -0
  30. data/examples/model/ext/src/domain/Independent.java +83 -0
  31. data/examples/model/ext/src/domain/Parent.java +129 -0
  32. data/examples/model/ext/src/domain/Person.java +14 -0
  33. data/examples/model/lib/model.rb +13 -0
  34. data/examples/model/lib/model/child.rb +13 -0
  35. data/examples/model/lib/model/domain_object.rb +6 -0
  36. data/examples/model/lib/model/independent.rb +11 -0
  37. data/examples/model/lib/model/parent.rb +17 -0
  38. data/jinx.gemspec +22 -0
  39. data/lib/jinx.rb +3 -0
  40. data/lib/jinx/active_support/README.txt +2 -0
  41. data/lib/jinx/active_support/core_ext/string.rb +7 -0
  42. data/lib/jinx/active_support/core_ext/string/inflections.rb +167 -0
  43. data/lib/jinx/active_support/inflections.rb +55 -0
  44. data/lib/jinx/active_support/inflector.rb +398 -0
  45. data/lib/jinx/cli/application.rb +36 -0
  46. data/lib/jinx/cli/command.rb +214 -0
  47. data/lib/jinx/helpers/array.rb +108 -0
  48. data/lib/jinx/helpers/boolean.rb +42 -0
  49. data/lib/jinx/helpers/case_insensitive_hash.rb +39 -0
  50. data/lib/jinx/helpers/class.rb +149 -0
  51. data/lib/jinx/helpers/collection.rb +33 -0
  52. data/lib/jinx/helpers/collections.rb +11 -0
  53. data/lib/jinx/helpers/collector.rb +20 -0
  54. data/lib/jinx/helpers/conditional_enumerator.rb +21 -0
  55. data/lib/jinx/helpers/enumerable.rb +242 -0
  56. data/lib/jinx/helpers/enumerate.rb +35 -0
  57. data/lib/jinx/helpers/error.rb +15 -0
  58. data/lib/jinx/helpers/file_separator.rb +65 -0
  59. data/lib/jinx/helpers/filter.rb +52 -0
  60. data/lib/jinx/helpers/flattener.rb +38 -0
  61. data/lib/jinx/helpers/hash.rb +12 -0
  62. data/lib/jinx/helpers/hashable.rb +502 -0
  63. data/lib/jinx/helpers/inflector.rb +36 -0
  64. data/lib/jinx/helpers/key_transformer_hash.rb +43 -0
  65. data/lib/jinx/helpers/lazy_hash.rb +44 -0
  66. data/lib/jinx/helpers/log.rb +106 -0
  67. data/lib/jinx/helpers/math.rb +12 -0
  68. data/lib/jinx/helpers/merge.rb +60 -0
  69. data/lib/jinx/helpers/module.rb +18 -0
  70. data/lib/jinx/helpers/multi_enumerator.rb +31 -0
  71. data/lib/jinx/helpers/options.rb +92 -0
  72. data/lib/jinx/helpers/os.rb +19 -0
  73. data/lib/jinx/helpers/partial_order.rb +37 -0
  74. data/lib/jinx/helpers/pretty_print.rb +207 -0
  75. data/lib/jinx/helpers/set.rb +8 -0
  76. data/lib/jinx/helpers/stopwatch.rb +76 -0
  77. data/lib/jinx/helpers/transformer.rb +24 -0
  78. data/lib/jinx/helpers/transitive_closure.rb +55 -0
  79. data/lib/jinx/helpers/uniquifier.rb +50 -0
  80. data/lib/jinx/helpers/validation.rb +33 -0
  81. data/lib/jinx/helpers/visitor.rb +370 -0
  82. data/lib/jinx/import/class_path_modifier.rb +77 -0
  83. data/lib/jinx/import/java.rb +337 -0
  84. data/lib/jinx/importer.rb +240 -0
  85. data/lib/jinx/metadata.rb +155 -0
  86. data/lib/jinx/metadata/attribute_enumerator.rb +73 -0
  87. data/lib/jinx/metadata/dependency.rb +244 -0
  88. data/lib/jinx/metadata/id_alias.rb +23 -0
  89. data/lib/jinx/metadata/introspector.rb +179 -0
  90. data/lib/jinx/metadata/inverse.rb +170 -0
  91. data/lib/jinx/metadata/java_property.rb +169 -0
  92. data/lib/jinx/metadata/propertied.rb +500 -0
  93. data/lib/jinx/metadata/property.rb +401 -0
  94. data/lib/jinx/metadata/property_characteristics.rb +114 -0
  95. data/lib/jinx/resource.rb +862 -0
  96. data/lib/jinx/resource/copy_visitor.rb +36 -0
  97. data/lib/jinx/resource/inversible.rb +90 -0
  98. data/lib/jinx/resource/match_visitor.rb +180 -0
  99. data/lib/jinx/resource/matcher.rb +20 -0
  100. data/lib/jinx/resource/merge_visitor.rb +73 -0
  101. data/lib/jinx/resource/mergeable.rb +185 -0
  102. data/lib/jinx/resource/reference_enumerator.rb +49 -0
  103. data/lib/jinx/resource/reference_path_visitor.rb +38 -0
  104. data/lib/jinx/resource/reference_visitor.rb +55 -0
  105. data/lib/jinx/resource/unique.rb +35 -0
  106. data/lib/jinx/version.rb +3 -0
  107. data/spec/defaults_spec.rb +30 -0
  108. data/spec/definitions/model/alias/child.rb +5 -0
  109. data/spec/definitions/model/base/child.rb +5 -0
  110. data/spec/definitions/model/base/domain_object.rb +5 -0
  111. data/spec/definitions/model/base/independent.rb +5 -0
  112. data/spec/definitions/model/defaults/child.rb +5 -0
  113. data/spec/definitions/model/dependency/child.rb +5 -0
  114. data/spec/definitions/model/dependency/parent.rb +6 -0
  115. data/spec/definitions/model/inverse/child.rb +5 -0
  116. data/spec/definitions/model/inverse/independent.rb +5 -0
  117. data/spec/definitions/model/inverse/parent.rb +5 -0
  118. data/spec/definitions/model/mandatory/child.rb +6 -0
  119. data/spec/dependency_spec.rb +47 -0
  120. data/spec/family_spec.rb +64 -0
  121. data/spec/inverse_spec.rb +53 -0
  122. data/spec/mandatory_spec.rb +43 -0
  123. data/spec/metadata_spec.rb +68 -0
  124. data/spec/resource_spec.rb +30 -0
  125. data/spec/spec_helper.rb +3 -0
  126. data/spec/support/model.rb +19 -0
  127. data/test/fixtures/line_separator/cr_line_sep.txt +1 -0
  128. data/test/fixtures/line_separator/crlf_line_sep.txt +3 -0
  129. data/test/fixtures/line_separator/lf_line_sep.txt +3 -0
  130. data/test/fixtures/mixed/ext/build.xml +35 -0
  131. data/test/fixtures/mixed/ext/src/mixed/Case/Example.java +5 -0
  132. data/test/helper.rb +7 -0
  133. data/test/lib/jinx/command_test.rb +41 -0
  134. data/test/lib/jinx/helpers/boolean_test.rb +27 -0
  135. data/test/lib/jinx/helpers/class_test.rb +60 -0
  136. data/test/lib/jinx/helpers/collections_test.rb +402 -0
  137. data/test/lib/jinx/helpers/file_separator_test.rb +29 -0
  138. data/test/lib/jinx/helpers/inflector_test.rb +11 -0
  139. data/test/lib/jinx/helpers/lazy_hash_test.rb +32 -0
  140. data/test/lib/jinx/helpers/module_test.rb +24 -0
  141. data/test/lib/jinx/helpers/options_test.rb +66 -0
  142. data/test/lib/jinx/helpers/partial_order_test.rb +41 -0
  143. data/test/lib/jinx/helpers/pretty_print_test.rb +83 -0
  144. data/test/lib/jinx/helpers/stopwatch_test.rb +16 -0
  145. data/test/lib/jinx/helpers/transitive_closure_test.rb +80 -0
  146. data/test/lib/jinx/helpers/visitor_test.rb +288 -0
  147. data/test/lib/jinx/import/java_test.rb +78 -0
  148. data/test/lib/jinx/import/mixed_case_test.rb +16 -0
  149. metadata +272 -0
@@ -0,0 +1,129 @@
1
+ package domain;
2
+
3
+ import java.util.Collection;
4
+ import java.util.ArrayList;
5
+
6
+ public class Parent extends DomainObject implements Person
7
+ {
8
+ /**
9
+ * A string property.
10
+ */
11
+ private String name;
12
+
13
+ /**
14
+ * The parent's spouse.
15
+ * <p>
16
+ * This property exercises a 1:1 self-reference.
17
+ * </p>
18
+ */
19
+ private Parent spouse;
20
+
21
+ /**
22
+ * This parent's children.
23
+ * <p>
24
+ * This property exercises a reference from an owner to dependents.
25
+ * </p>
26
+ */
27
+ private Collection<Child> children;
28
+
29
+ /**
30
+ * This parent's independent reference.
31
+ * <p>
32
+ * This property exercises a reference to an independent object.
33
+ * </p>
34
+ */
35
+ private Independent indy;
36
+
37
+ /**
38
+ * This parent's uni-directional dependent reference.
39
+ * <p>
40
+ * This property exercises a reference to a uni-directional dependent object.
41
+ * </p>
42
+ */
43
+ private Dependent dependent;
44
+
45
+ public Parent()
46
+ {
47
+ children = new ArrayList<Child>();
48
+ }
49
+
50
+ /**
51
+ * @return the name
52
+ */
53
+ public String getName()
54
+ {
55
+ return name;
56
+ }
57
+
58
+ /**
59
+ * @param name the name to set
60
+ */
61
+ public void setName(String name)
62
+ {
63
+ this.name = name;
64
+ }
65
+
66
+ /**
67
+ * @return the spouse
68
+ */
69
+ public Parent getSpouse()
70
+ {
71
+ return spouse;
72
+ }
73
+
74
+ /**
75
+ * @param spouse the spouse to set
76
+ */
77
+ public void setSpouse(Parent spouse)
78
+ {
79
+ this.spouse = spouse;
80
+ }
81
+
82
+ /**
83
+ * @return the children
84
+ */
85
+ public Collection<Child> getChildren()
86
+ {
87
+ return children;
88
+ }
89
+
90
+ /**
91
+ * @param children the children to set
92
+ */
93
+ public void setChildren(Collection<Child> children)
94
+ {
95
+ this.children = children;
96
+ }
97
+
98
+ /**
99
+ * @return the child independent reference
100
+ */
101
+ public Independent getIndy()
102
+ {
103
+ return indy;
104
+ }
105
+
106
+ /**
107
+ * @param indy the child independent reference to set
108
+ */
109
+ public void setIndy(Independent indy)
110
+ {
111
+ this.indy = indy;
112
+ }
113
+
114
+ /**
115
+ * @return the dependent
116
+ */
117
+ public Dependent getDependent()
118
+ {
119
+ return dependent;
120
+ }
121
+
122
+ /**
123
+ * @param dependent the dependent to set
124
+ */
125
+ public void setDependent(Dependent dependent)
126
+ {
127
+ this.dependent = dependent;
128
+ }
129
+ }
@@ -0,0 +1,14 @@
1
+ package domain;
2
+
3
+ public interface Person
4
+ {
5
+ /**
6
+ * @return the name
7
+ */
8
+ public String getName();
9
+
10
+ /**
11
+ * @param name the name to set
12
+ */
13
+ public void setName(String name);
14
+ }
@@ -0,0 +1,13 @@
1
+ # Add the Java jar file to the Java path.
2
+ require File.dirname(__FILE__) + '/../ext/bin/model.jar'
3
+
4
+ # The Jinx Model example application domain module.
5
+ module Model
6
+ include Jinx::Resource
7
+
8
+ # The Java package name.
9
+ packages 'domain'
10
+
11
+ # The JRuby mix-ins are in the model subdirectory.
12
+ definitions File.dirname(__FILE__) + '/model'
13
+ end
@@ -0,0 +1,13 @@
1
+ module Model
2
+ class Child
3
+ # The friends property has a pals
4
+ property :friends, :alias => :pals
5
+
6
+ # The default cardinal value is 1.
7
+ property :cardinal, :default => 1
8
+
9
+ # The secondary key is the name scoped by the parent.
10
+ property :parent, :secondary_key
11
+ property :name, :secondary_key
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Model
2
+ class DomainObject
3
+ # The identifier property is the primary key.
4
+ property :identifier, :primary_key
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module Model
2
+ class Independent
3
+ # The others property is a M:N association without a parameterized type.
4
+ # Specify the type here, since it cannot be introspected. The inverse
5
+ # of a source object is the target object others property value.
6
+ property :others, :type => self, :inverse => :others
7
+
8
+ # The secondary key is the name.
9
+ property :name, :secondary_key
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Model
2
+ class Parent
3
+ # A parent owns children.
4
+ property :children, :dependent
5
+
6
+ # The parent dependent attribute references a Dependent. The dependent
7
+ # attribute is, not surprisingly, designated as a dependent reference.
8
+ property :dependent, :dependent
9
+
10
+ # The spouse is an independent reference. The spouse is an idempotent inverse,
11
+ # i.e. parent = parent.spouse.spouse.
12
+ property :spouse, :inverse => :spouse
13
+
14
+ # The secondary key is the name.
15
+ property :name, :secondary_key
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/lib/jinx/version'
2
+ require 'date'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'jinx'
6
+ s.summary = 'Jruby INtrospeXion facade.'
7
+ s.description = s.summary + '. See github.com/jinx/core for more information.'
8
+ s.version = Jinx::VERSION
9
+ s.date = Date.today
10
+ s.author = 'OHSU'
11
+ s.email = 'jinx.ruby@gmail.com'
12
+ s.homepage = 'http://github.com/jinx/core'
13
+ s.require_path = 'lib'
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files test`.split("\n")
16
+ s.add_runtime_dependency 'bundler'
17
+ s.add_development_dependency 'rake'
18
+ s.add_development_dependency 'rspec', '>= 2.6'
19
+ s.has_rdoc = 'yard'
20
+ s.license = 'MIT'
21
+ s.rubyforge_project = 'caruby'
22
+ end
@@ -0,0 +1,3 @@
1
+ require 'jinx/helpers/log'
2
+ require 'jinx/helpers/error'
3
+ require 'jinx/resource'
@@ -0,0 +1,2 @@
1
+ The files in this directory are shamelessly stolen from Rails. They are included here rather than pulled in as a gem
2
+ in order to avoid a dependency on the entire Rails project for a limited utility.
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_support/core_ext/string/inflections'
4
+
5
+ class String #:nodoc:
6
+ include ActiveSupport::CoreExtensions::String::Inflections
7
+ end
@@ -0,0 +1,167 @@
1
+ require 'jinx/active_support/inflector'
2
+
3
+ module ActiveSupport #:nodoc:
4
+ module CoreExtensions #:nodoc:
5
+ module String #:nodoc:
6
+ # String inflections define new methods on the String class to transform names for different purposes.
7
+ # For instance, you can figure out the name of a database from the name of a class.
8
+ #
9
+ # "ScaleScore".tableize #=>"scale_scores"
10
+ module Inflections
11
+ # Returns the plural form of the word in the string.
12
+ #
13
+ # "post".pluralize #=>"posts"
14
+ # "octopus".pluralize #=>"octopi"
15
+ # "sheep".pluralize #=>"sheep"
16
+ # "words".pluralize #=>"words"
17
+ # "the blue mailman".pluralize #=>"the blue mailmen"
18
+ # "CamelOctopus".pluralize #=>"CamelOctopi"
19
+ def pluralize
20
+ Inflector.pluralize(self)
21
+ end
22
+
23
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
24
+ #
25
+ # "posts".singularize #=>"post"
26
+ # "octopi".singularize #=>"octopus"
27
+ # "sheep".singularize #=>"sheep"
28
+ # "word".singularize #=>"word"
29
+ # "the blue mailmen".singularize #=>"the blue mailman"
30
+ # "CamelOctopi".singularize #=>"CamelOctopus"
31
+ def singularize
32
+ Inflector.singularize(self)
33
+ end
34
+
35
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
36
+ # is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
37
+ #
38
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
39
+ #
40
+ # "active_record".camelize #=>"ActiveRecord"
41
+ # "active_record".camelize(:lower) #=>"activeRecord"
42
+ # "active_record/errors".camelize #=>"ActiveRecord::Errors"
43
+ # "active_record/errors".camelize(:lower) #=>"activeRecord::Errors"
44
+ def camelize(first_letter = :upper)
45
+ case first_letter
46
+ when :upper then Inflector.camelize(self, true)
47
+ when :lower then Inflector.camelize(self, false)
48
+ end
49
+ end
50
+ alias_method :camelcase, :camelize
51
+
52
+ # Capitalizes all the words and replaces some characters in the string to create
53
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
54
+ # used in the Rails internals.
55
+ #
56
+ # +titleize+ is also aliased as +titlecase+.
57
+ #
58
+ # "man from the boondocks".titleize #=>"Man From The Boondocks"
59
+ # "x-men: the last stand".titleize #=>"X Men: The Last Stand"
60
+ def titleize
61
+ Inflector.titleize(self)
62
+ end
63
+ alias_method :titlecase, :titleize
64
+
65
+ # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
66
+ #
67
+ # +underscore+ will also change '::' to '/' to convert namespaces to paths.
68
+ #
69
+ # "ActiveRecord".underscore #=>"active_record"
70
+ # "ActiveRecord::Errors".underscore #=>active_record/errors
71
+ def underscore
72
+ Inflector.underscore(self)
73
+ end
74
+
75
+ # Replaces underscores with dashes in the string.
76
+ #
77
+ # "puni_puni" #=>"puni-puni"
78
+ def dasherize
79
+ Inflector.dasherize(self)
80
+ end
81
+
82
+ # Removes the module part from the constant expression in the string.
83
+ #
84
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize #=>"Inflections"
85
+ # "Inflections".demodulize #=>"Inflections"
86
+ def demodulize
87
+ Inflector.demodulize(self)
88
+ end
89
+
90
+ # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
91
+ #
92
+ # ==== Examples
93
+ #
94
+ # class Person
95
+ # def to_param
96
+ # "#{id}-#{name.parameterize}"
97
+ # end
98
+ # end
99
+ #
100
+ # @person = Person.find(1)
101
+ # #=>#<Person id: 1, name: "Donald E. Knuth">
102
+ #
103
+ # <%= link_to(@person.name, person_path %>
104
+ # #=><a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
105
+ def parameterize
106
+ Inflector.parameterize(self)
107
+ end
108
+
109
+ # Creates the name of a table like Rails does for models to table names. This method
110
+ # uses the +pluralize+ method on the last word in the string.
111
+ #
112
+ # "RawScaledScorer".tableize #=>"raw_scaled_scorers"
113
+ # "egg_and_ham".tableize #=>"egg_and_hams"
114
+ # "fancyCategory".tableize #=>"fancy_categories"
115
+ def tableize
116
+ Inflector.tableize(self)
117
+ end
118
+
119
+ # Create a class name from a plural table name like Rails does for table names to models.
120
+ # Note that this returns a string and not a class. (To convert to an actual class
121
+ # follow +classify+ with +constantize+.)
122
+ #
123
+ # "egg_and_hams".classify #=>"EggAndHam"
124
+ # "posts".classify #=>"Post"
125
+ #
126
+ # Singular names are not handled correctly.
127
+ #
128
+ # "business".classify #=>"Busines"
129
+ def classify
130
+ Inflector.classify(self)
131
+ end
132
+
133
+ # Capitalizes the first word, turns underscores into spaces, and strips '_id'.
134
+ # Like +titleize+, this is meant for creating pretty output.
135
+ #
136
+ # "employee_salary" #=>"Employee salary"
137
+ # "author_id" #=>"Author"
138
+ def humanize
139
+ Inflector.humanize(self)
140
+ end
141
+
142
+ # Creates a foreign key name from a class name.
143
+ # +separate_class_name_and_id_with_underscore+ sets whether
144
+ # the method should put '_' between the name and 'id'.
145
+ #
146
+ # Examples
147
+ # "Message".foreign_key #=>"message_id"
148
+ # "Message".foreign_key(false) #=>"messageid"
149
+ # "Admin::Post".foreign_key #=>"post_id"
150
+ def foreign_key(separate_class_name_and_id_with_underscore = true)
151
+ Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
152
+ end
153
+
154
+ # +constantize+ tries to find a declared constant with the name specified
155
+ # in the string. It raises a NameError when the name is not in CamelCase
156
+ # or is not initialized.
157
+ #
158
+ # Examples
159
+ # "Module".constantize #=>Module
160
+ # "Class".constantize #=>Class
161
+ def constantize
162
+ Inflector.constantize(self)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,55 @@
1
+ module ActiveSupport
2
+ Inflector.inflections do |inflect|
3
+ inflect.plural(/$/, 's')
4
+ inflect.plural(/s$/i, 's')
5
+ inflect.plural(/(ax|test)is$/i, '\1es')
6
+ inflect.plural(/(octop|vir)us$/i, '\1i')
7
+ inflect.plural(/(alias|status)$/i, '\1es')
8
+ inflect.plural(/(bu)s$/i, '\1ses')
9
+ inflect.plural(/(buffal|tomat)o$/i, '\1oes')
10
+ inflect.plural(/([ti])um$/i, '\1a')
11
+ inflect.plural(/sis$/i, 'ses')
12
+ inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
13
+ inflect.plural(/(hive)$/i, '\1s')
14
+ inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
15
+ inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
16
+ inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
17
+ inflect.plural(/([m|l])ouse$/i, '\1ice')
18
+ inflect.plural(/^(ox)$/i, '\1en')
19
+ inflect.plural(/(quiz)$/i, '\1zes')
20
+
21
+ inflect.singular(/s$/i, '')
22
+ inflect.singular(/(n)ews$/i, '\1ews')
23
+ inflect.singular(/([ti])a$/i, '\1um')
24
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
25
+ inflect.singular(/(^analy)ses$/i, '\1sis')
26
+ inflect.singular(/([^f])ves$/i, '\1fe')
27
+ inflect.singular(/(hive)s$/i, '\1')
28
+ inflect.singular(/(tive)s$/i, '\1')
29
+ inflect.singular(/([lr])ves$/i, '\1f')
30
+ inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
31
+ inflect.singular(/(s)eries$/i, '\1eries')
32
+ inflect.singular(/(m)ovies$/i, '\1ovie')
33
+ inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
34
+ inflect.singular(/([m|l])ice$/i, '\1ouse')
35
+ inflect.singular(/(bus)es$/i, '\1')
36
+ inflect.singular(/(o)es$/i, '\1')
37
+ inflect.singular(/(shoe)s$/i, '\1')
38
+ inflect.singular(/(cris|ax|test)es$/i, '\1is')
39
+ inflect.singular(/(octop|vir)i$/i, '\1us')
40
+ inflect.singular(/(alias|status)es$/i, '\1')
41
+ inflect.singular(/^(ox)en/i, '\1')
42
+ inflect.singular(/(vert|ind)ices$/i, '\1ex')
43
+ inflect.singular(/(matr)ices$/i, '\1ix')
44
+ inflect.singular(/(quiz)zes$/i, '\1')
45
+
46
+ inflect.irregular('person', 'people')
47
+ inflect.irregular('man', 'men')
48
+ inflect.irregular('child', 'children')
49
+ inflect.irregular('sex', 'sexes')
50
+ inflect.irregular('move', 'moves')
51
+ inflect.irregular('cow', 'kine')
52
+
53
+ inflect.uncountable(%w(equipment information rice money species series fish sheep))
54
+ end
55
+ end