ns-options 0.2.0 → 0.3.0

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/README.markdown CHANGED
@@ -382,6 +382,55 @@ App.settings.root # => /path/to/example, uses the args rule to build the path
382
382
 
383
383
  With the args rule, you can have a type class accept more than one argument. The first argument will always be the value to coerce. Any more arguments will be appended on after the value.
384
384
 
385
+ ## NsOptions::Proxy
386
+ Mix in NsOptions::Proxy to any module/class to make it proxy a namespace. This essentially turns your class into a namespace itself. You can interact with it just as if it were a namespace object. For example:
387
+
388
+ ```ruby
389
+ module Something
390
+ include NsOptions
391
+ include NsOptions::Proxy
392
+
393
+ # define options directly
394
+ option :foo
395
+ option :bar, :default => "Bar"
396
+
397
+ # define sub-namespaces
398
+ namespace :more do
399
+ option :another
400
+ end
401
+
402
+ end
403
+
404
+ # handle those options
405
+ Something.bar #=> "Bar"
406
+ Something.to_hash #=> {:foo => nil, :bar => "Bar"}
407
+ Something.each do |opt_name, opt_value|
408
+ ...
409
+ end
410
+ ```
411
+
412
+ What's great is that while your Something behaves like a namespace, you can still define methods and add to it just as you would normally in Ruby:
413
+
414
+ ```ruby
415
+ module Something
416
+ def self.awesome_bar
417
+ "Awesome #{bar}"
418
+ end
419
+ end
420
+
421
+ Something.awesome_bar # => "Awesome Bar"
422
+ ```
423
+
424
+ And remember, NsOptions is mixed in, so you can go ahead and create a root namespace as you normally would:
425
+
426
+ ```ruby
427
+ module Something
428
+ options(:else) do
429
+ option :baz
430
+ end
431
+ end
432
+ ```
433
+
385
434
  ## License
386
435
 
387
436
  Copyright (c) 2011 Collin Redding and Team Insight
@@ -0,0 +1,73 @@
1
+ module NsOptions::AssertMacros
2
+
3
+ # a set of Assert macros to help write namespace definition and
4
+ # regression tests in Assert (https://github.com/teaminsight/assert)
5
+
6
+ def self.included(receiver)
7
+ receiver.class_eval do
8
+ extend MacroMethods
9
+ end
10
+ end
11
+
12
+ module MacroMethods
13
+
14
+ def have_namespaces(*namespaces)
15
+ called_from = caller.first
16
+ macro_name = "have namespaces: #{namespaces.map{|ns| "'#{ns}'"}.join(', ')}"
17
+
18
+ Assert::Macro.new(macro_name) do
19
+ namespaces.each do |ns|
20
+ should "have a namespace named '#{ns}'", called_from do
21
+ assert_respond_to ns, subject
22
+ assert_kind_of NsOptions::Namespace, subject.send(ns)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ alias_method :have_namespace, :have_namespaces
28
+
29
+ def have_options(*options)
30
+ called_from = caller.first
31
+ macro_name = "have options: #{options.map{|opt| "'#{opt}'"}.join(', ')}"
32
+
33
+ Assert::Macro.new(macro_name) do
34
+ options.each do |opt|
35
+ should "have an option named '#{opt}'", called_from do
36
+ assert_respond_to opt, subject
37
+ assert_kind_of NsOptions::Option, subject.options[opt]
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def have_option(*args)
44
+ called_from = caller.first
45
+ rules, type_class, opt_name = NsOptions::Option.args(*args)
46
+ test_name = [
47
+ "have an option: '#{opt_name}'",
48
+ "of type '#{type_class}'",
49
+ "with rules '#{rules.inspect}'"
50
+ ].join(', ')
51
+
52
+ Assert::Macro.new(test_name) do
53
+
54
+ should test_name do
55
+ # name assertions
56
+ assert_respond_to opt_name, subject
57
+
58
+ opt = subject.options[opt_name]
59
+ assert_kind_of NsOptions::Option, opt
60
+
61
+ # type_class assertions
62
+ assert_equal type_class, opt.type_class
63
+
64
+ # rules assertions
65
+ assert_equal rules, opt.rules
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -30,6 +30,7 @@ module NsOptions
30
30
  # separate objects from the class and other instances. Modules only deal with a single
31
31
  # namespace at the module level.
32
32
  def options(name, key = nil, &block)
33
+ NsOptions::Helper.advisor.is_this_namespace_ok?(name, caller)
33
34
  key ||= name.to_s
34
35
  method_definitions = <<-CLASS_METHOD
35
36
 
@@ -8,8 +8,32 @@ module NsOptions
8
8
  self.namespace = namespace
9
9
  end
10
10
 
11
+ # root namespace advisor
12
+
13
+ def is_this_namespace_ok?(name, from = nil)
14
+ if [:options].include?(name.to_sym)
15
+ puts self.not_recommended_method_message('namespace', name)
16
+ else
17
+ return true
18
+ end
19
+ puts "From: #{(from || caller).first}"
20
+ false
21
+ end
22
+
23
+ # sub-namespace / namespace-option advisors
24
+
25
+ def is_this_sub_namespace_ok?(name, from = nil)
26
+ self.is_this_ok?(:'sub-namespace', name, (from || caller))
27
+ end
28
+
29
+ def is_this_option_ok?(name, from = nil)
30
+ self.is_this_ok?(:option, name, (from || caller))
31
+ end
32
+
33
+ # helper methods
34
+
11
35
  def is_this_ok?(kind, name, from)
12
- display = (kind == :option ? "option" : "sub-namespace")
36
+ display = kind.to_s
13
37
  if self.bad_methods.include?(name.to_sym)
14
38
  message = self.bad_method_message(display, name)
15
39
  exception = NsOptions::Errors::InvalidName.new(message, from)
@@ -19,18 +43,10 @@ module NsOptions
19
43
  elsif self.not_recommended_methods.include?(name.to_sym)
20
44
  puts self.not_recommended_method_message(display, name)
21
45
  else
22
- return false
46
+ return true
23
47
  end
24
48
  puts "From: #{from.first}"
25
- true
26
- end
27
-
28
- def is_this_option_ok?(name, from = nil)
29
- self.is_this_ok?(:option, name, (from || caller))
30
- end
31
-
32
- def is_this_namespace_ok?(name, from = nil)
33
- self.is_this_ok?(:namespace, name, (from || caller))
49
+ false
34
50
  end
35
51
 
36
52
  def is_already_defined?(name)
@@ -51,13 +67,15 @@ module NsOptions
51
67
  "Please choose a different name for your #{kind}."
52
68
  ].join(" ")
53
69
  end
70
+
54
71
  def duplicate_message(name)
55
72
  [ "WARNING! '#{name}' has already been defined and will be overwritten.",
56
73
  "It's likely that it will not behave as expected."
57
74
  ].join(" ")
58
75
  end
76
+
59
77
  def not_recommended_method_message(kind, name)
60
- [ "WARNING! The #{kind} '#{name}' overwrites a namespace method.",
78
+ [ "WARNING! The #{kind} '#{name}' overwrites a method NsOptions depends on.",
61
79
  "This will limit some of the functionality of NsOptions."
62
80
  ].join(" ")
63
81
  end
@@ -48,7 +48,7 @@ module NsOptions
48
48
  DEFINE_METHOD
49
49
  end
50
50
 
51
- def advisor(namespace)
51
+ def advisor(namespace=nil)
52
52
  NsOptions::Helper::Advisor.new(namespace)
53
53
  end
54
54
 
@@ -55,7 +55,7 @@ module NsOptions
55
55
  # The defined namespaces is returned as well.
56
56
  def namespace(name, key = nil, &block)
57
57
  key = "#{self.options.key}:#{(key || name)}"
58
- NsOptions::Helper.advisor(self).is_this_namespace_ok?(name, caller)
58
+ NsOptions::Helper.advisor(self).is_this_sub_namespace_ok?(name, caller)
59
59
  namespace = self.options.add_namespace(name, key, self, &block)
60
60
  NsOptions::Helper.define_namespace_methods(self, name)
61
61
  namespace
@@ -3,16 +3,24 @@ module NsOptions
3
3
  class Option
4
4
  attr_accessor :name, :value, :type_class, :rules
5
5
 
6
- def initialize(name, type_class, rules={})
7
- self.name = name.to_s
6
+ def self.rules(rules)
7
+ (rules || {}).tap do |r|
8
+ r[:args] = (r[:args] ? [*r[:args]] : [])
9
+ end
10
+ end
8
11
 
9
- # if a nil type_class is given, just use Object
10
- # this makes the option accept any value with no type coercion
11
- self.type_class = (type_class || Object)
12
+ def self.args(*args)
13
+ [ self.rules(args.last.kind_of?(::Hash) ? args.pop : {}),
14
+ # if a nil type_class is given, just use Object
15
+ # this makes the option accept any value with no type coercion
16
+ (args[1] || Object),
17
+ args[0].to_s
18
+ ]
19
+ end
12
20
 
13
- self.rules = rules
14
- self.rules[:args] = (self.rules[:args] ? [*self.rules[:args]] : [])
15
- self.value = rules[:default]
21
+ def initialize(*args)
22
+ self.rules, self.type_class, self.name = self.class.args(*args)
23
+ self.value = self.rules[:default]
16
24
  end
17
25
 
18
26
  # if reading a lazy_proc, call the proc and return its coerced return val
@@ -63,7 +71,11 @@ module NsOptions
63
71
  elsif self.type_class == Hash
64
72
  {}.merge(value)
65
73
  else
66
- self.type_class.new(value, *self.rules[:args])
74
+ begin
75
+ self.type_class.new(value, *self.rules[:args])
76
+ rescue ArgumentError => err
77
+ raise ArgumentError, "#{self.type_class} `initialize': #{err.message}"
78
+ end
67
79
  end
68
80
  end
69
81
 
@@ -17,8 +17,7 @@ module NsOptions
17
17
  end
18
18
 
19
19
  def add(*args)
20
- options = args.last.kind_of?(Hash) ? args.pop : {}
21
- option = NsOptions::Option.new(args[0], args[1], options)
20
+ option = NsOptions::Option.new(*args)
22
21
  self[option.name] = option
23
22
  end
24
23
 
@@ -0,0 +1,45 @@
1
+ module NsOptions::Proxy
2
+
3
+ # Mix this in to any module or class to make it proxy a namespace
4
+ # this means you can interact with the module/class/class-instance as
5
+ # if it were a namespace object itself. For example:
6
+
7
+ NAMESPACE = "__proxy_options__"
8
+
9
+ class << self
10
+
11
+ def included(receiver)
12
+ receiver.class_eval do
13
+ include NsOptions
14
+ options(NAMESPACE)
15
+
16
+ extend ProxyMethods
17
+ include ProxyMethods
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ module ProxyMethods
24
+
25
+ # just proxy to the NAMESPACE created when Proxy was mixed in
26
+
27
+ def method_missing(meth, *args, &block)
28
+ if (po = self.__proxy_options__) && po.respond_to?(meth.to_s)
29
+ po.send(meth.to_s, *args, &block)
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ def respond_to?(*args)
36
+ if (po = self.__proxy_options__) && po.respond_to?(args.first.to_s)
37
+ true
38
+ else
39
+ super
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -1,3 +1,3 @@
1
1
  module NsOptions
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/ns-options.rb CHANGED
@@ -1,12 +1,15 @@
1
1
  module NsOptions
2
2
  autoload :HasOptions, 'ns-options/has_options'
3
+ autoload :Proxy, 'ns-options/proxy'
3
4
  autoload :Helper, 'ns-options/helper'
4
5
  autoload :Namespace, 'ns-options/namespace'
5
6
  autoload :Namespaces, 'ns-options/namespaces'
6
7
  autoload :Option, 'ns-options/option'
7
8
  autoload :Options, 'ns-options/options'
8
9
  autoload :VERSION, 'ns-options/version'
9
-
10
+
11
+ autoload :AssertMacros, 'ns-options/assert_macros'
12
+
10
13
  module Errors
11
14
  autoload :InvalidName, 'ns-options/errors/invalid_name'
12
15
  end
data/test/helper.rb CHANGED
@@ -7,3 +7,21 @@ require 'test/support/app'
7
7
  require 'test/support/user'
8
8
 
9
9
  require 'assert-mocha'
10
+
11
+ module NsOptions
12
+ module TestOutput
13
+
14
+ module_function
15
+
16
+ def capture
17
+ out = StringIO.new
18
+ $stdout = out
19
+ yield
20
+ return out
21
+ ensure
22
+ $stdout = STDOUT
23
+ end
24
+
25
+ end
26
+ end
27
+
@@ -0,0 +1,42 @@
1
+ require 'assert'
2
+
3
+ module NsOptions::AssertMacros
4
+
5
+ class BaseTests < Assert::Context
6
+ desc "NsOptions::AssertMacros"
7
+ include NsOptions::AssertMacros
8
+
9
+ setup do
10
+ @cls = Class.new do
11
+ include NsOptions
12
+
13
+ options(:test) do
14
+ option :one
15
+ option :two, :default => 2
16
+ option :three, :required => true
17
+ option :four, :args => [5,6,7]
18
+ option :five, Pathname, :default => '.'
19
+
20
+ namespace :more do
21
+ option :seven
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ subject { @cls.test }
28
+
29
+ should have_namespace :more
30
+ should have_namespaces :more
31
+
32
+ should have_options(:one, :two, :three, :four, :five)
33
+ should have_option :one
34
+
35
+ should have_option :two, :default => 2
36
+ should have_option :three, :required => true
37
+ should have_option :four, :args => [5,6,7]
38
+ should have_option :five, Pathname, :default => '.'
39
+
40
+ end
41
+
42
+ end
@@ -17,12 +17,13 @@ module NsOptions::HasOptions
17
17
  subject{ @instance }
18
18
 
19
19
  should have_class_methods :options
20
+
20
21
  end
21
22
 
22
- class OptionsTest < BaseTest
23
+ class OptionsTests < BaseTest
23
24
  desc "options method"
24
25
 
25
- class WithAKeyTest < OptionsTest
26
+ class WithAKeyTest < OptionsTests
26
27
  desc "with a key"
27
28
  setup do
28
29
  @key = "configs-key"
@@ -42,13 +43,16 @@ module NsOptions::HasOptions
42
43
  assert_equal @key, subject.class.configs.options.key
43
44
  assert_match @key, subject.configs.options.key
44
45
  end
46
+
45
47
  should "have used the provided block to define the namespace" do
46
48
  assert_respond_to :something, subject.configs
47
49
  assert_respond_to :something=, subject.configs
48
50
  assert subject.configs.options.fetch(:something)
49
51
  end
52
+
50
53
  end
51
- class WithoutAKeyTest < OptionsTest
54
+
55
+ class WithoutAKeyTest < OptionsTests
52
56
  desc "without a key"
53
57
  setup do
54
58
  @name = "configs"
@@ -61,7 +65,26 @@ module NsOptions::HasOptions
61
65
  assert_equal @name, subject.class.configs.options.key
62
66
  assert_match @name, subject.configs.options.key
63
67
  end
68
+
69
+ end
70
+
71
+ class AdvisorTests < OptionsTests
72
+ desc "creating a root namespace with a bad name"
73
+ setup do
74
+ @ns_name = "options"
75
+ @output = NsOptions::TestOutput.capture do
76
+ @ns = @class.options(@ns_name.to_sym)
77
+ end
78
+ @advisor = NsOptions::Helper::Advisor.new(@ns)
79
+ end
80
+
81
+ should "output a message warning using the method name as a namespace name" do
82
+ expected = @advisor.not_recommended_method_message("namespace", "options")
83
+ assert_match expected, @output.string
84
+ end
85
+
64
86
  end
87
+
65
88
  end
66
89
 
67
90
  end
@@ -2,19 +2,6 @@ require 'assert'
2
2
 
3
3
  class NsOptions::Helper::Advisor
4
4
 
5
- module Output
6
- module_function
7
-
8
- def capture
9
- out = StringIO.new
10
- $stdout = out
11
- yield
12
- return out
13
- ensure
14
- $stdout = STDOUT
15
- end
16
- end
17
-
18
5
  class BaseTest < Assert::Context
19
6
  desc "NsOptions::Helper::Advisor"
20
7
  setup do
@@ -24,7 +11,7 @@ class NsOptions::Helper::Advisor
24
11
  subject{ @advisor }
25
12
 
26
13
  should have_accessors :namespace
27
- should have_instance_methods :is_this_ok?, :is_this_option_ok?, :is_this_namespace_ok?,
14
+ should have_instance_methods :is_this_ok?, :is_this_option_ok?, :is_this_sub_namespace_ok?,
28
15
  :is_already_defined?, :bad_methods, :not_recommended_methods, :bad_method_message,
29
16
  :duplicate_message, :not_recommended_method_message
30
17
 
@@ -61,7 +48,7 @@ class NsOptions::Helper::Advisor
61
48
  desc "with a duplicate option"
62
49
  setup do
63
50
  @namespace.option(:duplicate)
64
- @output = Output.capture do
51
+ @output = NsOptions::TestOutput.capture do
65
52
  @advisor.is_this_option_ok?("duplicate")
66
53
  end
67
54
  end
@@ -71,6 +58,7 @@ class NsOptions::Helper::Advisor
71
58
  assert_match expected, @output.string
72
59
  assert_match "From: ", @output.string
73
60
  end
61
+
74
62
  should "return true with a call to #is_already_defined?" do
75
63
  assert_equal true, subject.is_already_defined?(:duplicate)
76
64
  end
@@ -79,7 +67,7 @@ class NsOptions::Helper::Advisor
79
67
  class NotRecommendedOptionTest < BaseTest
80
68
  desc "with a not recommended option"
81
69
  setup do
82
- @output = Output.capture do
70
+ @output = NsOptions::TestOutput.capture do
83
71
  @advisor.is_this_option_ok?("apply")
84
72
  end
85
73
  end
@@ -91,11 +79,41 @@ class NsOptions::Helper::Advisor
91
79
  end
92
80
  end
93
81
 
94
- class BadNamespaceTest < BaseTest
95
- desc "with a bad namespace"
82
+ class NotRecommendedNamespaceTest < BaseTest
83
+ desc "with a not recommended root namespace"
96
84
  setup do
97
- begin
85
+ @output = NsOptions::TestOutput.capture do
98
86
  @advisor.is_this_namespace_ok?("options")
87
+ end
88
+ end
89
+
90
+ should "output a message warning using the method name as a namespace name" do
91
+ expected = subject.not_recommended_method_message("namespace", "options")
92
+ assert_match expected, @output.string
93
+ assert_match "From: ", @output.string
94
+ end
95
+ end
96
+
97
+ class NotRecommendedSubNamespaceTest < BaseTest
98
+ desc "with a not recommended sub namespace"
99
+ setup do
100
+ @output = NsOptions::TestOutput.capture do
101
+ @advisor.is_this_sub_namespace_ok?("apply")
102
+ end
103
+ end
104
+
105
+ should "output a message warning using the method name as a namespace name" do
106
+ expected = subject.not_recommended_method_message("sub-namespace", "apply")
107
+ assert_match expected, @output.string
108
+ assert_match "From: ", @output.string
109
+ end
110
+ end
111
+
112
+ class BadSubNamespaceTest < BaseTest
113
+ desc "with a bad sub namespace"
114
+ setup do
115
+ begin
116
+ @advisor.is_this_sub_namespace_ok?("options")
99
117
  rescue Exception => @exception
100
118
  end
101
119
  end
@@ -107,12 +125,12 @@ class NsOptions::Helper::Advisor
107
125
  end
108
126
  end
109
127
 
110
- class DuplicateNamespaceTest < BaseTest
111
- desc "with a duplicate namespace"
128
+ class DuplicateSubNamespaceTest < BaseTest
129
+ desc "with a duplicate sub namespace"
112
130
  setup do
113
131
  @namespace.namespace(:duplicate)
114
- @output = Output.capture do
115
- @advisor.is_this_namespace_ok?("duplicate")
132
+ @output = NsOptions::TestOutput.capture do
133
+ @advisor.is_this_sub_namespace_ok?("duplicate")
116
134
  end
117
135
  end
118
136
 
@@ -121,24 +139,10 @@ class NsOptions::Helper::Advisor
121
139
  assert_match expected, @output.string
122
140
  assert_match "From: ", @output.string
123
141
  end
142
+
124
143
  should "return true with a call to #is_already_defined?" do
125
144
  assert_equal true, subject.is_already_defined?(:duplicate)
126
145
  end
127
146
  end
128
147
 
129
- class NotRecommendedNamespaceTest < BaseTest
130
- desc "with a not recommended namespace"
131
- setup do
132
- @output = Output.capture do
133
- @advisor.is_this_namespace_ok?("apply")
134
- end
135
- end
136
-
137
- should "output a message warning using the method name as a namespace name" do
138
- expected = subject.not_recommended_method_message("sub-namespace", "apply")
139
- assert_match expected, @output.string
140
- assert_match "From: ", @output.string
141
- end
142
- end
143
-
144
148
  end
@@ -50,7 +50,7 @@ class NsOptions::Namespace
50
50
  assert_equal @type, option.type_class
51
51
  assert_equal @rules, option.rules
52
52
  end
53
-
53
+
54
54
  should "check if the option name is ok" do
55
55
  advisor = NsOptions::Helper::Advisor.new(@namespace)
56
56
  NsOptions::Helper.expects(:advisor).with(@namespace).returns(advisor)
@@ -117,11 +117,11 @@ class NsOptions::Namespace
117
117
  assert(namespace = subject.options.namespaces[:another])
118
118
  assert_equal "#{subject.options.key}:special_key", namespace.options.key
119
119
  end
120
-
120
+
121
121
  should "check if the namespace name is ok" do
122
122
  advisor = NsOptions::Helper::Advisor.new(@namespace)
123
123
  NsOptions::Helper.expects(:advisor).with(@namespace).returns(advisor)
124
- advisor.expects(:is_this_namespace_ok?)
124
+ advisor.expects(:is_this_sub_namespace_ok?)
125
125
  assert_nothing_raised do
126
126
  @namespace.namespace(:yet_another)
127
127
  end
@@ -6,10 +6,12 @@ class NsOptions::Option
6
6
  desc "NsOptions::Option"
7
7
  setup do
8
8
  @rules = { :default => "development", :require => true }
9
- @option = NsOptions::Option.new(:stage, String, @rules)
9
+ @args = [:stage, String, @rules]
10
+ @option = NsOptions::Option.new(*@args)
10
11
  end
11
12
  subject{ @option }
12
13
 
14
+ should have_class_method :rules, :args
13
15
  should have_accessors :name, :value, :type_class, :rules
14
16
 
15
17
  should "have set the name" do
@@ -33,6 +35,56 @@ class NsOptions::Option
33
35
  end
34
36
  end
35
37
 
38
+ class ParseRulesTests < BaseTest
39
+ desc "parsing rules"
40
+ setup do
41
+ @cases = [nil, {}, {:args => 'is'}].map do |c|
42
+ subject.class.rules(c)
43
+ end
44
+ end
45
+
46
+ should "always return them as a Hash" do
47
+ @cases.each { |c| assert_kind_of Hash, c }
48
+ end
49
+
50
+ should "always return with an array args rule" do
51
+ @cases.each do |c|
52
+ assert c.has_key? :args
53
+ assert_kind_of Array, c[:args]
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ class ParseArgsTests < BaseTest
60
+ desc "when parsing args"
61
+ setup do
62
+ @prules, @ptype_class, @pname = subject.class.args(*@args)
63
+ end
64
+
65
+ should "parse option rules arguments, defaulting to {:args => []}" do
66
+ assert_equal @rules, @prules
67
+
68
+ @prules, @ptype_class, @pname = subject.class.args('test')
69
+ assert_equal({:args => []}, @prules)
70
+ end
71
+
72
+ should "parse the name arg and convert to a string" do
73
+ assert_equal "stage", @pname
74
+
75
+ @prules, @ptype_class, @pname = subject.class.args('test')
76
+ assert_equal 'test', @pname
77
+ end
78
+
79
+ should "parse the type_class arg and default it to Object" do
80
+ assert_equal String, @ptype_class
81
+
82
+ @prules, @ptype_class, @pname = subject.class.args('test')
83
+ assert_equal Object, @ptype_class
84
+ end
85
+
86
+ end
87
+
36
88
  class IsSetTest < BaseTest
37
89
  desc "is_set method"
38
90
  setup do
@@ -178,6 +230,33 @@ class NsOptions::Option
178
230
  end
179
231
  end
180
232
 
233
+ class WithTypeClassArgErrorTests < BaseTest
234
+ desc "setting a value with arg error"
235
+ setup do
236
+ @err = begin
237
+ raise ArgumentError, "some test error"
238
+ rescue ArgumentError => err
239
+ err
240
+ end
241
+ class SuperSuperTestTest
242
+ def initialize(*args)
243
+ raise ArgumentError, "some test error"
244
+ end
245
+ end
246
+ @option = NsOptions::Option.new(:something, SuperSuperTestTest)
247
+ end
248
+
249
+ should "reraise the arg error, including its type_class in the error message" do
250
+ err = begin
251
+ @option.value = "arg error should be raised"
252
+ rescue Exception => err
253
+ err
254
+ end
255
+ assert_equal ArgumentError, err.class
256
+ assert_included @option.type_class.to_s, err.message
257
+ end
258
+ end
259
+
181
260
  class WithAValueOfTheSameClassTest < BaseTest
182
261
  desc "with a value of the same class"
183
262
  setup do
@@ -0,0 +1,77 @@
1
+ require 'assert'
2
+
3
+ module NsOptions::Proxy
4
+
5
+ class BaseTests < Assert::Context
6
+ desc "NsOptions::Proxy"
7
+
8
+ def self.proxy_a_namespace
9
+ Assert::Macro.new do
10
+ should "create a default namespace to proxy to" do
11
+ assert_respond_to NAMESPACE, subject
12
+ assert_kind_of NsOptions::Namespace, subject.send(NAMESPACE)
13
+ end
14
+
15
+ should "respond to namespace methods" do
16
+ assert_respond_to :option, subject
17
+ assert_respond_to :namespace, subject
18
+ assert_respond_to :to_hash, subject
19
+ assert_respond_to :each, subject
20
+ end
21
+
22
+ should "create options directly" do
23
+ assert_nothing_raised do
24
+ subject.option :test_opt
25
+ end
26
+ end
27
+
28
+ should "create namespaces directly" do
29
+ assert_nothing_raised do
30
+ subject.namespace :test_ns
31
+ end
32
+ end
33
+
34
+
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ class ModuleTests < BaseTests
41
+ desc "when mixed in to a module"
42
+ setup do
43
+ @mod = Module.new do
44
+ include NsOptions
45
+ include NsOptions::Proxy
46
+ end
47
+ end
48
+ subject { @mod }
49
+
50
+ should proxy_a_namespace
51
+
52
+ end
53
+
54
+ class ClassTests < BaseTests
55
+ desc "when mixed into a class"
56
+ setup do
57
+ @cls = Class.new do
58
+ include NsOptions
59
+ include NsOptions::Proxy
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ class ClassLevelTests < ClassTests
66
+ subject { @cls }
67
+ should proxy_a_namespace
68
+
69
+ end
70
+
71
+ class InstanceLevelTests < ClassTests
72
+ subject { @cls.new }
73
+ should proxy_a_namespace
74
+
75
+ end
76
+
77
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ns-options
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Collin Redding
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-28 00:00:00 Z
18
+ date: 2011-12-02 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :development
@@ -62,6 +62,7 @@ files:
62
62
  - README.markdown
63
63
  - Rakefile
64
64
  - lib/ns-options.rb
65
+ - lib/ns-options/assert_macros.rb
65
66
  - lib/ns-options/boolean.rb
66
67
  - lib/ns-options/errors/invalid_name.rb
67
68
  - lib/ns-options/has_options.rb
@@ -71,6 +72,7 @@ files:
71
72
  - lib/ns-options/namespaces.rb
72
73
  - lib/ns-options/option.rb
73
74
  - lib/ns-options/options.rb
75
+ - lib/ns-options/proxy.rb
74
76
  - lib/ns-options/version.rb
75
77
  - log/.gitkeep
76
78
  - ns-options.gemspec
@@ -80,6 +82,7 @@ files:
80
82
  - test/irb.rb
81
83
  - test/support/app.rb
82
84
  - test/support/user.rb
85
+ - test/unit/ns-options/assert_macros_test.rb
83
86
  - test/unit/ns-options/boolean_test.rb
84
87
  - test/unit/ns-options/has_options_test.rb
85
88
  - test/unit/ns-options/helper/advisor_test.rb
@@ -88,6 +91,7 @@ files:
88
91
  - test/unit/ns-options/namespaces_test.rb
89
92
  - test/unit/ns-options/option_test.rb
90
93
  - test/unit/ns-options/options_test.rb
94
+ - test/unit/ns-options/proxy_test.rb
91
95
  homepage:
92
96
  licenses: []
93
97
 
@@ -128,6 +132,7 @@ test_files:
128
132
  - test/irb.rb
129
133
  - test/support/app.rb
130
134
  - test/support/user.rb
135
+ - test/unit/ns-options/assert_macros_test.rb
131
136
  - test/unit/ns-options/boolean_test.rb
132
137
  - test/unit/ns-options/has_options_test.rb
133
138
  - test/unit/ns-options/helper/advisor_test.rb
@@ -136,3 +141,4 @@ test_files:
136
141
  - test/unit/ns-options/namespaces_test.rb
137
142
  - test/unit/ns-options/option_test.rb
138
143
  - test/unit/ns-options/options_test.rb
144
+ - test/unit/ns-options/proxy_test.rb