code-box 0.5.0 → 0.5.1

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/Gemfile.lock CHANGED
@@ -1,21 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code-box (0.5.0)
4
+ code-box (0.5.1)
5
5
  activerecord (~> 3.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activemodel (3.2.6)
11
- activesupport (= 3.2.6)
10
+ activemodel (3.2.7)
11
+ activesupport (= 3.2.7)
12
12
  builder (~> 3.0.0)
13
- activerecord (3.2.6)
14
- activemodel (= 3.2.6)
15
- activesupport (= 3.2.6)
13
+ activerecord (3.2.7)
14
+ activemodel (= 3.2.7)
15
+ activesupport (= 3.2.7)
16
16
  arel (~> 3.0.2)
17
17
  tzinfo (~> 0.3.29)
18
- activesupport (3.2.6)
18
+ activesupport (3.2.7)
19
19
  i18n (~> 0.6)
20
20
  multi_json (~> 1.0)
21
21
  arel (3.0.2)
data/README.md CHANGED
@@ -1,3 +1,8 @@
1
+ # Notes
2
+
3
+ If you re using ActiveRecord ~> 4.0.0 use the version ~> 0.6
4
+ If you re using ActiveRecord ~> 3.0 use the version ~> 0.5.0
5
+
1
6
  # CodeBox::CodeAttribute
2
7
 
3
8
  Lets you define attributes as codes, instead keys (ids). For simple option storage saving a string code is often more simple an conveniant the storing an artificial id-key referencing a special code object.
@@ -134,12 +139,12 @@ Options are:
134
139
  If `true` the uniqueness validation is scoped by the attribute `type` (default false).
135
140
  * `:uniqueness_case_sensitive => true`
136
141
  If `true` the the uniqueness validation is case sensitive (default true).
137
- * `:position_attr => :position
142
+ * `:position_attr => :position`
138
143
  If present, the order when fetching the codes is done with this expression (default scope - means - if you want to omit the order used `unscoped` on any AR operation).
139
144
 
140
- All options except `:code_attribute` are used only for ActiveRecord models.
145
+ All options except `:code_attribute` are used __only__ for ActiveRecord models.
141
146
 
142
- If `*codes` are provided the following code constants will be defined when calling `acts_as_code('male', 'female', code_attribute: 'code')`
147
+ If `*codes` are provided the following code constants will be defined as shown in the example below.
143
148
 
144
149
  __IMPORTANT__ Code object constants will only be created when the code object is not an ActiveRecord model!
145
150
 
@@ -150,7 +155,7 @@ __IMPORTANT__ Code object constants will only be created when the code object is
150
155
  # acts_as_code('male', 'female') # Code attribute name will be 'code'
151
156
 
152
157
 
153
- # Given codes 'male' an 'female' the following constants will be defined:
158
+ # Given codes 'male' and 'female' the following constants will be defined:
154
159
  #
155
160
  # module Codes
156
161
  # Male = 'male'
@@ -158,7 +163,7 @@ __IMPORTANT__ Code object constants will only be created when the code object is
158
163
  # All = [Male, Female]
159
164
  # end
160
165
  #
161
- # Below constants pnly is is not ActiveRecod model!
166
+ # Below constants are only currently only defined if the hosting class not an ActiveRecod model (as in this sample).
162
167
  # Male = Gender.new('male')
163
168
  # Female = Gender.new('female')
164
169
  # All = [Male, Female]
@@ -166,7 +171,35 @@ __IMPORTANT__ Code object constants will only be created when the code object is
166
171
  end
167
172
 
168
173
 
169
- Furthermote àcts_as_code` defines the following methods:
174
+ If `*codes` are provided - in addition the following test_methods are defined:
175
+
176
+ class Gender
177
+ include CodeBox::ActsAsCode['male', 'female'] # Code attribute name will be 'code'
178
+ # Above is a shortcut for...
179
+ # include CodeBox::ActsAsCode
180
+ # acts_as_code('male', 'female') # Code attribute name will be 'code'
181
+
182
+
183
+ # Given codes 'male' and 'female' the following constants will be defined:
184
+ # ... al the stuff above
185
+ #
186
+ # def male?
187
+ # code == Codes::Male
188
+ # end
189
+ #
190
+ # def female?
191
+ # code == Codes::Female
192
+ # end
193
+ #
194
+ end
195
+
196
+ Pass the option `define_test_methods: false` if you don't want to have test-methods generated.
197
+ If you prefer the all test-methods prefixed with e.g. `is_` so the methods above look like `is_male?` then you can configure this
198
+ globaly by defining `CodeBox.test_method_prefix='is_'`.
199
+
200
+
201
+
202
+ In addition `acts_as_code` defines the following methods:
170
203
 
171
204
  * `.for_code(code)`
172
205
  Answers the code object for the given code (fetched from cache)
@@ -174,18 +207,37 @@ Furthermote àcts_as_code` defines the following methods:
174
207
  * `#translated_code(locale=I18n.locale, *other_locale_options)`
175
208
  Translates the code stored in `code`
176
209
 
177
- * `#translated_code(locale=I18n.locale, *other_locale_options)`
178
- Translates the code stored in `code`
179
-
180
- * `.translate_code(codes_and_options)`
181
- <br/>Translates a single code if `code` is a code, an array of codes of `code` is an array.
210
+ * `.translate_code(codes_and_options)`
211
+ Translates a single code if `code` is a code, an array of codes of `code` is an array.
182
212
  If code is an array the option :build => :zip can be used to build a select option capable array (e.g `[['Switzerland', 'SUI'],['Germany', 'GER'],['Denmark', 'DEN']]`)
183
213
 
184
214
  * `.build_select_options(codes_and_options)`
185
- Build an options array from the passed codes (all codes if no codes are passed). Add an empty option at the beginning if the option `:include_nil` is passed. The localization key is defined in CodeBox (CodeBox.i18n_empty_options_key). If you want the change the default key `shared.options.pls_select` you can do so in an initializer by calling `CodeBox.i18n_empty_options_key='your.key'`.
215
+ Build an options array from the passed codes (all codes if no codes are passed). Add an empty option at the beginning if the option `:include_empty` is passed. If `:include_empty` is…
216
+
217
+ * `true`, then options label is derived from the I18n tranlsation of the key defined in CodeBox.i18n_empty_options_key (default is `shared.options.pls_select` - you can change this default). The value of the option is `nil` by default.
218
+ * `false` then no empty option is defined (default)
219
+ * a String then the string is used as label. The value of the option is `nil` by default.
220
+ * a String starting with `i18n.` the the string is considered as a tranlation key (without the `i18n.` part). Value is nil by default.
221
+ * is a Hash then the value is take from the Hashs value for key `:value` (nil if not present), and the label is taken from the value of key `:label` (default CodeBox.i18n_empty_option_key). If a String is present it is interpreted as a plain label or I18n key as described above.
186
222
 
187
- * `.clear_code_cache`
188
- <br/>Clears the cache so its build up on need from all codes from scratch
223
+ ``Examples
224
+
225
+ .build_select_options(include_empty: true)
226
+
227
+ is same as …
228
+
229
+ .build_select_options(include_empty: {})
230
+
231
+ is same as …
232
+
233
+ .build_select_options(include_empty: {label: nil, value: nil})
234
+
235
+ is same as …
236
+
237
+ .build_select_options(include_empty: {label: '<your default key in CodeBox.i18n_empty_options_key>', value: nil})
238
+
239
+ * `.clear_code_cache`
240
+ Clears the cache so its build up again lazy when needed form all codes.
189
241
 
190
242
  * Passing
191
243
 
@@ -216,29 +268,23 @@ Assuming we have a simple ruby class with default code attribute 'code' we can d
216
268
  # raise "Sublass responsibility. You should implement '.all' returning all codes"
217
269
  # end
218
270
 
219
- # @return [Array] List if all code objects (instances of this)
271
+ # @return [Array] List if all code objects (instances of this) - is implemented when codes are defined.
220
272
  def self.all
221
- # you need to implement this
273
+ raise 'Class responsibility - implement method .all returning all code models.'
222
274
  end
223
275
 
224
276
  end
225
277
 
226
- Configuration options are:
227
-
228
- :type => :poro #(default, other :active_record)
229
- :code_attribute => :code #(default) or any other name as symbol
230
-
231
-
232
278
 
233
279
  #### ActiveRecod code objects (:active_record)
234
280
 
235
281
  Assuming we have an ActiveRecod code class with `code_attribute :code` we can defined such a class like
236
282
 
237
283
  class Codes::MySpecificCode < ActiveRecord::Base
238
- include CodeBox::ActsAsCode[:type => :active_record]
284
+ include CodeBox::ActsAsCode[]
239
285
  # Above is actually a shortcut for:
240
286
  # include CodeBox::ActsAsCode
241
- # acts_as_code(:type => :active_record)
287
+ # acts_as_code
242
288
 
243
289
  # Above include creates the following:
244
290
  #
@@ -249,19 +295,31 @@ Assuming we have an ActiveRecod code class with `code_attribute :code` we can de
249
295
 
250
296
  end
251
297
 
252
- Configuration options are:
253
-
254
- :type => :active_record # other :poro(default)
255
- :code_attribute => :code # (default) or any other name as symbol
256
- :polymorphic => false # (default). If `true` the uniqueness validation is scope by the attribute `type`
257
- :uniqueness_case_sensitive => true # (default). If `false` the the uniqueness validation is case insensitive
258
- :position_attr => :position # If present, the order when fetching the codes is done with this expression (default scope - means - if you want to omit the order used `unscoped` on any AR operation).
259
-
260
298
 
261
299
 
262
300
  ### Examples
263
301
  TO BE DONE…
264
302
 
303
+ ## Changelog
304
+
305
+ ### Version 0.5.1
306
+ * Adding testing methods for codes objects. E.g. Code-Object with code 'my_code' get method `#codeObjectInstance.my_code?` defined.
307
+ * Method `.build_select_options` has been changed so you can pass in more flexible empty option configuration (see Readme).
308
+ * Ugrade of Rails 4 Version pending…
309
+
310
+ ### Version 0.6.0
311
+ * Moving to activerecord 4.0.
312
+
313
+ ### Version 0.5.0
314
+ * Change constant definition. Create code constants in a Codes module so the can be included in other places - an document it.
315
+ * Remove option `:model_type. The option is obsolte and can be derived from the including module.
316
+
317
+ ### Version 0.4.*
318
+ * Define constant whens defining codes.
319
+
320
+ ### Version 0.3.*
321
+ * Need to scan the logs…
322
+
265
323
  ## Contributing
266
324
 
267
325
  1. Fork it!
data/code-box.gemspec CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
  require File.expand_path('../lib/code-box/version', __FILE__)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
- gem.name = "code-box"
6
+ gem.name = 'code-box'
7
7
  gem.version = CodeBox::VERSION
8
8
 
9
9
  gem.authors = ["Martin Schweizer"]
@@ -47,21 +47,23 @@ module CodeBox
47
47
 
48
48
  module ClassMethods
49
49
  DefaultOptions = {
50
- :code_attribute => 'code',
51
- :sti => false,
52
- :uniqueness_case_sensitive => true,
53
- :position_attr => :position,
50
+ code_attribute: 'code',
51
+ sti: false,
52
+ uniqueness_case_sensitive: true,
53
+ position_attr: :position,
54
+ define_test_methods: true,
54
55
  }
55
56
 
56
57
  def acts_as_code(*codes_and_or_options)
57
- options = codes_and_or_options.extract_options!
58
- codes = codes_and_or_options
59
- opts = DefaultOptions.merge(options)
60
- code_attr = opts[:code_attribute].to_s
61
- position_attr = opts[:position_attribute]
62
- case_sensitive = opts[:uniqueness_case_sensitive]
58
+ options = codes_and_or_options.extract_options!
59
+ codes = codes_and_or_options
60
+ opts = DefaultOptions.merge(options)
61
+ code_attr = opts[:code_attribute].to_s
62
+ position_attr = opts[:position_attribute]
63
+ case_sensitive = opts[:uniqueness_case_sensitive]
64
+ define_test_methods = opts[:define_test_methods]
63
65
 
64
- model_type = self.ancestors.include?('ActiveRecord::Base'.constantize) ? :active_record : :poro
66
+ model_type = self.ancestors.include?('ActiveRecord::Base'.constantize) ? :active_record : :poro
65
67
 
66
68
  class_eval <<-RUBY_
67
69
  def translated_#{code_attr}(locale = I18n.locale, *options)
@@ -98,12 +100,32 @@ module CodeBox
98
100
  end
99
101
 
100
102
  def self.build_select_options(*args)
101
- options = args.extract_options!
102
- codes = args.empty? ? #{code_attr.pluralize.camelize}::All : args
103
- include_nil = !!options[:include_nil]
103
+ options = args.extract_options!
104
+ codes = args.empty? ? #{code_attr.pluralize.camelize}::All : args
105
+ include_empty = options[:include_empty] || false
106
+ locale = options.fetch(:locale, I18n.locale)
107
+
108
+ label, value = case include_empty
109
+ when Hash
110
+ [
111
+ include_empty.fetch(:label, "i18n.#{CodeBox.i18n_empty_options_key}"),
112
+ include_empty.fetch(:value, nil)
113
+ ]
114
+ when TrueClass
115
+ [ "i18n.#{CodeBox.i18n_empty_options_key}", nil ]
116
+ when String
117
+ [ include_empty, nil ]
118
+ else # is something falsish
119
+ []
120
+ end
121
+
104
122
 
123
+ # If starts with 'i18n.' it is considered an I18n key, else the label itself
105
124
  options = translate_#{code_attr}(codes, build: :zip)
106
- options.unshift [I18n.t(CodeBox.i18n_empty_options_key), nil] if include_nil
125
+ if include_empty
126
+ label = I18n.t(label[5..-1], locale: locale) if label.starts_with?('i18n.')
127
+ options.unshift [label, value]
128
+ end
107
129
 
108
130
  options
109
131
  end
@@ -142,7 +164,7 @@ module CodeBox
142
164
  validates_presence_of :#{code_attr}
143
165
  validates_uniqueness_of :#{code_attr}#{opts[:sti] ? ', :scope => :type' : ' '}, :case_sensitive => #{case_sensitive}
144
166
 
145
- default_scope order('#{order_expression}')
167
+ default_scope -> { order('#{order_expression}') }
146
168
  CODE
147
169
 
148
170
  when :poro
@@ -156,7 +178,7 @@ module CodeBox
156
178
  end
157
179
 
158
180
  def self.all
159
- raise 'Class responsibility'
181
+ raise 'Class responsibility - implement method .all returning all code models.'
160
182
  end
161
183
 
162
184
  def hash
@@ -175,14 +197,11 @@ module CodeBox
175
197
  raise ArgumentError, "'#{model_type}' is not a valid type. Use :active_record or :poro(default) instead"
176
198
  end
177
199
 
178
- define_codes(*codes)
200
+ define_codes(*codes, define_test_methods) unless codes.empty?
179
201
  end
180
202
 
181
- def define_codes(*codes)
182
- return if codes.empty?
183
-
203
+ def define_codes(*codes, define_test_methods)
184
204
  # --- Define the code constants...
185
-
186
205
  code_attr = self._code_box_code_attr_name
187
206
  model_type = self.ancestors.include?('ActiveRecord::Base'.constantize) ? :active_record : :poro
188
207
 
@@ -204,8 +223,27 @@ module CodeBox
204
223
  codes_module.const_set('All', constants.values.compact)
205
224
  end
206
225
 
226
+
227
+ # Define test methods for each code like e.g.
228
+ # def married?
229
+ # code == Codes::Married
230
+ # end
231
+ if define_test_methods
232
+ method_prefix = CodeBox.test_method_prefix
233
+
234
+ codes.each do |code|
235
+ method_name = "#{method_prefix}#{code.to_s}"
236
+ class_eval <<-CODE
237
+ def #{method_name}?
238
+ #{code_attr} == #{module_name}::#{code.to_s.camelize}
239
+ end
240
+ CODE
241
+ end
242
+ end
243
+
207
244
  return if model_type == :active_record
208
245
 
246
+
209
247
  # --- Define the code instance constants...
210
248
 
211
249
  constants = {}
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module CodeBox
4
- VERSION = "0.5.0"
4
+ VERSION = "0.5.1"
5
5
  end
data/lib/code-box.rb CHANGED
@@ -5,8 +5,9 @@ require 'code-box/acts_as_code'
5
5
 
6
6
  module CodeBox
7
7
  Config = {
8
- :i18n_model_segment => :activerecord,
9
- :i18n_empty_options_key => 'shared.options.pls_select',
8
+ i18n_model_segment: :activerecord,
9
+ i18n_empty_options_key: 'shared.options.pls_select',
10
+ test_method_prefix: '',
10
11
  }
11
12
 
12
13
  def i18n_model_segment=(segment)
@@ -25,5 +26,15 @@ module CodeBox
25
26
  Config[:i18n_empty_options_key]
26
27
  end
27
28
 
28
- module_function :i18n_model_segment, :i18n_model_segment=, :i18n_empty_options_key, :i18n_empty_options_key=
29
+ def test_method_prefix=(prefix)
30
+ Config[:test_method_prefix] = (prefix.nil? ? '' : prefix.strip)
31
+ end
32
+
33
+ def test_method_prefix
34
+ Config[:test_method_prefix]
35
+ end
36
+
37
+ module_function :i18n_model_segment, :i18n_model_segment=,
38
+ :i18n_empty_options_key, :i18n_empty_options_key=,
39
+ :test_method_prefix, :test_method_prefix=
29
40
  end
@@ -57,15 +57,15 @@ class TestActsAsCode < Test::Unit::TestCase
57
57
 
58
58
  def test_code_instance_constant_definitions_w_define_code
59
59
  # Constants
60
- assert Codes::CivilStatusUseDefine.const_defined?('Single')
61
- assert Codes::CivilStatusUseDefine.const_defined?('Married')
62
- assert Codes::CivilStatusUseDefine.const_defined?('All')
60
+ assert Codes::CivilStatus.const_defined?('Single')
61
+ assert Codes::CivilStatus.const_defined?('Married')
62
+ assert Codes::CivilStatus.const_defined?('All')
63
63
 
64
64
  # Constants-Values
65
- assert_equal [Codes::CivilStatusUseDefine::Single, Codes::CivilStatusUseDefine::Married], Codes::CivilStatusUseDefine::All
66
- assert_equal [Codes::CivilStatusUseDefine::Single, Codes::CivilStatusUseDefine::Married], Codes::CivilStatusUseDefine.all
67
- assert_equal Codes::CivilStatusUseDefine::Single.code, 'single'
68
- assert_equal Codes::CivilStatusUseDefine::Married.code, 'married'
65
+ assert_equal [Codes::CivilStatus::Single, Codes::CivilStatus::Married], Codes::CivilStatus::All
66
+ assert_equal [Codes::CivilStatus::Single, Codes::CivilStatus::Married], Codes::CivilStatus.all
67
+ assert_equal Codes::CivilStatus::Single.code, 'single'
68
+ assert_equal Codes::CivilStatus::Married.code, 'married'
69
69
  end
70
70
 
71
71
  def test_code_translation
@@ -79,9 +79,29 @@ class TestActsAsCode < Test::Unit::TestCase
79
79
  options_array = Codes::CivilStatus.build_select_options
80
80
  assert_equal options_array.size, 2
81
81
 
82
- options_array = Codes::CivilStatus.build_select_options(include_nil: true)
82
+ options_array = Codes::CivilStatus.build_select_options(include_empty: true)
83
+ assert_equal options_array.size, 3
84
+ assert_equal options_array.first[1], nil
85
+ end
86
+
87
+ def test_options_building_with_text_label
88
+ options_array = Codes::CivilStatus.build_select_options(include_empty: { label: 'MyLabel' })
89
+ assert_equal options_array.size, 3
90
+ assert_equal options_array.first[0], 'MyLabel'
91
+ assert_equal options_array.first[1], nil
92
+ end
93
+
94
+ def test_options_building_with_custom_value
95
+ options_array = Codes::CivilStatus.build_select_options(include_empty: { value: 'all' })
96
+ assert_equal options_array.size, 3
97
+ assert_equal options_array.first[1], 'all'
98
+ end
99
+
100
+ def test_options_building_with_custom_label_and_value
101
+ options_array = Codes::CivilStatus.build_select_options(include_empty: { label: 'Yaiii', value: 'all' })
83
102
  assert_equal options_array.size, 3
84
- puts options_array: options_array
103
+ assert_equal options_array.first[0], 'Yaiii'
104
+ assert_equal options_array.first[1], 'all'
85
105
  end
86
106
 
87
107
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code-box
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
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: 2013-09-10 00:00:00.000000000 Z
12
+ date: 2013-09-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord