ns-options 0.4.1 → 1.0.0.rc1

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 (51) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +2 -1
  3. data/LICENSE +1 -1
  4. data/README.md +187 -301
  5. data/Rakefile +1 -1
  6. data/lib/ns-options/assert_macros.rb +9 -12
  7. data/lib/ns-options/boolean.rb +2 -0
  8. data/lib/ns-options/namespace.rb +34 -134
  9. data/lib/ns-options/namespace_advisor.rb +35 -0
  10. data/lib/ns-options/namespace_data.rb +166 -0
  11. data/lib/ns-options/namespaces.rb +23 -12
  12. data/lib/ns-options/option.rb +50 -24
  13. data/lib/ns-options/options.rb +23 -49
  14. data/lib/ns-options/proxy.rb +40 -53
  15. data/lib/ns-options/proxy_method.rb +54 -0
  16. data/lib/ns-options/root_methods.rb +77 -0
  17. data/lib/ns-options/version.rb +1 -1
  18. data/lib/ns-options.rb +18 -8
  19. data/ns-options.gemspec +3 -4
  20. data/test/helper.rb +3 -10
  21. data/test/support/app.rb +3 -1
  22. data/test/support/proxy.rb +4 -0
  23. data/test/support/type_class_proxy.rb +29 -0
  24. data/test/support/user.rb +5 -5
  25. data/test/{integration/app_test.rb → system/app_tests.rb} +8 -6
  26. data/test/{integration/proxy_test.rb → system/proxy_tests.rb} +12 -0
  27. data/test/system/type_class_proxy_tests.rb +108 -0
  28. data/test/system/user_tests.rb +146 -0
  29. data/test/unit/{ns-options/boolean_test.rb → boolean_tests.rb} +5 -4
  30. data/test/unit/namespace_advisor_tests.rb +69 -0
  31. data/test/unit/namespace_data_tests.rb +336 -0
  32. data/test/unit/namespace_tests.rb +205 -0
  33. data/test/unit/namespaces_tests.rb +99 -0
  34. data/test/unit/{ns-options/option_test.rb → option_tests.rb} +155 -93
  35. data/test/unit/options_tests.rb +152 -0
  36. data/test/unit/proxy_method_tests.rb +87 -0
  37. data/test/unit/{ns-options/proxy_test.rb → proxy_tests.rb} +52 -0
  38. data/test/unit/root_methods_tests.rb +126 -0
  39. metadata +58 -63
  40. data/lib/ns-options/errors/invalid_name.rb +0 -15
  41. data/lib/ns-options/has_options.rb +0 -53
  42. data/lib/ns-options/helper/advisor.rb +0 -88
  43. data/lib/ns-options/helper.rb +0 -87
  44. data/test/integration/user_test.rb +0 -94
  45. data/test/unit/ns-options/has_options_test.rb +0 -90
  46. data/test/unit/ns-options/helper/advisor_test.rb +0 -148
  47. data/test/unit/ns-options/helper_test.rb +0 -56
  48. data/test/unit/ns-options/namespace_test.rb +0 -432
  49. data/test/unit/ns-options/namespaces_test.rb +0 -55
  50. data/test/unit/ns-options/options_test.rb +0 -221
  51. /data/test/unit/{ns-options/assert_macros_test.rb → assert_macros_tests.rb} +0 -0
@@ -0,0 +1,205 @@
1
+ require 'assert'
2
+ require 'ns-options/namespace'
3
+
4
+ class NsOptions::Namespace
5
+
6
+ class BaseTests < Assert::Context
7
+ desc "NsOptions::Namespace"
8
+ setup do
9
+ @name = "something"
10
+ @namespace = NsOptions::Namespace.new(@name)
11
+ end
12
+ subject{ @namespace }
13
+
14
+ should have_reader :__name__, :__data__
15
+ should have_imeths :option, :opt, :namespace, :ns
16
+ should have_imeths :option_type_class, :opt_type_class
17
+ should have_imeths :required_set?, :valid?
18
+ should have_imeths :has_option?, :has_namespace?
19
+ should have_imeths :define, :build_from, :reset, :apply, :to_hash, :each
20
+
21
+ should "know its name" do
22
+ assert_equal @name, subject.__name__
23
+ end
24
+
25
+ should "contain its name key in its inspect output" do
26
+ assert_included ":something", subject.inspect
27
+ end
28
+
29
+ should "contain its to_hash representation in its inspect output" do
30
+ assert_included subject.to_hash.inspect, subject.inspect
31
+ end
32
+
33
+ should "know its option type class" do
34
+ assert_equal Object, subject.option_type_class
35
+ end
36
+
37
+ should "set its option type class" do
38
+ subject.option_type_class(String)
39
+ assert_equal String, subject.option_type_class
40
+ end
41
+
42
+ end
43
+
44
+ class OptionTests < BaseTests
45
+ desc "when adding an option named `something`"
46
+ setup do
47
+ @added_opt = @namespace.option('something', String, { :default => true })
48
+ end
49
+
50
+ should "have added an option to the namespace" do
51
+ assert subject.has_option? :something
52
+
53
+ opt = subject.__data__.child_options[:something]
54
+ assert_equal 'something', opt.name
55
+ assert_equal String, opt.type_class
56
+ assert_equal true, opt.rules[:default]
57
+ end
58
+
59
+ should "return the option it added" do
60
+ assert_kind_of NsOptions::Option, @added_opt
61
+
62
+ option = subject.__data__.child_options[:something]
63
+ assert_equal option, @added_opt
64
+ end
65
+
66
+ should "advise on the option name" do
67
+ not_recommended_warn = NsOptions::TestOutput.capture do
68
+ subject.option 'to_hash'
69
+ end
70
+ assert_match 'WARNING: ', not_recommended_warn
71
+
72
+ subject.option 'opt1'
73
+ duplicate_warn = NsOptions::TestOutput.capture do
74
+ subject.option 'opt1'
75
+ end
76
+ assert_match 'WARNING: ', duplicate_warn
77
+ end
78
+
79
+ should "respond to a reader/writer named after the option name" do
80
+ assert_responds_to :something, subject
81
+ assert_responds_to :something=, subject
82
+ end
83
+
84
+ should "return the option using the reader" do
85
+ assert_equal subject.__data__.child_options.get(:something), subject.something
86
+ end
87
+
88
+ should "be writable through the defined writer" do
89
+ assert_nothing_raised{ subject.something = "abc" }
90
+ assert_equal "abc", subject.something
91
+ end
92
+
93
+ should "be writable through the reader with args" do
94
+ assert_nothing_raised{ subject.something "123" }
95
+ assert_equal "123", subject.something
96
+ end
97
+
98
+ end
99
+
100
+ class NamespaceTests < BaseTests
101
+ desc "when adding a namespace named `something`"
102
+ setup do
103
+ @namespace.namespace('something') do
104
+ option :something_else
105
+ end
106
+ end
107
+
108
+ should "know that it has the child namespace" do
109
+ assert subject.has_namespace? :something
110
+
111
+ ns = subject.something
112
+ assert_kind_of NsOptions::Namespace, ns
113
+ assert_equal 'something', ns.__name__
114
+ assert ns.has_option? :something_else
115
+ end
116
+
117
+ should "respond to a reader named after the namespace name" do
118
+ assert_responds_to :something, subject
119
+ end
120
+
121
+ should "return the namespace using the reader" do
122
+ assert_equal subject.__data__.child_namespaces[:something], subject.something
123
+ end
124
+
125
+ should "define on the namespace if it is called with a block" do
126
+ ns = subject.something
127
+ assert_not ns.has_option? :defined_later
128
+
129
+ subject.something { option :defined_later }
130
+ assert ns.has_option? :defined_later
131
+ end
132
+
133
+ should "advise on the namespace name" do
134
+ not_recommended_warn = NsOptions::TestOutput.capture do
135
+ subject.namespace 'to_hash'
136
+ end
137
+ assert_match 'WARNING: ', not_recommended_warn
138
+
139
+ subject.namespace 'opt1'
140
+ duplicate_warn = NsOptions::TestOutput.capture do
141
+ subject.namespace 'opt1'
142
+ end
143
+ assert_match 'WARNING: ', duplicate_warn
144
+ end
145
+
146
+ end
147
+
148
+ class DynamicOptionNamespaceWriterTests < BaseTests
149
+
150
+ should "write non-pre-defined values as Object options" do
151
+ assert_not subject.has_option? :not_pre_defined
152
+ assert_responds_to :not_pre_defined=, subject
153
+ assert_not_responds_to :not_pre_defined, subject
154
+
155
+ assert_nothing_raised { subject.not_pre_defined = 123 }
156
+
157
+ assert subject.has_option? :not_pre_defined
158
+ assert_responds_to :not_pre_defined, subject
159
+
160
+ assert_equal 123, subject.not_pre_defined
161
+ assert_equal Object, subject.__data__.child_options['not_pre_defined'].type_class
162
+ end
163
+
164
+ should "raise NoMethodError when writing namespace values" do
165
+ subject.namespace('something')
166
+
167
+ assert_raises NoMethodError do
168
+ subject.something = 'a value'
169
+ end
170
+ assert_raises NoMethodError do
171
+ subject.something = {:a => 'value'}
172
+ end
173
+ end
174
+
175
+ end
176
+
177
+ class EqualityTests < BaseTests
178
+ desc "when compared for equality"
179
+ setup do
180
+ @named_values = {:some => 'value', 'another' => 'value'}
181
+ @namespace.apply(@named_values)
182
+ end
183
+
184
+ should "be equal to another namespace with the same named values" do
185
+ other_ns = NsOptions::Namespace.new('other_something')
186
+ other_ns.apply(@named_values)
187
+
188
+ assert_equal other_ns, subject
189
+ end
190
+
191
+ should "not be equal to another namespace with different values" do
192
+ other_ns = NsOptions::Namespace.new('other_something')
193
+ other_ns.apply({:other => 'data'})
194
+
195
+ assert_not_equal other_ns, subject
196
+ end
197
+
198
+ should "not be equal to other things" do
199
+ assert_not_equal 1, subject
200
+ assert_not_equal @named_values, subject
201
+ end
202
+
203
+ end
204
+
205
+ end
@@ -0,0 +1,99 @@
1
+ require 'assert'
2
+ require 'ns-options/namespaces'
3
+
4
+ class NsOptions::Namespaces
5
+
6
+ class BaseTests < Assert::Context
7
+ desc "NsOptions::Namespaces"
8
+ setup do
9
+ @namespaces = NsOptions::Namespaces.new
10
+ end
11
+ subject{ @namespaces }
12
+
13
+ should have_accessor :[]
14
+ should have_imeths :keys, :each, :empty?
15
+ should have_imeths :add, :rm, :get, :required_set?
16
+
17
+ should "only use strings for keys (indifferent access)" do
18
+ subject['string_key'] = true
19
+ subject[:symbol_key] = true
20
+
21
+ assert_includes 'string_key', subject.keys
22
+ assert_includes 'symbol_key', subject.keys
23
+ assert_not_includes :string_key, subject.keys
24
+ end
25
+
26
+ should "get items" do
27
+ subject[:a_key] = "a key"
28
+
29
+ assert_equal subject[:a_key], subject.get(:a_key)
30
+ assert_equal subject[:a_key], subject.get('a_key')
31
+ end
32
+
33
+ end
34
+
35
+ class AddTests < BaseTests
36
+ desc "add method"
37
+
38
+ should "add namespaces" do
39
+ assert_nil subject[:a_name]
40
+ subject.add(:a_name, NsOptions::Namespace.new(:a_name))
41
+ assert subject[:a_name]
42
+ end
43
+
44
+ should "should work with both string and symbol names" do
45
+ assert_nil subject[:a_name]
46
+ subject.add('a_name', NsOptions::Namespace.new('a_name'))
47
+ assert subject[:a_name]
48
+ end
49
+
50
+ should "return the option added" do
51
+ added_ns = subject.add(:a_name, NsOptions::Namespace.new(:a_name))
52
+ assert_kind_of NsOptions::Namespace, added_ns
53
+ end
54
+
55
+ end
56
+
57
+ class RmTests < BaseTests
58
+ desc "rm method"
59
+ setup do
60
+ @namespaces.add(:my_string, NsOptions::Namespace.new(:my_string))
61
+ end
62
+
63
+ should "remove the option definition from the collection" do
64
+ assert subject[:my_string]
65
+
66
+ subject.rm(:my_string)
67
+ assert_nil subject[:my_string]
68
+ end
69
+
70
+ should "should work with both string and symbol names" do
71
+ assert subject[:my_string]
72
+
73
+ subject.rm('my_string')
74
+ assert_nil subject[:my_string]
75
+ end
76
+
77
+ end
78
+
79
+ class RequiredSetTests < BaseTests
80
+ desc "with a namespace with :required options"
81
+ setup do
82
+ @namespace = NsOptions::Namespace.new :with_required do
83
+ option :required, :required => true
84
+ end
85
+ @namespaces[:with_required] = @namespace
86
+ end
87
+
88
+ should "know when its namespaces have all required set" do
89
+ assert_not subject.required_set?
90
+ @namespace.not_required = 'a value'
91
+ assert_not subject.required_set?
92
+
93
+ @namespace.required = 'something'
94
+ assert subject.required_set?
95
+ end
96
+
97
+ end
98
+
99
+ end