classx 0.0.1 → 0.0.2

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 (40) hide show
  1. data/ChangeLog +408 -2
  2. data/README +2 -2
  3. data/Rakefile +4 -3
  4. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-block_rb.html +1 -1
  5. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-callbacks_rb.html +1 -1
  6. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-change_rb.html +1 -1
  7. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-hunk_rb.html +1 -1
  8. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs_rb.html +1 -1
  9. data/doc/output/coverage/-Library-Ruby-Gems-gems-rcov-0_8_1_2_0-lib-rcov_rb.html +1 -1
  10. data/doc/output/coverage/index.html +37 -172
  11. data/doc/output/coverage/lib-classx-attribute_rb.html +788 -0
  12. data/doc/output/coverage/{-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-invokemethod_rb.html → lib-classx-attributes_rb.html} +96 -47
  13. data/doc/output/coverage/lib-classx-validate_rb.html +36 -36
  14. data/doc/output/coverage/lib-classx_rb.html +74 -151
  15. data/example/commandable.rb +28 -0
  16. data/lib/classx.rb +35 -112
  17. data/lib/classx/attribute.rb +178 -0
  18. data/lib/classx/attributes.rb +80 -8
  19. data/lib/classx/commandable.rb +38 -0
  20. data/lib/classx/validate.rb +1 -1
  21. data/spec/classx/default_option_spec.rb +140 -0
  22. data/spec/classx/handles_spec.rb +44 -0
  23. data/spec/classx/with_coerce.rb +79 -0
  24. data/spec/classx/with_extend.rb +25 -0
  25. data/spec/classx/with_include.rb +25 -0
  26. data/spec/classx/with_multiple_class_spec.rb +23 -0
  27. data/spec/classx/without_accessor_spec.rb +26 -0
  28. data/spec/classx/without_anyoption_spec.rb +23 -0
  29. data/spec/classx/writable_option_spec.rb +73 -0
  30. data/spec/classx_attributes_spec.rb +30 -0
  31. data/tasks/basic_config.rake +5 -1
  32. metadata +22 -15
  33. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-drb_rb.html +0 -2373
  34. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-eq_rb.html +0 -626
  35. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-forwardable_rb.html +0 -828
  36. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-pp_rb.html +0 -1257
  37. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-prettyprint_rb.html +0 -1506
  38. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-timeout_rb.html +0 -715
  39. data/lib/classx.rb.new +0 -102
  40. data/spec/classx_spec.rb +0 -261
@@ -1,8 +1,46 @@
1
1
  require 'optparse'
2
2
 
3
+ $ClassXCommandableMappingOf = {}
4
+
3
5
  class ClassX
4
6
  module Commandable
7
+ class MissingCoerceMapping < Exception; end
8
+
5
9
  def from_argv argv=ARGV.dup
10
+ OptionParser.new do |opt|
11
+ begin
12
+ opt.banner = "#{$0} [options]"
13
+ value_of = {}
14
+ attribute_of.each do |key, val|
15
+
16
+ val_format = val.value_class ? val.value_class : "VAL"
17
+ if val.optional?
18
+ val_format = "[ #{val_format} ]"
19
+ end
20
+
21
+ if val.value_class
22
+ begin
23
+ opt.on("--#{key} #{val_format}", val.value_class, val.desc) {|v| value_of[key] = v }
24
+ rescue Exception => e
25
+ if $ClassXCommandableMappingOf[val.value_class]
26
+ opt.on("--#{key} #{val_format}", $ClassXCommandableMappingOf[val.value_class], val.desc) {|v| value_of[key] = v }
27
+ else
28
+ raise MissingCoerceMapping, "missing coerce rule. please specify $ClassXCommandableMappingOf"
29
+ end
30
+ end
31
+ else
32
+ opt.on("--#{key} #{val_format}") {|v| value_of[key] = v }
33
+ end
34
+ end
35
+
36
+ opt.on('-h', '--help', 'show this document') {|v| raise OptionParser::ParseError }
37
+ opt.parse!(argv)
38
+ return new(value_of)
39
+ rescue ClassX::AttrRequiredError, OptionParser::ParseError => e
40
+ warn opt
41
+ exit
42
+ end
43
+ end
6
44
  end
7
45
  end
8
46
  end
@@ -28,7 +28,7 @@ module ClassX::Validate
28
28
  uniq_key = caller[0]
29
29
  unless @@__validate_cached[uniq_key]
30
30
  @@__validate_cached[uniq_key] = Class.new(ClassX)
31
- @@__validate_cached[uniq_key].class_eval &block
31
+ @@__validate_cached[uniq_key].class_eval(&block)
32
32
  end
33
33
  @@__validate_cached[uniq_key].new hash
34
34
  end
@@ -0,0 +1,140 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'with :default option' do
7
+ describe 'when value is Proc' do
8
+ before do
9
+ @class = Class.new(ClassX)
10
+ @class.class_eval do
11
+ has :x, :default => proc { Object.new }
12
+ end
13
+ end
14
+
15
+ it 'should have any value when instanciate' do
16
+ @class.new.x.should_not be_nil
17
+ end
18
+
19
+ it 'should have difference of object_id between some instance' do
20
+ @class.new.x.should_not equal(@class.new.x)
21
+ end
22
+
23
+ it "can use self as Proc's argument" do
24
+ @class.class_eval do
25
+ has :y, :default => proc {|mine| mine.x }, :lazy => true
26
+ has :z, :default => proc {|mine| mine.y }, :lazy => true
27
+ end
28
+
29
+ instance = @class.new
30
+ instance.y.should equal(instance.x)
31
+ instance.z.should equal(instance.y)
32
+ end
33
+ end
34
+
35
+ describe 'when value is not Proc' do
36
+ before do
37
+ @class = Class.new(ClassX)
38
+ @class.class_eval do
39
+ has :x, :default => []
40
+ end
41
+ end
42
+
43
+ it 'should have any value when instanciate' do
44
+ @class.new.x.should == []
45
+ end
46
+
47
+ it 'should have the same object_id between some instance' do
48
+ @class.new.x.should equal(@class.new.x)
49
+ end
50
+ end
51
+ end
52
+
53
+ describe 'with :optional is false' do
54
+ before do
55
+ @class = Class.new(ClassX)
56
+ @class.class_eval do
57
+ has :x, :optional => false
58
+ end
59
+ end
60
+
61
+ it "should raise AttrRequiredError without value" do
62
+ lambda { @class.new }.should raise_error(ClassX::AttrRequiredError)
63
+ end
64
+
65
+ it "should not raise AttrRequiredError with value" do
66
+ lambda { @class.new(:x => Object.new) }.should_not raise_error(ClassX::AttrRequiredError)
67
+ end
68
+
69
+ it 'should not raise AttrRequiredError with key as String' do
70
+ lambda { @class.new('x' => Object.new) }.should_not raise_error(ClassX::AttrRequiredError)
71
+ end
72
+ end
73
+
74
+ describe ':optional is false and with :default option' do
75
+ it 'should raise ClassX::RequiredAttrShouldNotHaveDefault' do
76
+ lambda {
77
+ klass = Class.new(ClassX)
78
+ klass.class_eval do
79
+ has :x, :optional => false, :default => 1
80
+ end
81
+ }.should raise_error(ClassX::RequiredAttrShouldNotHaveDefault)
82
+ end
83
+ end
84
+
85
+ describe 'declare attribute without :optional and :default option' do
86
+ before do
87
+ @class = Class.new(ClassX)
88
+ @class.class_eval do
89
+ has :x, :kind_of => Integer
90
+ end
91
+ end
92
+
93
+ it 'should be required attribute' do
94
+ lambda { @class.new }.should raise_error(ClassX::AttrRequiredError)
95
+ end
96
+ end
97
+
98
+ describe ':optional is true and without :default option' do
99
+ before do
100
+ @class = Class.new(ClassX)
101
+ @class.class_eval do
102
+ has :x, :optional => true, :kind_of => Integer
103
+ end
104
+ end
105
+
106
+ it 'should be required attribute' do
107
+ lambda { @class.new }.should_not raise_error(ClassX::AttrRequiredError)
108
+ end
109
+ end
110
+
111
+ describe 'with :optional is true' do
112
+ describe 'without :writable option' do
113
+ before do
114
+ @class = Class.new(ClassX)
115
+ @class.class_eval do
116
+ has :x, :optional => true
117
+ end
118
+ end
119
+ it 'should not raise AttrRequiredError' do
120
+ lambda { @class.new }.should_not raise_error(ClassX::AttrRequiredError)
121
+ end
122
+ end
123
+ end
124
+
125
+ describe 'not attribute param exist in #initialize argument' do
126
+ before do
127
+ @class = Class.new(ClassX)
128
+ @class.class_eval do
129
+ has :x
130
+ end
131
+ end
132
+
133
+ # TODO: I'll change it to be able to choosee wheather check this strictly or not.
134
+ # In many case, lack argument cause any problem. On the other hand, extra argument does not cause any problem, I think.
135
+ it 'should be ignored' do
136
+ lambda { @class.new(:x => 10, :y => 20 ) }.should_not raise_error(Exception)
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,44 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'with handles option as Hash' do
7
+ before do
8
+ @class1 = Class.new(ClassX)
9
+ @class1.class_eval do
10
+ has :x, :handles => { :x_inspect => :inspect }
11
+ end
12
+ end
13
+
14
+ it 'should respond_to x_inspect method' do
15
+ obj = Object.new
16
+ @class1.new(:x => obj).should be_respond_to(:x_inspect)
17
+ end
18
+
19
+ it 'should delegate method to value' do
20
+ obj = Object.new
21
+ @class1.new(:x => obj).x_inspect.should == obj.inspect
22
+ end
23
+ end
24
+
25
+ describe 'with handles option as Array' do
26
+ before do
27
+ @class1 = Class.new(ClassX)
28
+ @class1.class_eval do
29
+ has :x, :handles => [ :length ]
30
+ end
31
+ end
32
+
33
+ it 'should respond_to item name method' do
34
+ obj = [1, 2, 3]
35
+ @class1.new(:x => obj).should be_respond_to(:length)
36
+ end
37
+
38
+ it 'should delegate method to the same item name' do
39
+ obj = [1, 2, 3]
40
+ @class1.new(:x => obj).length.should == obj.length
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,79 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'with coece' do
7
+ describe 'when Array is value' do
8
+ before do
9
+ @class = Class.new(ClassX)
10
+ @class.class_eval do
11
+ has :x, :isa => Integer, :coerce => [
12
+ { proc {|val| val.respond_to? :to_i } => proc {|val| val.to_i } },
13
+ { proc {|val| val.respond_to? :to_s } => proc {|val| val.to_s } },
14
+ ]
15
+ end
16
+ end
17
+
18
+ it 'attrubute :x should convert Str to Integer' do
19
+ lambda { @class.new(:x => "10") }.should_not raise_error(Exception)
20
+ end
21
+
22
+ it 'attrubute :x should not convert Object to Integer' do
23
+ lambda { @class.new(:x => Object.new ) }.should raise_error(ClassX::InvalidAttrArgument)
24
+ end
25
+ end
26
+
27
+ describe 'when Proc is key' do
28
+ before do
29
+ @class = Class.new(ClassX)
30
+ @class.class_eval do
31
+ has :x, :isa => Integer, :coerce => { proc {|val| val.respond_to? :to_i } => proc {|val| val.to_i } }
32
+ end
33
+ end
34
+
35
+ it 'attrubute :x should convert Str to Integer' do
36
+ lambda { @class.new(:x => "10") }.should_not raise_error(Exception)
37
+ end
38
+
39
+ it 'attrubute :x should not convert Object to Integer' do
40
+ lambda { @class.new(:x => Object.new ) }.should raise_error(ClassX::InvalidAttrArgument)
41
+ end
42
+ end
43
+
44
+ describe 'when Symbol is key' do
45
+ before do
46
+ @class = Class.new(ClassX)
47
+ @class.class_eval do
48
+ has :x, :isa => Integer, :coerce => { :to_i => proc {|val| val.to_i } }
49
+ end
50
+ end
51
+
52
+ it 'attrubute :x should convert Str to Integer' do
53
+ lambda { @class.new(:x => "10") }.should_not raise_error(Exception)
54
+ end
55
+
56
+ it 'attrubute :x should not convert Object to Integer' do
57
+ lambda { @class.new(:x => Object.new ) }.should raise_error(ClassX::InvalidAttrArgument)
58
+ end
59
+ end
60
+
61
+ describe 'when Module or Class is key' do
62
+ before do
63
+ @class = Class.new(ClassX)
64
+ @class.class_eval do
65
+ has :x, :isa => Integer, :coerce => { String => proc {|val| val.to_i } }
66
+ end
67
+ end
68
+
69
+ it 'attrubute :x should convert Str to Integer' do
70
+ lambda { @class.new(:x => "10") }.should_not raise_error(Exception)
71
+ end
72
+
73
+ it 'attrubute :x should not convert Object to Integer' do
74
+ lambda { @class.new(:x => Object.new ) }.should raise_error(ClassX::InvalidAttrArgument)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,25 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'with extend' do
7
+ before do
8
+ @class = Class.new(ClassX)
9
+ mod = Module.new
10
+ mod.module_eval do
11
+ define_method :test do
12
+ :test
13
+ end
14
+ end
15
+ @class.class_eval do
16
+ has :x, :extend => mod
17
+ end
18
+ end
19
+
20
+ it 'attrubute :x should have test class method' do
21
+ @class.new(:x => 10).attribute_of['x'].class.test.should == :test
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'with include' do
7
+ before do
8
+ @class = Class.new(ClassX)
9
+ mod = Module.new
10
+ mod.module_eval do
11
+ define_method :test do
12
+ :test
13
+ end
14
+ end
15
+ @class.class_eval do
16
+ has :x, :include => mod
17
+ end
18
+ end
19
+
20
+ it 'attrubute :x should have #test method' do
21
+ @class.new(:x => 10).attribute_of['x'].test.should == :test
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'with multiple class' do
7
+ before do
8
+ @class1 = Class.new(ClassX)
9
+ @class1.class_eval do
10
+ has :x
11
+ end
12
+ @class2 = Class.new(ClassX)
13
+ @class2.class_eval do
14
+ end
15
+ end
16
+
17
+ it 'should not raise AttrRequiredError when initialized anothor class' do
18
+ lambda { @class2.new }.should_not raise_error(ClassX::AttrRequiredError)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'without accessor' do
7
+ before do
8
+ @class = Class.new(ClassX)
9
+ @class.class_eval do
10
+ end
11
+ end
12
+
13
+ it 'should not raise_error' do
14
+ lambda { @class.new }.should_not raise_error(Exception)
15
+ end
16
+
17
+ it 'should raise ArgumentError when recieved not kind of Hash instance as initialize argument' do
18
+ lambda { @class.new([]) }.should raise_error(ArgumentError)
19
+ end
20
+
21
+ it 'should have empty attributes' do
22
+ @class.attribute_of.keys.should be_empty
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+ require 'classx'
3
+
4
+ describe ClassX do
5
+ describe '#has' do
6
+ describe 'without any option' do
7
+ before do
8
+ @class = Class.new(ClassX)
9
+ @class.class_eval do
10
+ has :x
11
+ end
12
+ end
13
+
14
+ it 'should required :x on initialize' do
15
+ lambda { @class.new }.should raise_error(ClassX::AttrRequiredError)
16
+ end
17
+
18
+ it 'should define #x= private method to class' do
19
+ @class.private_instance_methods.map {|meth| meth.to_s }.should be_include("x=")
20
+ end
21
+ end
22
+ end
23
+ end