ns-options 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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