ns-options 0.4.1 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -141,6 +141,58 @@ module NsOptions::Proxy
141
141
  assert_equal @proxy2, @proxy1
142
142
  end
143
143
 
144
+ end
145
+
146
+ class DynamicOptionWriterTests < BaseTests
147
+ setup do
148
+ @mod = Module.new do
149
+ include NsOptions::Proxy
150
+
151
+ option :test
152
+ end
153
+ end
154
+ subject { @mod }
155
+
156
+ should "write non-pre-defined values as Object options" do
157
+ assert_not subject.has_option? :not_pre_defined
158
+ assert_responds_to :not_pre_defined=, subject
159
+ assert_not_responds_to :not_pre_defined, subject
160
+
161
+ assert_nothing_raised { subject.not_pre_defined = 123 }
162
+
163
+ assert subject.has_option? :not_pre_defined
164
+ assert_responds_to :not_pre_defined, subject
165
+
166
+ assert_equal 123, subject.not_pre_defined
167
+ assert_equal Object, subject.__data__.child_options['not_pre_defined'].type_class
168
+ end
169
+
170
+ end
171
+
172
+ class InheritedTests < BaseTests
173
+ desc "when inherited"
174
+ setup do
175
+ @a_super_class = Class.new do
176
+ include NsOptions::Proxy
177
+ option_type_class Fixnum
178
+
179
+ option :test
180
+ namespace(:other) { option :stuff }
181
+ end
182
+ end
183
+
184
+ should "pass its definition to any subclass" do
185
+ a_sub_class = Class.new(@a_super_class)
186
+
187
+ assert a_sub_class.has_option? :test
188
+ assert a_sub_class.has_namespace? :other
189
+ assert a_sub_class.other.has_option? :stuff
190
+
191
+ a_sub_ns_data = a_sub_class.__proxy_options__.__data__
192
+ assert_equal Fixnum, a_sub_ns_data.option_type_class
193
+ other_ns_data = a_sub_class.other.__data__
194
+ assert_equal Fixnum, other_ns_data.option_type_class
195
+ end
144
196
 
145
197
  end
146
198
 
@@ -0,0 +1,126 @@
1
+ require 'assert'
2
+ require 'ns-options/root_methods'
3
+ require 'ns-options/namespace'
4
+
5
+ class NsOptions::RootMethods
6
+
7
+ class BaseTests < Assert::Context
8
+ desc "NsOptions::RootMethods"
9
+ setup do
10
+ @rm = NsOptions::RootMethods.new(Module.new, 'whatever')
11
+ end
12
+ subject { @rm }
13
+
14
+ should have_imeths :define_on_class?, :define, :validate
15
+
16
+ end
17
+
18
+ class ValidateTests < BaseTests
19
+ desc "validate meth"
20
+ setup do
21
+ @io = StringIO.new(@out = "")
22
+ @caller = ["a test caller"]
23
+ end
24
+
25
+ should "return false for :options, :opts, :namespace, :ns names" do
26
+ [:options, :opts, :namespace, :ns].each do |meth|
27
+ rm = NsOptions::RootMethods.new(Module.new, meth)
28
+ assert_equal false, rm.validate(@io, @caller)
29
+ end
30
+
31
+ rm = NsOptions::RootMethods.new(Module.new, "anything_else")
32
+ assert_equal true, rm.validate(@io, @caller)
33
+ end
34
+
35
+ should "write a warning and any caller info" do
36
+ NsOptions::RootMethods.new(Module.new, :ns).validate(@io, @caller)
37
+
38
+ assert_match "WARNING: ", @out
39
+ assert_match @caller.first, @out
40
+ end
41
+
42
+ should "be called when calling `define'" do
43
+ NsOptions::RootMethods.new(Module.new, :ns).define(@io, @caller)
44
+
45
+ assert_match "WARNING: ", @out
46
+ assert_match @caller.first, @out
47
+ end
48
+
49
+ end
50
+
51
+ class ModuleTests < BaseTests
52
+ desc "defined on a module"
53
+ setup do
54
+ @rm = NsOptions::RootMethods.new(@the_module = Module.new, 'on_module')
55
+ @rm.define
56
+ end
57
+
58
+ should "know its not defining on a class" do
59
+ assert_not subject.define_on_class?
60
+ end
61
+
62
+ should "define a singleton method that builds a ns" do
63
+ assert_responds_to 'on_module', @the_module
64
+ assert_kind_of NsOptions::Namespace, @the_module.on_module
65
+ end
66
+
67
+ end
68
+
69
+ class ClassTests < BaseTests
70
+ desc "defined on a class"
71
+ setup do
72
+ @rm = NsOptions::RootMethods.new(@the_class = Class.new, 'on_class')
73
+ @rm.define
74
+ end
75
+
76
+ should "know its defining on a class" do
77
+ assert subject.define_on_class?
78
+ end
79
+
80
+ should "define a singleton method that builds a ns" do
81
+ assert_responds_to 'on_class', @the_class
82
+ ns = @the_class.on_class { option :opt1 }
83
+
84
+ assert_kind_of NsOptions::Namespace, ns
85
+ assert ns.__data__.has_option?(:opt1)
86
+ end
87
+
88
+ should "define an instance method that builds a ns from its singleton" do
89
+ @the_class.on_class { option :opt1 }
90
+ a_class = @the_class.new
91
+ assert_responds_to 'on_class', a_class
92
+ ns = a_class.on_class
93
+
94
+ assert_kind_of NsOptions::Namespace, ns
95
+ assert ns.__data__.has_option?(:opt1)
96
+ end
97
+
98
+ end
99
+
100
+ class InheritedClassTests < BaseTests
101
+ desc "when inherited"
102
+ setup do
103
+ @rm = NsOptions::RootMethods.new(@a_super_class = Class.new, 'a_ns')
104
+ @rm.define
105
+ @a_super_class.a_ns Fixnum do
106
+ option :test
107
+ namespace(:other) { option :stuff }
108
+ end
109
+ end
110
+
111
+ should "define a singleton method that builds a ns with the same def as its superclass" do
112
+ a_sub_class = Class.new(@a_super_class)
113
+
114
+ assert a_sub_class.a_ns.has_option? :test
115
+ assert a_sub_class.a_ns.has_namespace? :other
116
+ assert a_sub_class.a_ns.other.has_option? :stuff
117
+
118
+ a_sub_ns_data = a_sub_class.a_ns.__data__
119
+ assert_equal Fixnum, a_sub_ns_data.option_type_class
120
+ other_ns_data = a_sub_class.a_ns.other.__data__
121
+ assert_equal Fixnum, other_ns_data.option_type_class
122
+ end
123
+
124
+ end
125
+
126
+ end
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ns-options
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease:
4
+ hash: -1692815510
5
+ prerelease: 6
6
6
  segments:
7
+ - 1
8
+ - 0
7
9
  - 0
8
- - 4
10
+ - rc
9
11
  - 1
10
- version: 0.4.1
12
+ version: 1.0.0.rc1
11
13
  platform: ruby
12
14
  authors:
13
15
  - Collin Redding
@@ -15,39 +17,24 @@ autorequire:
15
17
  bindir: bin
16
18
  cert_chain: []
17
19
 
18
- date: 2012-06-05 00:00:00 Z
20
+ date: 2012-11-19 00:00:00 Z
19
21
  dependencies:
20
22
  - !ruby/object:Gem::Dependency
21
- type: :development
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
23
+ name: assert
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
25
  none: false
25
26
  requirements:
26
27
  - - ~>
27
28
  - !ruby/object:Gem::Version
28
- hash: 5
29
+ hash: 27
29
30
  segments:
30
31
  - 0
31
- - 7
32
- version: "0.7"
33
- version_requirements: *id001
34
- name: assert
35
- - !ruby/object:Gem::Dependency
32
+ - 8
33
+ version: "0.8"
36
34
  type: :development
35
+ requirement: *id001
37
36
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
43
- hash: 9
44
- segments:
45
- - 0
46
- - 1
47
- version: "0.1"
48
- version_requirements: *id002
49
- name: assert-mocha
50
- description: Define and use namespaced options with a clean interface.
37
+ description: A DSL for defining, organizing and accessing options.
51
38
  email:
52
39
  - collin.redding@reelfx.com
53
40
  executables: []
@@ -65,36 +52,39 @@ files:
65
52
  - lib/ns-options.rb
66
53
  - lib/ns-options/assert_macros.rb
67
54
  - lib/ns-options/boolean.rb
68
- - lib/ns-options/errors/invalid_name.rb
69
- - lib/ns-options/has_options.rb
70
- - lib/ns-options/helper.rb
71
- - lib/ns-options/helper/advisor.rb
72
55
  - lib/ns-options/namespace.rb
56
+ - lib/ns-options/namespace_advisor.rb
57
+ - lib/ns-options/namespace_data.rb
73
58
  - lib/ns-options/namespaces.rb
74
59
  - lib/ns-options/option.rb
75
60
  - lib/ns-options/options.rb
76
61
  - lib/ns-options/proxy.rb
62
+ - lib/ns-options/proxy_method.rb
63
+ - lib/ns-options/root_methods.rb
77
64
  - lib/ns-options/version.rb
78
65
  - log/.gitkeep
79
66
  - ns-options.gemspec
80
67
  - test/helper.rb
81
- - test/integration/app_test.rb
82
- - test/integration/proxy_test.rb
83
- - test/integration/user_test.rb
84
68
  - test/irb.rb
85
69
  - test/support/app.rb
86
70
  - test/support/proxy.rb
71
+ - test/support/type_class_proxy.rb
87
72
  - test/support/user.rb
88
- - test/unit/ns-options/assert_macros_test.rb
89
- - test/unit/ns-options/boolean_test.rb
90
- - test/unit/ns-options/has_options_test.rb
91
- - test/unit/ns-options/helper/advisor_test.rb
92
- - test/unit/ns-options/helper_test.rb
93
- - test/unit/ns-options/namespace_test.rb
94
- - test/unit/ns-options/namespaces_test.rb
95
- - test/unit/ns-options/option_test.rb
96
- - test/unit/ns-options/options_test.rb
97
- - test/unit/ns-options/proxy_test.rb
73
+ - test/system/app_tests.rb
74
+ - test/system/proxy_tests.rb
75
+ - test/system/type_class_proxy_tests.rb
76
+ - test/system/user_tests.rb
77
+ - test/unit/assert_macros_tests.rb
78
+ - test/unit/boolean_tests.rb
79
+ - test/unit/namespace_advisor_tests.rb
80
+ - test/unit/namespace_data_tests.rb
81
+ - test/unit/namespace_tests.rb
82
+ - test/unit/namespaces_tests.rb
83
+ - test/unit/option_tests.rb
84
+ - test/unit/options_tests.rb
85
+ - test/unit/proxy_method_tests.rb
86
+ - test/unit/proxy_tests.rb
87
+ - test/unit/root_methods_tests.rb
98
88
  homepage:
99
89
  licenses: []
100
90
 
@@ -115,35 +105,40 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
105
  required_rubygems_version: !ruby/object:Gem::Requirement
116
106
  none: false
117
107
  requirements:
118
- - - ">="
108
+ - - ">"
119
109
  - !ruby/object:Gem::Version
120
- hash: 3
110
+ hash: 25
121
111
  segments:
122
- - 0
123
- version: "0"
112
+ - 1
113
+ - 3
114
+ - 1
115
+ version: 1.3.1
124
116
  requirements: []
125
117
 
126
118
  rubyforge_project:
127
- rubygems_version: 1.8.11
119
+ rubygems_version: 1.8.24
128
120
  signing_key:
129
121
  specification_version: 3
130
- summary: Define and use namespaced options with a clean interface.
122
+ summary: A DSL for defining, organizing and accessing options.
131
123
  test_files:
132
124
  - test/helper.rb
133
- - test/integration/app_test.rb
134
- - test/integration/proxy_test.rb
135
- - test/integration/user_test.rb
136
125
  - test/irb.rb
137
126
  - test/support/app.rb
138
127
  - test/support/proxy.rb
128
+ - test/support/type_class_proxy.rb
139
129
  - test/support/user.rb
140
- - test/unit/ns-options/assert_macros_test.rb
141
- - test/unit/ns-options/boolean_test.rb
142
- - test/unit/ns-options/has_options_test.rb
143
- - test/unit/ns-options/helper/advisor_test.rb
144
- - test/unit/ns-options/helper_test.rb
145
- - test/unit/ns-options/namespace_test.rb
146
- - test/unit/ns-options/namespaces_test.rb
147
- - test/unit/ns-options/option_test.rb
148
- - test/unit/ns-options/options_test.rb
149
- - test/unit/ns-options/proxy_test.rb
130
+ - test/system/app_tests.rb
131
+ - test/system/proxy_tests.rb
132
+ - test/system/type_class_proxy_tests.rb
133
+ - test/system/user_tests.rb
134
+ - test/unit/assert_macros_tests.rb
135
+ - test/unit/boolean_tests.rb
136
+ - test/unit/namespace_advisor_tests.rb
137
+ - test/unit/namespace_data_tests.rb
138
+ - test/unit/namespace_tests.rb
139
+ - test/unit/namespaces_tests.rb
140
+ - test/unit/option_tests.rb
141
+ - test/unit/options_tests.rb
142
+ - test/unit/proxy_method_tests.rb
143
+ - test/unit/proxy_tests.rb
144
+ - test/unit/root_methods_tests.rb
@@ -1,15 +0,0 @@
1
- module NsOptions
2
- module Errors
3
-
4
- class InvalidName < StandardError
5
- attr_accessor :message
6
-
7
- def initialize(message, backtrace)
8
- self.message = message
9
- self.set_backtrace(backtrace)
10
- end
11
-
12
- end
13
-
14
- end
15
- end
@@ -1,53 +0,0 @@
1
- module NsOptions
2
-
3
- module HasOptions
4
- class << self
5
-
6
- def included(klass)
7
- klass.class_eval do
8
- extend NsOptions::HasOptions::DSL
9
- end
10
- end
11
-
12
- end
13
-
14
- module DSL
15
-
16
- # This is the main DSL method for creating a namespace of options for your
17
- # class/module. This will define a class method for both classes and
18
- # modules and an additional instance method for classes. The namespace is
19
- # then created and returned by calling the class method version. For
20
- # classes, the instance method will build an entirely new namespace from
21
- # the class level namespace. This is so when you define options at the
22
- # class level:
23
- #
24
- # class Something
25
- # include NsOptions
26
- # options(:settings) do
27
- # option :root
28
- # end
29
- # end
30
- #
31
- # the namespaces at the instance level still get all the defined options,
32
- # but are completely separate objects from the class and other instances.
33
- # Modules only deal with a single namespace at the module level.
34
-
35
- # The options method takes three args:
36
- # * `name` : what to name the defined methods for accessing the namespace
37
- # * `key` : (optional) what to key the created namespace objects with
38
- # - defaults to `name`
39
- # - useful if persisting namespaces into some key-value store
40
- # * `block`: (optional) a predefined set of nested options and namespaces
41
-
42
- def options(name, key = nil, &block)
43
- NsOptions::Helper.advisor.is_this_namespace_ok?(name, caller)
44
- NsOptions::Helper.define_root_namespace_methods(self, name, key)
45
- self.send(name, &block)
46
- end
47
- alias_method :opts, :options
48
-
49
- end
50
-
51
- end
52
-
53
- end
@@ -1,88 +0,0 @@
1
- require 'ns-options/errors/invalid_name'
2
-
3
- module NsOptions
4
- module Helper
5
-
6
- class Advisor
7
- attr_accessor :namespace
8
-
9
- def initialize(namespace)
10
- self.namespace = namespace
11
- end
12
-
13
- # root namespace advisor
14
-
15
- def is_this_namespace_ok?(name, from = nil)
16
- if [:options].include?(name.to_sym)
17
- puts self.not_recommended_method_message('namespace', name)
18
- else
19
- return true
20
- end
21
- puts "From: #{(from || caller).first}"
22
- false
23
- end
24
-
25
- # sub-namespace / namespace-option advisors
26
-
27
- def is_this_sub_namespace_ok?(name, from = nil)
28
- self.is_this_ok?(:'sub-namespace', name, (from || caller))
29
- end
30
-
31
- def is_this_option_ok?(name, from = nil)
32
- self.is_this_ok?(:option, name, (from || caller))
33
- end
34
-
35
- # helper methods
36
-
37
- def is_this_ok?(kind, name, from)
38
- display = kind.to_s
39
- if self.bad_methods.include?(name.to_sym)
40
- message = self.bad_method_message(display, name)
41
- exception = NsOptions::Errors::InvalidName.new(message, from)
42
- raise(exception)
43
- elsif self.is_already_defined?(name)
44
- puts self.duplicate_message(name)
45
- elsif self.not_recommended_methods.include?(name.to_sym)
46
- puts self.not_recommended_method_message(display, name)
47
- else
48
- return true
49
- end
50
- puts "From: #{from.first}"
51
- false
52
- end
53
-
54
- def is_already_defined?(name)
55
- self.namespace.options.is_defined?(name) ||
56
- self.namespace.options.is_namespace_defined?(name)
57
- end
58
-
59
- def bad_methods
60
- @bad_methods ||= [ :option, :namespace, :define, :options ]
61
- end
62
-
63
- def not_recommended_methods
64
- @not_recommended_methods ||= NsOptions::Namespace.instance_methods(false).map(&:to_sym)
65
- end
66
-
67
- def bad_method_message(kind, name)
68
- [ "The #{kind} '#{name}' overwrites a namespace method that NsOptions depends on.",
69
- "Please choose a different name for your #{kind}."
70
- ].join(" ")
71
- end
72
-
73
- def duplicate_message(name)
74
- [ "WARNING! '#{name}' has already been defined and will be overwritten.",
75
- "It's likely that it will not behave as expected."
76
- ].join(" ")
77
- end
78
-
79
- def not_recommended_method_message(kind, name)
80
- [ "WARNING! The #{kind} '#{name}' overwrites a method NsOptions depends on.",
81
- "This will limit some of the functionality of NsOptions."
82
- ].join(" ")
83
- end
84
-
85
- end
86
-
87
- end
88
- end
@@ -1,87 +0,0 @@
1
- require 'ns-options/helper/advisor'
2
-
3
- module NsOptions
4
-
5
- module Helper
6
-
7
- module_function
8
-
9
- def find_and_define_namespace(namespace, name)
10
- sub_namespace = namespace.options.get_namespace(name)
11
- self.define_namespace_methods(namespace, name)
12
- sub_namespace
13
- end
14
-
15
- def define_namespace_methods(namespace, name)
16
- namespace.metaclass.class_eval <<-DEFINE_METHOD
17
-
18
- def #{name}(&block)
19
- namespace = self.options.namespaces.get("#{name}")
20
- namespace.define(&block) if block
21
- namespace
22
- end
23
-
24
- DEFINE_METHOD
25
- end
26
-
27
- def find_and_define_option(namespace, option_name)
28
- option = namespace.options[option_name]
29
- self.define_option_methods(namespace, option)
30
- option
31
- end
32
-
33
- def define_option_methods(namespace, option)
34
- namespace.metaclass.class_eval <<-DEFINE_METHOD
35
-
36
- def #{option.name}(*args)
37
- if !args.empty?
38
- self.send("#{option.name}=", *args)
39
- else
40
- self.options.get(:#{option.name})
41
- end
42
- end
43
-
44
- def #{option.name}=(*args)
45
- value = args.size == 1 ? args.first : args
46
- self.options.set(:#{option.name}, value)
47
- end
48
-
49
- DEFINE_METHOD
50
- end
51
-
52
- def advisor(namespace=nil)
53
- NsOptions::Helper::Advisor.new(namespace)
54
- end
55
-
56
- def define_root_namespace_methods(define_on, name, key=nil)
57
- key ||= name.to_s
58
-
59
- # covers defining on Modules and at the class-level of Classes
60
- method_definitions = <<-CLASS_METHOD
61
-
62
- def self.#{name}(&block)
63
- @#{name} ||= NsOptions::Namespace.new('#{key}', &block)
64
- end
65
-
66
- CLASS_METHOD
67
-
68
- if define_on.kind_of?(Class)
69
- # covers defining at the instance-level of Classes
70
- method_definitions += <<-INSTANCE_METHOD
71
-
72
- def #{name}(&block)
73
- unless @#{name}
74
- @#{name} = NsOptions::Namespace.new('#{key}', &block)
75
- @#{name}.options.build_from(self.class.#{name}.options, @#{name})
76
- end
77
- @#{name}
78
- end
79
-
80
- INSTANCE_METHOD
81
- end
82
- define_on.class_eval(method_definitions)
83
- end
84
-
85
- end
86
-
87
- end