volt 0.8.14 → 0.8.15

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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Readme.md +8 -2
  4. data/VERSION +1 -1
  5. data/app/volt/controllers/notices_controller.rb +1 -1
  6. data/app/volt/models/user.rb +2 -2
  7. data/app/volt/tasks/live_query/live_query_pool.rb +1 -1
  8. data/app/volt/tasks/query_tasks.rb +1 -1
  9. data/app/volt/tasks/store_tasks.rb +1 -1
  10. data/app/volt/tasks/user_tasks.rb +2 -2
  11. data/lib/volt/boot.rb +2 -2
  12. data/lib/volt/cli/asset_compile.rb +31 -27
  13. data/lib/volt/cli.rb +64 -65
  14. data/lib/volt/config.rb +25 -23
  15. data/lib/volt/console.rb +17 -16
  16. data/lib/volt/controllers/model_controller.rb +82 -80
  17. data/lib/volt/data_stores/data_store.rb +2 -2
  18. data/lib/volt/data_stores/mongo_driver.rb +2 -2
  19. data/lib/volt/extra_core/inflections.rb +2 -2
  20. data/lib/volt/extra_core/inflector/inflections.rb +185 -183
  21. data/lib/volt/extra_core/inflector/methods.rb +50 -48
  22. data/lib/volt/extra_core/string.rb +2 -2
  23. data/lib/volt/models/array_model.rb +93 -92
  24. data/lib/volt/models/cursor.rb +3 -2
  25. data/lib/volt/models/model.rb +248 -251
  26. data/lib/volt/models/model_hash_behaviour.rb +44 -44
  27. data/lib/volt/models/model_helpers.rb +38 -36
  28. data/lib/volt/models/model_state.rb +16 -17
  29. data/lib/volt/models/model_wrapper.rb +25 -24
  30. data/lib/volt/models/persistors/array_store.rb +145 -143
  31. data/lib/volt/models/persistors/base.rb +18 -16
  32. data/lib/volt/models/persistors/flash.rb +24 -22
  33. data/lib/volt/models/persistors/local_store.rb +46 -44
  34. data/lib/volt/models/persistors/model_identity_map.rb +10 -8
  35. data/lib/volt/models/persistors/model_store.rb +76 -76
  36. data/lib/volt/models/persistors/params.rb +19 -17
  37. data/lib/volt/models/persistors/query/query_listener.rb +65 -63
  38. data/lib/volt/models/persistors/query/query_listener_pool.rb +12 -10
  39. data/lib/volt/models/persistors/store.rb +28 -28
  40. data/lib/volt/models/persistors/store_factory.rb +12 -10
  41. data/lib/volt/models/persistors/store_state.rb +33 -31
  42. data/lib/volt/models/url.rb +96 -104
  43. data/lib/volt/models/validations.rb +56 -54
  44. data/lib/volt/models/validators/length_validator.rb +24 -22
  45. data/lib/volt/models/validators/presence_validator.rb +14 -12
  46. data/lib/volt/page/bindings/attribute_binding.rb +106 -106
  47. data/lib/volt/page/bindings/base_binding.rb +23 -21
  48. data/lib/volt/page/bindings/component_binding.rb +3 -1
  49. data/lib/volt/page/bindings/content_binding.rb +34 -34
  50. data/lib/volt/page/bindings/each_binding.rb +113 -113
  51. data/lib/volt/page/bindings/event_binding.rb +38 -34
  52. data/lib/volt/page/bindings/if_binding.rb +56 -54
  53. data/lib/volt/page/bindings/template_binding/grouped_controllers.rb +24 -22
  54. data/lib/volt/page/bindings/template_binding.rb +182 -185
  55. data/lib/volt/page/channel.rb +79 -77
  56. data/lib/volt/page/channel_stub.rb +29 -27
  57. data/lib/volt/page/document.rb +6 -5
  58. data/lib/volt/page/document_events.rb +54 -52
  59. data/lib/volt/page/page.rb +139 -138
  60. data/lib/volt/page/string_template_renderer.rb +36 -36
  61. data/lib/volt/page/sub_context.rb +26 -25
  62. data/lib/volt/page/targets/attribute_section.rb +27 -25
  63. data/lib/volt/page/targets/attribute_target.rb +7 -6
  64. data/lib/volt/page/targets/base_section.rb +27 -26
  65. data/lib/volt/page/targets/binding_document/base_node.rb +3 -1
  66. data/lib/volt/page/targets/binding_document/component_node.rb +85 -82
  67. data/lib/volt/page/targets/binding_document/html_node.rb +11 -9
  68. data/lib/volt/page/targets/dom_section.rb +78 -77
  69. data/lib/volt/page/targets/dom_target.rb +8 -6
  70. data/lib/volt/page/targets/dom_template.rb +90 -88
  71. data/lib/volt/page/targets/helpers/comment_searchers.rb +51 -49
  72. data/lib/volt/page/tasks.rb +59 -57
  73. data/lib/volt/page/template_renderer.rb +17 -14
  74. data/lib/volt/page/url_tracker.rb +26 -24
  75. data/lib/volt/reactive/computation.rb +87 -88
  76. data/lib/volt/reactive/dependency.rb +30 -28
  77. data/lib/volt/reactive/eventable.rb +64 -62
  78. data/lib/volt/reactive/hash_dependency.rb +25 -23
  79. data/lib/volt/reactive/reactive_accessors.rb +34 -32
  80. data/lib/volt/reactive/reactive_array.rb +162 -162
  81. data/lib/volt/reactive/reactive_hash.rb +37 -35
  82. data/lib/volt/router/routes.rb +99 -101
  83. data/lib/volt/server/component_handler.rb +20 -21
  84. data/lib/volt/server/component_templates.rb +72 -70
  85. data/lib/volt/server/html_parser/attribute_scope.rb +109 -99
  86. data/lib/volt/server/html_parser/each_scope.rb +17 -16
  87. data/lib/volt/server/html_parser/if_view_scope.rb +51 -49
  88. data/lib/volt/server/html_parser/sandlebars_parser.rb +184 -177
  89. data/lib/volt/server/html_parser/textarea_scope.rb +24 -22
  90. data/lib/volt/server/html_parser/view_handler.rb +66 -65
  91. data/lib/volt/server/html_parser/view_parser.rb +23 -21
  92. data/lib/volt/server/html_parser/view_scope.rb +142 -141
  93. data/lib/volt/server/rack/asset_files.rb +81 -79
  94. data/lib/volt/server/rack/component_code.rb +17 -15
  95. data/lib/volt/server/rack/component_html_renderer.rb +14 -12
  96. data/lib/volt/server/rack/component_paths.rb +72 -71
  97. data/lib/volt/server/rack/index_files.rb +36 -39
  98. data/lib/volt/server/rack/opal_files.rb +43 -41
  99. data/lib/volt/server/rack/source_map_server.rb +23 -21
  100. data/lib/volt/server/socket_connection_handler.rb +46 -45
  101. data/lib/volt/server/socket_connection_handler_stub.rb +21 -19
  102. data/lib/volt/server.rb +60 -58
  103. data/lib/volt/spec/setup.rb +3 -3
  104. data/lib/volt/tasks/dispatcher.rb +24 -23
  105. data/lib/volt/tasks/task_handler.rb +35 -33
  106. data/lib/volt/utils/ejson.rb +8 -6
  107. data/lib/volt/utils/generic_counting_pool.rb +33 -31
  108. data/lib/volt/utils/generic_pool.rb +73 -70
  109. data/lib/volt/utils/local_storage.rb +42 -38
  110. data/lib/volt/volt/environment.rb +1 -1
  111. data/lib/volt.rb +44 -42
  112. data/spec/apps/kitchen_sink/app/main/assets/css/todos.css +28 -0
  113. data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
  114. data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +2 -2
  115. data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +17 -0
  116. data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -0
  117. data/spec/apps/kitchen_sink/app/main/views/todos/index.html +24 -0
  118. data/spec/apps/kitchen_sink/config.ru +1 -1
  119. data/spec/controllers/reactive_accessors_spec.rb +5 -5
  120. data/spec/extra_core/inflector_spec.rb +2 -2
  121. data/spec/integration/list_spec.rb +68 -0
  122. data/spec/models/model_spec.rb +57 -57
  123. data/spec/models/persistors/params_spec.rb +6 -6
  124. data/spec/models/persistors/store_spec.rb +7 -7
  125. data/spec/models/validations_spec.rb +3 -3
  126. data/spec/page/bindings/content_binding_spec.rb +7 -7
  127. data/spec/page/bindings/template_binding_spec.rb +4 -5
  128. data/spec/page/sub_context_spec.rb +2 -2
  129. data/spec/reactive/computation_spec.rb +10 -10
  130. data/spec/reactive/dependency_spec.rb +2 -2
  131. data/spec/reactive/eventable_spec.rb +4 -4
  132. data/spec/reactive/reactive_array_spec.rb +13 -13
  133. data/spec/router/routes_spec.rb +5 -5
  134. data/spec/server/html_parser/sandlebars_parser_spec.rb +9 -9
  135. data/spec/server/html_parser/view_parser_spec.rb +27 -27
  136. data/spec/server/rack/asset_files_spec.rb +5 -5
  137. data/spec/server/rack/component_paths_spec.rb +2 -2
  138. data/spec/tasks/live_query_spec.rb +2 -2
  139. data/spec/tasks/query_tasks.rb +1 -1
  140. data/spec/tasks/query_tracker_spec.rb +1 -1
  141. data/spec/templates/targets/binding_document/component_node_spec.rb +2 -2
  142. data/spec/utils/generic_counting_pool_spec.rb +2 -2
  143. data/spec/utils/generic_pool_spec.rb +2 -2
  144. data/templates/component/controllers/main_controller.rb +1 -1
  145. data/templates/model/model.rb.tt +2 -2
  146. data/templates/newgem/app/newgem/controllers/main_controller.rb.tt +2 -2
  147. data/templates/project/app/main/controllers/main_controller.rb +1 -1
  148. data/templates/project/config.ru +1 -1
  149. metadata +10 -3
  150. data/app/volt/assets/js/vertxbus.js +0 -216
@@ -1,6 +1,6 @@
1
1
  require 'volt/data_stores/mongo_driver'
2
2
 
3
- class Volt
3
+ module Volt
4
4
  class DataStore
5
5
  def self.fetch
6
6
  if Volt.config.db_driver == 'mongo'
@@ -10,4 +10,4 @@ class Volt
10
10
  end
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -1,6 +1,6 @@
1
1
  require 'mongo'
2
2
 
3
- class Volt
3
+ module Volt
4
4
  class DataStore
5
5
  class MongoDriver
6
6
  def self.fetch
@@ -11,4 +11,4 @@ class Volt
11
11
  end
12
12
  end
13
13
  end
14
- end
14
+ end
@@ -1,6 +1,6 @@
1
1
  require 'volt/extra_core/inflector/inflections'
2
2
 
3
- Inflector.inflections(:en) do |inflect|
3
+ Volt::Inflector.inflections(:en) do |inflect|
4
4
  inflect.plural(/$/, 's')
5
5
  inflect.plural(/s$/i, 's')
6
6
  inflect.plural(/^(ax|test)is$/i, '\1es')
@@ -60,4 +60,4 @@ Inflector.inflections(:en) do |inflect|
60
60
  inflect.irregular('zombie', 'zombies')
61
61
 
62
62
  inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
63
- end
63
+ end
@@ -1,203 +1,205 @@
1
- module Inflector
2
- # A singleton instance of this class is yielded by Inflector.inflections,
3
- # which can then be used to specify additional inflection rules. If passed
4
- # an optional locale, rules for other languages can be specified. The
5
- # default locale is <tt>:en</tt>. Only rules for English are provided.
6
- #
7
- # ActiveSupport::Inflector.inflections(:en) do |inflect|
8
- # inflect.plural /^(ox)$/i, '\1\2en'
9
- # inflect.singular /^(ox)en/i, '\1'
10
- #
11
- # inflect.irregular 'octopus', 'octopi'
12
- #
13
- # inflect.uncountable 'equipment'
14
- # end
15
- #
16
- # New rules are added at the top. So in the example above, the irregular
17
- # rule for octopus will now be the first of the pluralization and
18
- # singularization rules that is runs. This guarantees that your rules run
19
- # before any of the rules that may already have been loaded.
20
- class Inflections
21
- @__instance__ = {}
22
-
23
- def self.instance(locale = :en)
24
- @__instance__[locale] ||= new
25
- end
26
-
27
- attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
28
-
29
- def initialize
30
- @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
31
- end
32
-
33
- # Private, for the test suite.
34
- def initialize_dup(orig) # :nodoc:
35
- %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
36
- instance_variable_set("@#{scope}", orig.send(scope).dup)
37
- end
38
- end
39
-
40
- # Specifies a new acronym. An acronym must be specified as it will appear
41
- # in a camelized string. An underscore string that contains the acronym
42
- # will retain the acronym when passed to +camelize+, +humanize+, or
43
- # +titleize+. A camelized string that contains the acronym will maintain
44
- # the acronym when titleized or humanized, and will convert the acronym
45
- # into a non-delimited single lowercase word when passed to +underscore+.
46
- #
47
- # acronym 'HTML'
48
- # titleize 'html' #=> 'HTML'
49
- # camelize 'html' #=> 'HTML'
50
- # underscore 'MyHTML' #=> 'my_html'
51
- #
52
- # The acronym, however, must occur as a delimited unit and not be part of
53
- # another word for conversions to recognize it:
1
+ module Volt
2
+ module Inflector
3
+ # A singleton instance of this class is yielded by Inflector.inflections,
4
+ # which can then be used to specify additional inflection rules. If passed
5
+ # an optional locale, rules for other languages can be specified. The
6
+ # default locale is <tt>:en</tt>. Only rules for English are provided.
54
7
  #
55
- # acronym 'HTTP'
56
- # camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
57
- # camelize 'https' #=> 'Https', not 'HTTPs'
58
- # underscore 'HTTPS' #=> 'http_s', not 'https'
8
+ # ActiveSupport::Inflector.inflections(:en) do |inflect|
9
+ # inflect.plural /^(ox)$/i, '\1\2en'
10
+ # inflect.singular /^(ox)en/i, '\1'
59
11
  #
60
- # acronym 'HTTPS'
61
- # camelize 'https' #=> 'HTTPS'
62
- # underscore 'HTTPS' #=> 'https'
12
+ # inflect.irregular 'octopus', 'octopi'
63
13
  #
64
- # Note: Acronyms that are passed to +pluralize+ will no longer be
65
- # recognized, since the acronym will not occur as a delimited unit in the
66
- # pluralized result. To work around this, you must specify the pluralized
67
- # form as an acronym as well:
14
+ # inflect.uncountable 'equipment'
15
+ # end
68
16
  #
69
- # acronym 'API'
70
- # camelize(pluralize('api')) #=> 'Apis'
71
- #
72
- # acronym 'APIs'
73
- # camelize(pluralize('api')) #=> 'APIs'
74
- #
75
- # +acronym+ may be used to specify any word that contains an acronym or
76
- # otherwise needs to maintain a non-standard capitalization. The only
77
- # restriction is that the word must begin with a capital letter.
78
- #
79
- # acronym 'RESTful'
80
- # underscore 'RESTful' #=> 'restful'
81
- # underscore 'RESTfulController' #=> 'restful_controller'
82
- # titleize 'RESTfulController' #=> 'RESTful Controller'
83
- # camelize 'restful' #=> 'RESTful'
84
- # camelize 'restful_controller' #=> 'RESTfulController'
85
- #
86
- # acronym 'McDonald'
87
- # underscore 'McDonald' #=> 'mcdonald'
88
- # camelize 'mcdonald' #=> 'McDonald'
89
- def acronym(word)
90
- @acronyms[word.downcase] = word
91
- @acronym_regex = /#{@acronyms.values.join("|")}/
92
- end
17
+ # New rules are added at the top. So in the example above, the irregular
18
+ # rule for octopus will now be the first of the pluralization and
19
+ # singularization rules that is runs. This guarantees that your rules run
20
+ # before any of the rules that may already have been loaded.
21
+ class Inflections
22
+ @__instance__ = {}
23
+
24
+ def self.instance(locale = :en)
25
+ @__instance__[locale] ||= new
26
+ end
93
27
 
94
- # Specifies a new pluralization rule and its replacement. The rule can
95
- # either be a string or a regular expression. The replacement should
96
- # always be a string that may include references to the matched data from
97
- # the rule.
98
- def plural(rule, replacement)
99
- @uncountables.delete(rule) if rule.is_a?(String)
100
- @uncountables.delete(replacement)
101
- @plurals.insert(0, [rule, replacement])
102
- end
28
+ attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
103
29
 
104
- # Specifies a new singularization rule and its replacement. The rule can
105
- # either be a string or a regular expression. The replacement should
106
- # always be a string that may include references to the matched data from
107
- # the rule.
108
- def singular(rule, replacement)
109
- @uncountables.delete(rule) if rule.is_a?(String)
110
- @uncountables.delete(replacement)
111
- @singulars.insert(0, [rule, replacement])
112
- end
30
+ def initialize
31
+ @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
32
+ end
113
33
 
114
- # Specifies a new irregular that applies to both pluralization and
115
- # singularization at the same time. This can only be used for strings, not
116
- # regular expressions. You simply pass the irregular in singular and
117
- # plural form.
118
- #
119
- # irregular 'octopus', 'octopi'
120
- # irregular 'person', 'people'
121
- def irregular(singular, plural)
122
- @uncountables.delete(singular)
123
- @uncountables.delete(plural)
34
+ # Private, for the test suite.
35
+ def initialize_dup(orig) # :nodoc:
36
+ %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
37
+ instance_variable_set("@#{scope}", orig.send(scope).dup)
38
+ end
39
+ end
124
40
 
125
- s0 = singular[0]
126
- srest = singular[1..-1]
41
+ # Specifies a new acronym. An acronym must be specified as it will appear
42
+ # in a camelized string. An underscore string that contains the acronym
43
+ # will retain the acronym when passed to +camelize+, +humanize+, or
44
+ # +titleize+. A camelized string that contains the acronym will maintain
45
+ # the acronym when titleized or humanized, and will convert the acronym
46
+ # into a non-delimited single lowercase word when passed to +underscore+.
47
+ #
48
+ # acronym 'HTML'
49
+ # titleize 'html' #=> 'HTML'
50
+ # camelize 'html' #=> 'HTML'
51
+ # underscore 'MyHTML' #=> 'my_html'
52
+ #
53
+ # The acronym, however, must occur as a delimited unit and not be part of
54
+ # another word for conversions to recognize it:
55
+ #
56
+ # acronym 'HTTP'
57
+ # camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
58
+ # camelize 'https' #=> 'Https', not 'HTTPs'
59
+ # underscore 'HTTPS' #=> 'http_s', not 'https'
60
+ #
61
+ # acronym 'HTTPS'
62
+ # camelize 'https' #=> 'HTTPS'
63
+ # underscore 'HTTPS' #=> 'https'
64
+ #
65
+ # Note: Acronyms that are passed to +pluralize+ will no longer be
66
+ # recognized, since the acronym will not occur as a delimited unit in the
67
+ # pluralized result. To work around this, you must specify the pluralized
68
+ # form as an acronym as well:
69
+ #
70
+ # acronym 'API'
71
+ # camelize(pluralize('api')) #=> 'Apis'
72
+ #
73
+ # acronym 'APIs'
74
+ # camelize(pluralize('api')) #=> 'APIs'
75
+ #
76
+ # +acronym+ may be used to specify any word that contains an acronym or
77
+ # otherwise needs to maintain a non-standard capitalization. The only
78
+ # restriction is that the word must begin with a capital letter.
79
+ #
80
+ # acronym 'RESTful'
81
+ # underscore 'RESTful' #=> 'restful'
82
+ # underscore 'RESTfulController' #=> 'restful_controller'
83
+ # titleize 'RESTfulController' #=> 'RESTful Controller'
84
+ # camelize 'restful' #=> 'RESTful'
85
+ # camelize 'restful_controller' #=> 'RESTfulController'
86
+ #
87
+ # acronym 'McDonald'
88
+ # underscore 'McDonald' #=> 'mcdonald'
89
+ # camelize 'mcdonald' #=> 'McDonald'
90
+ def acronym(word)
91
+ @acronyms[word.downcase] = word
92
+ @acronym_regex = /#{@acronyms.values.join("|")}/
93
+ end
127
94
 
128
- p0 = plural[0]
129
- prest = plural[1..-1]
95
+ # Specifies a new pluralization rule and its replacement. The rule can
96
+ # either be a string or a regular expression. The replacement should
97
+ # always be a string that may include references to the matched data from
98
+ # the rule.
99
+ def plural(rule, replacement)
100
+ @uncountables.delete(rule) if rule.is_a?(String)
101
+ @uncountables.delete(replacement)
102
+ @plurals.insert(0, [rule, replacement])
103
+ end
130
104
 
131
- if s0.upcase == p0.upcase
132
- plural(/(#{s0})#{srest}$/i, '\1' + prest)
133
- plural(/(#{p0})#{prest}$/i, '\1' + prest)
105
+ # Specifies a new singularization rule and its replacement. The rule can
106
+ # either be a string or a regular expression. The replacement should
107
+ # always be a string that may include references to the matched data from
108
+ # the rule.
109
+ def singular(rule, replacement)
110
+ @uncountables.delete(rule) if rule.is_a?(String)
111
+ @uncountables.delete(replacement)
112
+ @singulars.insert(0, [rule, replacement])
113
+ end
134
114
 
135
- singular(/(#{s0})#{srest}$/i, '\1' + srest)
136
- singular(/(#{p0})#{prest}$/i, '\1' + srest)
137
- else
138
- plural(/#{s0.upcase}(?i)#{srest}$/, p0.upcase + prest)
139
- plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest)
140
- plural(/#{p0.upcase}(?i)#{prest}$/, p0.upcase + prest)
141
- plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest)
142
-
143
- singular(/#{s0.upcase}(?i)#{srest}$/, s0.upcase + srest)
144
- singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest)
145
- singular(/#{p0.upcase}(?i)#{prest}$/, s0.upcase + srest)
146
- singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest)
115
+ # Specifies a new irregular that applies to both pluralization and
116
+ # singularization at the same time. This can only be used for strings, not
117
+ # regular expressions. You simply pass the irregular in singular and
118
+ # plural form.
119
+ #
120
+ # irregular 'octopus', 'octopi'
121
+ # irregular 'person', 'people'
122
+ def irregular(singular, plural)
123
+ @uncountables.delete(singular)
124
+ @uncountables.delete(plural)
125
+
126
+ s0 = singular[0]
127
+ srest = singular[1..-1]
128
+
129
+ p0 = plural[0]
130
+ prest = plural[1..-1]
131
+
132
+ if s0.upcase == p0.upcase
133
+ plural(/(#{s0})#{srest}$/i, '\1' + prest)
134
+ plural(/(#{p0})#{prest}$/i, '\1' + prest)
135
+
136
+ singular(/(#{s0})#{srest}$/i, '\1' + srest)
137
+ singular(/(#{p0})#{prest}$/i, '\1' + srest)
138
+ else
139
+ plural(/#{s0.upcase}(?i)#{srest}$/, p0.upcase + prest)
140
+ plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest)
141
+ plural(/#{p0.upcase}(?i)#{prest}$/, p0.upcase + prest)
142
+ plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest)
143
+
144
+ singular(/#{s0.upcase}(?i)#{srest}$/, s0.upcase + srest)
145
+ singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest)
146
+ singular(/#{p0.upcase}(?i)#{prest}$/, s0.upcase + srest)
147
+ singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest)
148
+ end
147
149
  end
148
- end
149
150
 
150
- # Add uncountable words that shouldn't be attempted inflected.
151
- #
152
- # uncountable 'money'
153
- # uncountable 'money', 'information'
154
- # uncountable %w( money information rice )
155
- def uncountable(*words)
156
- (@uncountables << words).flatten!
157
- end
151
+ # Add uncountable words that shouldn't be attempted inflected.
152
+ #
153
+ # uncountable 'money'
154
+ # uncountable 'money', 'information'
155
+ # uncountable %w( money information rice )
156
+ def uncountable(*words)
157
+ (@uncountables << words).flatten!
158
+ end
158
159
 
159
- # Specifies a humanized form of a string by a regular expression rule or
160
- # by a string mapping. When using a regular expression based replacement,
161
- # the normal humanize formatting is called after the replacement. When a
162
- # string is used, the human form should be specified as desired (example:
163
- # 'The name', not 'the_name').
164
- #
165
- # human /_cnt$/i, '\1_count'
166
- # human 'legacy_col_person_name', 'Name'
167
- def human(rule, replacement)
168
- @humans.insert(0, [rule, replacement])
169
- end
160
+ # Specifies a humanized form of a string by a regular expression rule or
161
+ # by a string mapping. When using a regular expression based replacement,
162
+ # the normal humanize formatting is called after the replacement. When a
163
+ # string is used, the human form should be specified as desired (example:
164
+ # 'The name', not 'the_name').
165
+ #
166
+ # human /_cnt$/i, '\1_count'
167
+ # human 'legacy_col_person_name', 'Name'
168
+ def human(rule, replacement)
169
+ @humans.insert(0, [rule, replacement])
170
+ end
170
171
 
171
- # Clears the loaded inflections within a given scope (default is
172
- # <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
173
- # options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
174
- # <tt>:humans</tt>.
175
- #
176
- # clear :all
177
- # clear :plurals
178
- def clear(scope = :all)
179
- case scope
180
- when :all
181
- @plurals, @singulars, @uncountables, @humans = [], [], [], []
182
- else
183
- instance_variable_set "@#{scope}", []
172
+ # Clears the loaded inflections within a given scope (default is
173
+ # <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
174
+ # options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
175
+ # <tt>:humans</tt>.
176
+ #
177
+ # clear :all
178
+ # clear :plurals
179
+ def clear(scope = :all)
180
+ case scope
181
+ when :all
182
+ @plurals, @singulars, @uncountables, @humans = [], [], [], []
183
+ else
184
+ instance_variable_set "@#{scope}", []
185
+ end
184
186
  end
185
187
  end
186
- end
187
188
 
188
- # Yields a singleton instance of Inflector::Inflections so you can specify
189
- # additional inflector rules. If passed an optional locale, rules for other
190
- # languages can be specified. If not specified, defaults to <tt>:en</tt>.
191
- # Only rules for English are provided.
192
- #
193
- # ActiveSupport::Inflector.inflections(:en) do |inflect|
194
- # inflect.uncountable 'rails'
195
- # end
196
- def self.inflections(locale = :en)
197
- if block_given?
198
- yield Inflections.instance(locale)
199
- else
200
- Inflections.instance(locale)
189
+ # Yields a singleton instance of Inflector::Inflections so you can specify
190
+ # additional inflector rules. If passed an optional locale, rules for other
191
+ # languages can be specified. If not specified, defaults to <tt>:en</tt>.
192
+ # Only rules for English are provided.
193
+ #
194
+ # ActiveSupport::Inflector.inflections(:en) do |inflect|
195
+ # inflect.uncountable 'rails'
196
+ # end
197
+ def self.inflections(locale = :en)
198
+ if block_given?
199
+ yield Inflections.instance(locale)
200
+ else
201
+ Inflections.instance(locale)
202
+ end
201
203
  end
202
204
  end
203
- end
205
+ end
@@ -4,60 +4,62 @@
4
4
  # names, modularized class names to ones without, and class names to foreign
5
5
  # keys. The default inflections for pluralization, singularization, and
6
6
  # uncountable words are kept in inflections.rb.
7
- module Inflector
8
- # Returns the plural form of the word in the string.
9
- #
10
- # If passed an optional +locale+ parameter, the word will be
11
- # pluralized using rules defined for that language. By default,
12
- # this parameter is set to <tt>:en</tt>.
13
- #
14
- # 'post'.pluralize # => "posts"
15
- # 'octopus'.pluralize # => "octopi"
16
- # 'sheep'.pluralize # => "sheep"
17
- # 'words'.pluralize # => "words"
18
- # 'CamelOctopus'.pluralize # => "CamelOctopi"
19
- # 'ley'.pluralize(:es) # => "leyes"
20
- def self.pluralize(word, locale = :en)
21
- apply_inflections(word, inflections(locale).plurals)
22
- end
7
+ module Volt
8
+ module Inflector
9
+ # Returns the plural form of the word in the string.
10
+ #
11
+ # If passed an optional +locale+ parameter, the word will be
12
+ # pluralized using rules defined for that language. By default,
13
+ # this parameter is set to <tt>:en</tt>.
14
+ #
15
+ # 'post'.pluralize # => "posts"
16
+ # 'octopus'.pluralize # => "octopi"
17
+ # 'sheep'.pluralize # => "sheep"
18
+ # 'words'.pluralize # => "words"
19
+ # 'CamelOctopus'.pluralize # => "CamelOctopi"
20
+ # 'ley'.pluralize(:es) # => "leyes"
21
+ def self.pluralize(word, locale = :en)
22
+ apply_inflections(word, inflections(locale).plurals)
23
+ end
23
24
 
24
- # The reverse of +pluralize+, returns the singular form of a word in a
25
- # string.
26
- #
27
- # If passed an optional +locale+ parameter, the word will be
28
- # pluralized using rules defined for that language. By default,
29
- # this parameter is set to <tt>:en</tt>.
30
- #
31
- # 'posts'.singularize # => "post"
32
- # 'octopi'.singularize # => "octopus"
33
- # 'sheep'.singularize # => "sheep"
34
- # 'word'.singularize # => "word"
35
- # 'CamelOctopi'.singularize # => "CamelOctopus"
36
- # 'leyes'.singularize(:es) # => "ley"
37
- def self.singularize(word, locale = :en)
38
- apply_inflections(word, inflections(locale).singulars)
39
- end
25
+ # The reverse of +pluralize+, returns the singular form of a word in a
26
+ # string.
27
+ #
28
+ # If passed an optional +locale+ parameter, the word will be
29
+ # pluralized using rules defined for that language. By default,
30
+ # this parameter is set to <tt>:en</tt>.
31
+ #
32
+ # 'posts'.singularize # => "post"
33
+ # 'octopi'.singularize # => "octopus"
34
+ # 'sheep'.singularize # => "sheep"
35
+ # 'word'.singularize # => "word"
36
+ # 'CamelOctopi'.singularize # => "CamelOctopus"
37
+ # 'leyes'.singularize(:es) # => "ley"
38
+ def self.singularize(word, locale = :en)
39
+ apply_inflections(word, inflections(locale).singulars)
40
+ end
40
41
 
41
42
 
42
- private
43
+ private
43
44
 
44
- # Applies inflection rules for +singularize+ and +pluralize+.
45
- #
46
- # apply_inflections('post', inflections.plurals) # => "posts"
47
- # apply_inflections('posts', inflections.singulars) # => "post"
48
- def self.apply_inflections(word, rules)
49
- result = word.to_s.dup
45
+ # Applies inflection rules for +singularize+ and +pluralize+.
46
+ #
47
+ # apply_inflections('post', inflections.plurals) # => "posts"
48
+ # apply_inflections('posts', inflections.singulars) # => "post"
49
+ def self.apply_inflections(word, rules)
50
+ result = word.to_s.dup
50
51
 
51
- if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
52
- result
53
- else
54
- rules.each do |(rule, replacement)|
55
- if result.match(rule)
56
- result = result.sub(rule, replacement)
57
- break
52
+ if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
53
+ result
54
+ else
55
+ rules.each do |(rule, replacement)|
56
+ if result.match(rule)
57
+ result = result.sub(rule, replacement)
58
+ break
59
+ end
58
60
  end
61
+ result
59
62
  end
60
- result
61
63
  end
62
64
  end
63
- end
65
+ end
@@ -24,11 +24,11 @@ class String
24
24
  end
25
25
 
26
26
  def pluralize
27
- Inflector.pluralize(self)
27
+ Volt::Inflector.pluralize(self)
28
28
  end
29
29
 
30
30
  def singularize
31
- Inflector.singularize(self)
31
+ Volt::Inflector.singularize(self)
32
32
  end
33
33
 
34
34
  def titleize