volt 0.8.14 → 0.8.15

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