selection_options_for 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.DS_Store ADDED
Binary file
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.5
2
+
3
+ * initial release as a rubygem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in selection_options_for.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2006 Mark Windholtz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # SelectionOptionsFor
2
+
3
+ This code allows you to keep the display labels in the model
4
+ when the DB holds only a 1 character flag.
5
+ and when the code requires symbolic references to the value to use in algorithms
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'selection_options_for'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install selection_options_for
20
+
21
+ ## Usage
22
+
23
+
24
+ SelectionOptionsFor
25
+ ===================
26
+
27
+ This code allows you to keep the display labels in the model
28
+ when the DB holds only a 1 character flag.
29
+ and when the code requires symbolic references to the value to use in algorithms
30
+
31
+ element 0 of the array passed in is always the logical symbol
32
+ If a 2-element Array is passed in, [key, label] and the first letter of label is the DB value
33
+ If a 3-element Array is passed in, [key, DB value, label]
34
+ Any other type passed in throws an error
35
+
36
+ Limitations: Don't use this if you will run reports directly against the DB
37
+ In that case, the reports will not have access to the display labels
38
+
39
+
40
+ class Article < ActiveRecord::Base
41
+ selection_options_for :file_type_option,
42
+ [:pdf, 'PDF'],
43
+ [:html, 'HTML'],
44
+ [:msword, 'MS-Word']
45
+ [:text, 'X', 'Textfile']
46
+ end
47
+
48
+ adds the following CLASS METHODS to Article
49
+
50
+ * file_type_options
51
+ returns a array of 2-value arrays suitable to fill a select tag
52
+ The second example shows how to start the selection on a blank
53
+ $ <%= select :article, :file_type_option, Article.file_type_options %>
54
+ $ <%= select :article, :file_type_option, [['','']] + Article.file_type_options %>
55
+
56
+ $ assert_equal ["MS-Word", "PDF", "HTML"], Article.file_type_option_hash.values
57
+ $ assert_equal "['MS-Word', 'PDF', 'HTML']", Article.file_type_option_js_list
58
+
59
+ $ file_type_option_symbols
60
+ returns hash of symbols
61
+
62
+ adds the following INSTANCE METHODS to Article
63
+
64
+ $ file_type_option_hash
65
+ $ file_type_option
66
+ returns the single character value as in the db
67
+
68
+ $ file_type_option_label
69
+ returns the current values label
70
+
71
+ $ file_type_option_symbol
72
+ returns the current values symbol
73
+
74
+ methods ending in '?' return boolean if the value is set
75
+ methods ending in '!' set the value
76
+
77
+ $ file_type_option_pdf?
78
+ $ file_type_option_pdf!
79
+
80
+ $ file_type_option_html?
81
+ $ file_type_option_html!
82
+
83
+ $ file_type_option_msword?
84
+ $ file_type_option_msword!
85
+
86
+ example #1: Selection list
87
+
88
+ article = Article.new
89
+ article.file_type_option_pdf!
90
+ assert_equal 'P', article.file_type_option
91
+ assert_equal :pdf, article.file_type_symbol
92
+ assert_equal true, article.file_type_option_pdf?
93
+ assert_equal 'PDF', article.file_type_option_label
94
+ assert_equal [["MS-Word", "M"], ["PDF", "P"], ["HTML", "H"]],
95
+ Article.file_type_options
96
+ assert_equal({"M"=>"MS-Word", "P"=>"PDF", "H"=>"HTML"},
97
+ Article.file_type_option_hash)
98
+
99
+ assert_equals({'P'=>:pdf, 'H'=>:html, 'W'=>:msword, 'T'=>:text},
100
+ Article.file_type_option_symbols)
101
+
102
+ By default the first letter of the label is used as the one character value
103
+ in the database field. When there are duplicate first letters
104
+ you can specify a different letter to be stored in the database
105
+ In the example below 'R' is stored in the database when
106
+ 'Credit Card Account' is selected.
107
+
108
+ Example #1: Selection list
109
+
110
+ class Article < ActiveRecord::Base
111
+ selection_options_for :payment_method_option,
112
+ [:basic, 'Basic'],
113
+ [:cash, 'Cash Account'],
114
+ [:cc, 'R','Credit Card Account']
115
+ end
116
+
117
+ $ <%= select :article, :payment_method_option, Article.payment_method_options %>
118
+
119
+ Example #2: Radio button labels
120
+
121
+ $ <% Article.payment_method_option_hash.each do | key, value | %>
122
+ $ <%= radio_button :article, :payment_method_option, key %> <%= value %><br />
123
+ $ <% end %>
124
+
125
+ Example #3 in a java_script list
126
+ payment_method_option_js_list
127
+
128
+
129
+ ## Contributing
130
+
131
+ 1. Fork it
132
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
133
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
134
+ 4. Push to the branch (`git push origin my-new-feature`)
135
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ require "selection_options_for/version"
2
+ require "selection_options_for/model_additions"
3
+ require "selection_options_for/railtie" if defined? Rails
4
+
5
+ module SelectionOptionsFor # :nodoc:
6
+ end
7
+
@@ -0,0 +1,62 @@
1
+ module ModelAdditions
2
+
3
+ def selection_options_for(id, *opts) # :nodoc:
4
+ id = id.to_s
5
+ id_hash = id + '_hash'
6
+ id_symbols = id + '_symbols'
7
+ class_eval <<-EOF
8
+ write_inheritable_attribute("#{id_hash}".to_sym, {})
9
+ write_inheritable_attribute("#{id_symbols}".to_sym, {})
10
+ def self.#{id_hash}()
11
+ read_inheritable_attribute("#{id_hash}".to_sym)
12
+ end
13
+ def self.#{id_symbols}()
14
+ read_inheritable_attribute("#{id_symbols}".to_sym)
15
+ end
16
+ def self.#{id}s
17
+ #{id_hash}.map { |key, value| [value,key] }.sort
18
+ end
19
+ def #{id}_label
20
+ #{self}.#{id_hash}[#{id}]
21
+ end
22
+ def self.#{id}_js_list
23
+ result = '['
24
+ #{id_hash}.values.sort.each{ |e| result = result + "'"+ e + "', "}
25
+ result.chop!.chop! if result.size > 2
26
+ result + ']'
27
+ end
28
+ def #{id}_symbol
29
+ #{self}.#{id_symbols}[self.#{id}]
30
+ end
31
+ EOF
32
+ # load the labels into the class id_hash variable
33
+ opts.each do |label|
34
+ unless label.class == Array
35
+ raise "Invalid item ["+ label.to_s + "] in :" + id + " of type [" + label.class.to_s + "]. Expected Array"
36
+ end
37
+ case label.size
38
+ when 2
39
+ letter, display_text = label[1].first, label[1]
40
+ when 3
41
+ letter, display_text = label[1], label[2]
42
+ else
43
+ raise "Invalid number of items in selection_options_for :" + id + " [" +
44
+ label.class.to_s + "]."
45
+ end
46
+ if(send(id_hash).has_key?(letter))
47
+ raise "Duplicate key during selection_options_for :" + id + ". key: " +
48
+ letter + ' for text: ' + display_text
49
+ end
50
+ send(id_hash)[letter] = display_text
51
+ send(id_symbols)[letter] = label[0]
52
+ module_eval <<-EOF2
53
+ def #{id}_#{label[0].to_s}?
54
+ self.#{id} == '#{letter}'
55
+ end
56
+ def #{id}_#{label[0].to_s}!
57
+ self.#{id} = '#{letter}'
58
+ end
59
+ EOF2
60
+ end # opts.each
61
+ end # selection_options_for
62
+ end
@@ -0,0 +1,9 @@
1
+ module SelectionOptionsFor
2
+ class Railtie < Rails::Railtie
3
+ initializer "selection_options_for.model_additions" do
4
+ ActiveSupport.on_load :active_record do
5
+ extend ModelAdditions
6
+ end
7
+ end # initializer
8
+ end # class
9
+ end # module
@@ -0,0 +1,3 @@
1
+ module SelectionOptionsFor
2
+ VERSION = "0.0.5" unless defined? SelectionOptionsFor::VERSION
3
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/selection_options_for/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Mark Windholtz"]
6
+ gem.email = ["mark@agiledna.com"]
7
+ gem.summary = %q{Display labels and symbolic references }
8
+ gem.description = %q{
9
+ This code allows you to keep the display labels in the model
10
+ when the DB holds only a 1 character flag.
11
+ and when the code requires symbolic references to the value to use in algorithms
12
+
13
+ element 0 of the array passed in is always the logical symbol
14
+ If a 2-element Array is passed in, [key, label] and the first letter of label is the DB value
15
+ If a 3-element Array is passed in, [key, DB value, label]
16
+ Any other type passed in throws an error
17
+
18
+ Limitations: Don't use this if you will run reports directly against the DB
19
+ In that case, the reports will not have access to the display labels
20
+ }
21
+ gem.homepage = "https://github.com/mwindholtz/selection_options_for"
22
+
23
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ gem.files = `git ls-files`.split("\n")
25
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ gem.name = "selection_options_for"
27
+ gem.require_paths = ["lib"]
28
+ gem.version = SelectionOptionsFor::VERSION
29
+ end
@@ -0,0 +1,66 @@
1
+ ## ruby -Itest test/selection_options_for_ex_test.rb
2
+ require 'test_helper'
3
+
4
+ #
5
+ # test bad data and exceptions
6
+ #
7
+
8
+ class ModelUnderTest < ActiveRecord::Base
9
+ def self.columns() @columns ||= []; end
10
+ def self.column(name, sql_type = nil, default = nil, null = true)
11
+ columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
12
+ end
13
+
14
+ column :price_option, :string
15
+
16
+ begin
17
+ selection_options_for :price_option,
18
+ [:basic, 'Basic' ],
19
+ [:cash, 'Cash Account '],
20
+ [:cc, 'R','Credit Card Account'],
21
+ 123
22
+
23
+ rescue RuntimeError => ex
24
+ @@exception_num = ex
25
+ end
26
+
27
+ def self.exception_num
28
+ @@exception_num
29
+ end
30
+
31
+ begin
32
+ selection_options_for :status_option,
33
+ [:basic, 'Basic' ],
34
+ 'Cash Account',
35
+ [:cc, 'R','Credit Card Account']
36
+
37
+ rescue RuntimeError => ex
38
+ @@exception_string = ex
39
+ end
40
+
41
+ def self.exception_string
42
+ @@exception_string
43
+ end
44
+
45
+
46
+ end
47
+
48
+ class TranslateOptionsForExTest < Test::Unit::TestCase
49
+ def setup
50
+ @model = ModelUnderTest
51
+ end
52
+
53
+ def test_invalid_num
54
+ assert_equal RuntimeError, ModelUnderTest.exception_num.class
55
+ assert_equal "Invalid item [123] in :price_option of type [Fixnum]. Expected Array",
56
+ ModelUnderTest.exception_num.message
57
+ end
58
+
59
+ def test_invalid_string
60
+ assert_equal RuntimeError, ModelUnderTest.exception_string.class
61
+ assert_equal "Invalid item [Cash Account] in :status_option of type [String]. Expected Array",
62
+ ModelUnderTest.exception_string.message
63
+ end
64
+
65
+
66
+ end
@@ -0,0 +1,167 @@
1
+ ## ruby -Itest test/selection_options_for_test.rb
2
+ require 'test_helper'
3
+
4
+ #
5
+ # setup three classes for these tests
6
+ #
7
+ # 1. ModelUnderTest -- declare selection_options_for to be tested
8
+ # 2. SiblingOfModelUnderTest -- make sure that no meta-level leaks occur
9
+ # 3. SubClassOfModel -- should have it's own copy of class variables
10
+ #
11
+
12
+ class SiblingOfModelUnderTest < ActiveRecord::Base
13
+ def self.columns() @columns ||= []; end
14
+ def self.column(name, sql_type = nil, default = nil, null = true)
15
+ columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
16
+ end
17
+ end
18
+
19
+ class ModelUnderTest < ActiveRecord::Base
20
+ def self.columns() @columns ||= []; end
21
+ def self.column(name, sql_type = nil, default = nil, null = true)
22
+ columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
23
+ end
24
+
25
+ column :status_option, :string
26
+ column :payment_method_option, :string
27
+
28
+ selection_options_for :status_option,
29
+ [:partial, 'Partial Registration'],
30
+ [:active, 'Active'],
31
+ [:changing_email, 'E', 'Active, Changing Email'],
32
+ [:inactive, 'Inactive'],
33
+ [:forgot_pw, 'F', 'Active, Forgot Password' ]
34
+
35
+ selection_options_for :payment_method_option,
36
+ [:basic, 'Basic'],
37
+ [:cash, 'Cash Account'],
38
+ [:cc, 'R','Credit Card Account']
39
+
40
+ selection_options_for :sorted_option,
41
+ [:none, 'H', 'Honorary Member'],
42
+ [:member, 'M', 'CSM - Certified ScrumMaster'],
43
+ [:pract, 'P', 'CSP - Certified Scrum Practitioner'],
44
+ [:cst, 'T', 'CST - Certified Scrum Trainer'],
45
+ [:icst, 'I', 'ICST - Certified Scrum Trainer (inactive)']
46
+
47
+ end
48
+
49
+ class SubClassOfModel < ModelUnderTest
50
+ selection_options_for :payment_method_option,
51
+ [:advanced, 'Advanced'],
52
+ [:ecash, 'ECash Account']
53
+ end
54
+
55
+ class SelectionOptionsForTest < Test::Unit::TestCase
56
+ def setup
57
+ @model = ModelUnderTest
58
+ end
59
+
60
+ def test_should_provide_symbols
61
+ expected = {"Basic"=>:basic, "Cash Account"=>:cash, "R"=>:cc}
62
+ assert_equal expected, ModelUnderTest.payment_method_option_symbols
63
+ end
64
+
65
+ def test_should_provide_symbol
66
+ target = @model.new
67
+ target.status_option_forgot_pw!
68
+ assert_equal :forgot_pw, @model.status_option_symbols[target.status_option]
69
+ assert_equal :forgot_pw, target.status_option_symbol
70
+ end
71
+
72
+ def test_symbol_generation
73
+ target = @model.new
74
+ # forget PW
75
+ target.status_option_forgot_pw!
76
+ assert target.status_option_forgot_pw?
77
+ assert !target.status_option_active?
78
+ assert !target.status_option_changing_email?
79
+ assert !target.status_option_inactive?
80
+ assert !target.status_option_partial?
81
+ # active
82
+ target.status_option_active!
83
+ assert !target.status_option_forgot_pw?
84
+ assert target.status_option_active?
85
+ assert !target.status_option_changing_email?
86
+ assert !target.status_option_inactive?
87
+ assert !target.status_option_partial?
88
+ # active
89
+ target.status_option_inactive!
90
+ assert !target.status_option_forgot_pw?
91
+ assert !target.status_option_active?
92
+ assert !target.status_option_changing_email?
93
+ assert target.status_option_inactive?
94
+ assert !target.status_option_partial?
95
+ end
96
+
97
+ def test_sibling_of_target_not_effected_by_calss_methods
98
+ SiblingOfModelUnderTest.payment_method_options
99
+ flunk "Should throw Exception"
100
+ rescue NoMethodError => ex
101
+ assert true
102
+ rescue
103
+ flunk "wrong exception thrown"
104
+ end
105
+
106
+ def test_sibling_of_target_not_effected_by_instance_methods
107
+ sib = SiblingOfModelUnderTest.new
108
+ sib.status_option_partial?
109
+ flunk "Should throw Exception"
110
+ rescue NoMethodError => ex
111
+ assert true
112
+ rescue
113
+ flunk "wrong exception thrown"
114
+ end
115
+
116
+ def test_each_subclass_has_own_symbols
117
+
118
+ assert_equal [["Advanced", "Advanced"], ["ECash Account", "ECash Account"]].sort ,
119
+ SubClassOfModel.payment_method_options.sort
120
+ end
121
+
122
+ def test_payment_method_option_array
123
+
124
+ assert_equal [["Basic", "Basic"],
125
+ ["Cash Account", "Cash Account"],
126
+ ["Credit Card Account", "R"]].sort ,
127
+ @model.payment_method_options.sort
128
+ end
129
+
130
+ def test_default_status
131
+ target = @model.new
132
+ target.status_option_forgot_pw!
133
+ assert_equal 'Active, Forgot Password', target.status_option_label
134
+ target.status_option = 'Active'
135
+ assert_equal 'Active', target.status_option_label
136
+ end
137
+
138
+ def test_status_option_array
139
+
140
+ assert_equal [["Active", "Active"],
141
+ ["Active, Changing Email", "E"],
142
+ ["Active, Forgot Password", "F"],
143
+ ["Inactive", "Inactive"],
144
+ ["Partial Registration", "Partial Registration"]].sort ,
145
+ @model.status_options.sort
146
+ end
147
+
148
+ def test_default_payment_method_option_hash
149
+ expected = {"Cash Account"=>"Cash Account", "R"=>"Credit Card Account", "Basic"=>"Basic"}
150
+ assert_equal expected, @model.payment_method_option_hash
151
+ end
152
+
153
+ def test_status_option_js_list
154
+ assert_equal "['Active', 'Active, Changing Email', 'Active, Forgot Password', 'Inactive', 'Partial Registration']",
155
+ @model.status_option_js_list
156
+ end
157
+
158
+ def test_sorted_option_array
159
+ assert_equal [["CSM - Certified ScrumMaster", "M"],
160
+ ["CSP - Certified Scrum Practitioner", "P"],
161
+ ["CST - Certified Scrum Trainer", "T"],
162
+ ["Honorary Member", "H"],
163
+ ["ICST - Certified Scrum Trainer (inactive)", "I"]] ,
164
+ @model.sorted_options
165
+ end
166
+
167
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_record'
4
+ require File.dirname(__FILE__) + '/../lib/selection_options_for'
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: selection_options_for
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 5
10
+ version: 0.0.5
11
+ platform: ruby
12
+ authors:
13
+ - Mark Windholtz
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-09 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: "\n This code allows you to keep the display labels in the model \n when the DB holds only a 1 character flag.\n and when the code requires symbolic references to the value to use in algorithms\n \n element 0 of the array passed in is always the logical symbol\n If a 2-element Array is passed in, [key, label] and the first letter of label is the DB value\n If a 3-element Array is passed in, [key, DB value, label] \n Any other type passed in throws an error\n \n Limitations: Don't use this if you will run reports directly against the DB \n In that case, the reports will not have access to the display labels \n "
22
+ email:
23
+ - mark@agiledna.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .DS_Store
32
+ - CHANGELOG.md
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - lib/selection_options_for.rb
38
+ - lib/selection_options_for/model_additions.rb
39
+ - lib/selection_options_for/railtie.rb
40
+ - lib/selection_options_for/version.rb
41
+ - selection_options_for.gemspec
42
+ - test/selection_options_for_ex_test.rb
43
+ - test/selection_options_for_test.rb
44
+ - test/test_helper.rb
45
+ homepage: https://github.com/mwindholtz/selection_options_for
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.17
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Display labels and symbolic references
78
+ test_files:
79
+ - test/selection_options_for_ex_test.rb
80
+ - test/selection_options_for_test.rb
81
+ - test/test_helper.rb
82
+ has_rdoc: