moosex 0.0.9 → 0.0.10
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.
- checksums.yaml +4 -4
- data/Changelog +7 -0
- data/Gemfile.lock +1 -1
- data/README.md +285 -173
- data/lib/moosex.rb +56 -47
- data/lib/moosex/version.rb +1 -1
- data/moosex.gemspec +2 -2
- data/samples/point.rb +59 -0
- data/spec/baz_spec.rb +85 -0
- data/spec/build_spec.rb +23 -0
- data/spec/buildargs_spec.rb +106 -0
- data/spec/coerce_spec.rb +51 -0
- data/spec/foo_spec.rb +40 -0
- data/spec/lazy_spec.rb +126 -0
- data/spec/lol_spec.rb +42 -0
- data/spec/moosex_spec.rb +7 -746
- data/spec/point_spec.rb +201 -0
- data/spec/proxy_spec.rb +145 -0
- data/spec/trigger_spec.rb +83 -0
- metadata +26 -5
data/spec/point_spec.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'moosex'
|
2
|
+
|
3
|
+
class Point
|
4
|
+
include MooseX
|
5
|
+
|
6
|
+
has x: {
|
7
|
+
is: :rw, # read-write (mandatory)
|
8
|
+
isa: Integer, # should be Integer
|
9
|
+
default: 0, # default value is 0 (constant)
|
10
|
+
}
|
11
|
+
|
12
|
+
has y: {
|
13
|
+
is: :rw,
|
14
|
+
isa: Integer,
|
15
|
+
default: lambda { 0 }, # you should specify a lambda
|
16
|
+
}
|
17
|
+
|
18
|
+
has secret: {
|
19
|
+
is: :private,
|
20
|
+
}
|
21
|
+
|
22
|
+
def clear
|
23
|
+
self.x= 0 # to run with type-check you must
|
24
|
+
self.y= 0 # use the setter instad @x=
|
25
|
+
end
|
26
|
+
|
27
|
+
def change_secret(new_secret)
|
28
|
+
self.secret= new_secret
|
29
|
+
end
|
30
|
+
|
31
|
+
def show_secret
|
32
|
+
secret
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "Point" do
|
37
|
+
describe "should has an intelligent constructor" do
|
38
|
+
it "without arguments, should initialize with default values" do
|
39
|
+
p = Point.new
|
40
|
+
p.x.should be_zero
|
41
|
+
p.y.should be_zero
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should initialize only y" do
|
45
|
+
p = Point.new( x: 5 )
|
46
|
+
p.x.should == 5
|
47
|
+
p.y.should be_zero
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should initialize x and y" do
|
51
|
+
p = Point.new( x: 5, y: 4)
|
52
|
+
p.x.should == 5
|
53
|
+
p.y.should == 4
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "private accessors" do
|
58
|
+
it "should change private by method" do
|
59
|
+
p = Point.new(secret: 1)
|
60
|
+
p.show_secret.should == 1
|
61
|
+
p.change_secret(2)
|
62
|
+
p.show_secret.should == 2
|
63
|
+
end
|
64
|
+
|
65
|
+
it "cant read secret" do
|
66
|
+
p = Point.new
|
67
|
+
expect {
|
68
|
+
p.secret
|
69
|
+
}.to raise_error(NoMethodError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "cant write secret" do
|
73
|
+
p = Point.new
|
74
|
+
expect {
|
75
|
+
p.secret = 1
|
76
|
+
}.to raise_error(NoMethodError)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "should create a getter and a setter" do
|
81
|
+
it "for x" do
|
82
|
+
p = Point.new
|
83
|
+
p.x= 5
|
84
|
+
p.x.should == 5
|
85
|
+
end
|
86
|
+
|
87
|
+
it "for x, with type check" do
|
88
|
+
p = Point.new
|
89
|
+
expect {
|
90
|
+
p.x = "lol"
|
91
|
+
}.to raise_error('isa check for "x" failed: is not instance of Integer!')
|
92
|
+
end
|
93
|
+
|
94
|
+
it "for x, with type check" do
|
95
|
+
expect {
|
96
|
+
Point.new(x: "lol")
|
97
|
+
}.to raise_error('isa check for "x" failed: is not instance of Integer!')
|
98
|
+
end
|
99
|
+
|
100
|
+
it "clear should clean attributes" do
|
101
|
+
p = Point.new( x: 5, y: 4)
|
102
|
+
p.clear
|
103
|
+
p.x.should be_zero
|
104
|
+
p.y.should be_zero
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class Point3D < Point
|
110
|
+
|
111
|
+
has x: { # override original attr!
|
112
|
+
is: :rw,
|
113
|
+
isa: Integer,
|
114
|
+
default: 1,
|
115
|
+
}
|
116
|
+
|
117
|
+
has z: {
|
118
|
+
is: :rw, # read-write (mandatory)
|
119
|
+
isa: Integer, # should be Integer
|
120
|
+
default: 0, # default value is 0 (constant)
|
121
|
+
}
|
122
|
+
|
123
|
+
has color: {
|
124
|
+
is: :rw, # you should specify the reader/writter
|
125
|
+
reader: :what_is_the_color_of_this_point,
|
126
|
+
writter: :set_the_color_of_this_point,
|
127
|
+
default: :red,
|
128
|
+
}
|
129
|
+
|
130
|
+
def clear
|
131
|
+
self.x= 0 # to run with type-check you must
|
132
|
+
self.y= 0 # use the setter instad @x=
|
133
|
+
self.z= 0
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "Point3D" do
|
138
|
+
describe "should has an intelligent constructor" do
|
139
|
+
it "without arguments, should initialize with default values" do
|
140
|
+
p = Point3D.new
|
141
|
+
p.x.should == 1
|
142
|
+
p.y.should be_zero
|
143
|
+
p.z.should be_zero
|
144
|
+
p.what_is_the_color_of_this_point.should == :red
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should initialize only y" do
|
148
|
+
p = Point3D.new( x: 5 )
|
149
|
+
p.x.should == 5
|
150
|
+
p.y.should be_zero
|
151
|
+
p.z.should be_zero
|
152
|
+
p.what_is_the_color_of_this_point.should == :red
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should initialize x and y" do
|
156
|
+
p = Point3D.new( x: 5, y: 4, z: 8, color: :yellow)
|
157
|
+
p.x.should == 5
|
158
|
+
p.y.should == 4
|
159
|
+
p.z.should == 8
|
160
|
+
p.what_is_the_color_of_this_point.should == :yellow
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "should create a getter and a setter" do
|
165
|
+
it "for z" do
|
166
|
+
p = Point3D.new
|
167
|
+
p.z= 5
|
168
|
+
p.z.should == 5
|
169
|
+
end
|
170
|
+
|
171
|
+
it "for z, with type check" do
|
172
|
+
p = Point3D.new
|
173
|
+
expect {
|
174
|
+
p.z = "lol"
|
175
|
+
}.to raise_error('isa check for "z" failed: is not instance of Integer!')
|
176
|
+
end
|
177
|
+
|
178
|
+
it "for z, with type check" do
|
179
|
+
expect {
|
180
|
+
Point3D.new(z: "lol")
|
181
|
+
}.to raise_error('isa check for "z" failed: is not instance of Integer!')
|
182
|
+
end
|
183
|
+
|
184
|
+
it "clear should clean attributes" do
|
185
|
+
p = Point3D.new( x: 5, y: 4, z: 9)
|
186
|
+
p.clear
|
187
|
+
p.x.should be_zero
|
188
|
+
p.y.should be_zero
|
189
|
+
p.z.should be_zero
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "should create the accessors names with custom names" do
|
194
|
+
it "should get/set" do
|
195
|
+
p = Point3D.new
|
196
|
+
p.what_is_the_color_of_this_point.should == :red
|
197
|
+
p.set_the_color_of_this_point(:black)
|
198
|
+
p.what_is_the_color_of_this_point.should == :black
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
data/spec/proxy_spec.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'moosex'
|
2
|
+
|
3
|
+
class ProxyToTarget
|
4
|
+
include MooseX
|
5
|
+
|
6
|
+
has target: {
|
7
|
+
is: :ro,
|
8
|
+
default: lambda { Target.new }, # default, new instace of Target
|
9
|
+
handles: { # handles is for delegation,
|
10
|
+
my_method_x: :method_x, # inject methods with new names
|
11
|
+
my_method_y: :method_y, # old => obj.target.method_x
|
12
|
+
}, # now => obj.my_method_x
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
module TargetModule
|
17
|
+
def method_x; 1024; end # works with simple methods
|
18
|
+
def method_y(a,b,c); a + b + c; end # or methods with arguments
|
19
|
+
end
|
20
|
+
|
21
|
+
class Target
|
22
|
+
include TargetModule
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "ProxyToTarget" do
|
26
|
+
it "should delegate method_x to the target" do
|
27
|
+
p = ProxyToTarget.new
|
28
|
+
|
29
|
+
p.target.method_x.should == 1024
|
30
|
+
p.my_method_x.should == 1024
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should delegate method_y to the target" do
|
34
|
+
p = ProxyToTarget.new
|
35
|
+
|
36
|
+
p.target.method_y(1,2,3).should == 6
|
37
|
+
p.my_method_y(1,2,3).should == 6
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should inject method_y" do
|
41
|
+
p = ProxyToTarget.new
|
42
|
+
|
43
|
+
p.respond_to?(:my_method_y).should be_true
|
44
|
+
ProxyToTarget.instance_methods.member?(:my_method_y).should be_true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class ProxyToTargetUsingArrayOfMethods
|
49
|
+
include MooseX
|
50
|
+
|
51
|
+
has targetz: {
|
52
|
+
is: :ro,
|
53
|
+
default: lambda { Target.new },
|
54
|
+
handles: [
|
55
|
+
:method_x, :method_y # will inject all methods with same name
|
56
|
+
]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "ProxyToTargetUsingArrayOfMethods" do
|
61
|
+
it "should delegate method_x to the target" do
|
62
|
+
p = ProxyToTargetUsingArrayOfMethods.new
|
63
|
+
|
64
|
+
p.targetz.method_x.should == 1024
|
65
|
+
p.method_x.should == 1024
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should delegate method_y to the target" do
|
69
|
+
p = ProxyToTargetUsingArrayOfMethods.new
|
70
|
+
|
71
|
+
p.targetz.method_y(1,2,3).should == 6
|
72
|
+
p.method_y(1,2,3).should == 6
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class ProxyToTargetUsingSingleMethod
|
77
|
+
include MooseX
|
78
|
+
|
79
|
+
has target: {
|
80
|
+
is: :ro,
|
81
|
+
default: lambda { Target.new },
|
82
|
+
handles: "method_x" # coerce to an array of symbols
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "ProxyToTargetUsingSingleMethod" do
|
87
|
+
it "should delegate method_x to the target" do
|
88
|
+
p = ProxyToTargetUsingSingleMethod.new
|
89
|
+
|
90
|
+
p.target.method_x.should == 1024
|
91
|
+
p.method_x.should == 1024
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class ProxyToTargetUsingModule
|
96
|
+
include MooseX
|
97
|
+
|
98
|
+
has target: {
|
99
|
+
is: :ro,
|
100
|
+
default: lambda { Target.new },
|
101
|
+
handles: TargetModule # will import all methods from module
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "ProxyToTargetUsingModule" do
|
106
|
+
it "should delegate method_x to the target" do
|
107
|
+
p = ProxyToTargetUsingModule.new
|
108
|
+
|
109
|
+
p.target.method_x.should == 1024
|
110
|
+
p.method_x.should == 1024
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should delegate method_y to the target" do
|
114
|
+
p = ProxyToTargetUsingModule.new
|
115
|
+
|
116
|
+
p.target.method_y(1,2,3).should == 6
|
117
|
+
p.method_y(1,2,3).should == 6
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class ProxyToTargetUsingClass
|
122
|
+
include MooseX
|
123
|
+
|
124
|
+
has target: {
|
125
|
+
is: :ro,
|
126
|
+
default: lambda { Target.new },
|
127
|
+
handles: Target # will use only public methods on Target class
|
128
|
+
} # exclude methods from superclass
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "ProxyToTargetUsingClass" do
|
132
|
+
it "should delegate method_x to the target" do
|
133
|
+
p = ProxyToTargetUsingClass.new
|
134
|
+
|
135
|
+
p.target.method_x.should == 1024
|
136
|
+
p.method_x.should == 1024
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should delegate method_y to the target" do
|
140
|
+
p = ProxyToTargetUsingClass.new
|
141
|
+
|
142
|
+
p.target.method_y(1,2,3).should == 6
|
143
|
+
p.method_y(1,2,3).should == 6
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'moosex'
|
2
|
+
|
3
|
+
class TriggerTest
|
4
|
+
include MooseX
|
5
|
+
|
6
|
+
has logger: {
|
7
|
+
is: :ro
|
8
|
+
}
|
9
|
+
|
10
|
+
has attr_with_trigger: {
|
11
|
+
is: :rw,
|
12
|
+
trigger: :my_method,
|
13
|
+
}
|
14
|
+
|
15
|
+
has attr_with_trigger_ro: {
|
16
|
+
is: :ro,
|
17
|
+
trigger: :my_method,
|
18
|
+
}
|
19
|
+
|
20
|
+
has attr_with_default: {
|
21
|
+
is: :rw,
|
22
|
+
trigger: lambda do |object, new_value|
|
23
|
+
object.logger.log "will update attr_with_trigger with new value #{new_value}"
|
24
|
+
end,
|
25
|
+
default: 1,
|
26
|
+
}
|
27
|
+
|
28
|
+
has attr_lazy_trigger: {
|
29
|
+
is: :lazy,
|
30
|
+
trigger: :my_method,
|
31
|
+
builder: lambda{ |x| 1},
|
32
|
+
}
|
33
|
+
|
34
|
+
def my_method(new_value)
|
35
|
+
logger.log "will update attr_with_trigger with new value #{new_value}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "TriggerTest" do
|
40
|
+
it "should call trigger on constructor" do
|
41
|
+
log = double
|
42
|
+
log.should_receive(:log)
|
43
|
+
t = TriggerTest.new(attr_with_trigger: 1, logger: log)
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should call trigger on constructor (ro)" do
|
48
|
+
log = double
|
49
|
+
log.should_receive(:log)
|
50
|
+
t = TriggerTest.new(attr_with_trigger_ro: 1, logger: log)
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should NOT call trigger on constructor (with default)" do
|
55
|
+
log = double
|
56
|
+
log.should_not_receive(:log)
|
57
|
+
t = TriggerTest.new(logger: log)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should NOT call trigger on constructor (with default)" do
|
61
|
+
log = double
|
62
|
+
log.should_receive(:log)
|
63
|
+
t = TriggerTest.new(logger: log)
|
64
|
+
|
65
|
+
t.attr_with_default = 1
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should call trigger on setter" do
|
69
|
+
log = double
|
70
|
+
log.should_receive(:log)
|
71
|
+
t = TriggerTest.new(logger: log)
|
72
|
+
|
73
|
+
t.attr_with_trigger = 1
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should call trigger on setter" do
|
77
|
+
log = double
|
78
|
+
log.should_receive(:log)
|
79
|
+
t = TriggerTest.new(logger: log)
|
80
|
+
|
81
|
+
t.attr_lazy_trigger.should == 1
|
82
|
+
end
|
83
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moosex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Peczenyj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,8 +52,8 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description: MooseX is an extension of Ruby object
|
56
|
-
|
55
|
+
description: MooseX is an extension of Ruby object DSL. The main goal of MooseX is
|
56
|
+
to make Ruby Object Oriented programming easier, more consistent, and less tedious.
|
57
57
|
With MooseX you can think more about what you want to do and less about the mechanics
|
58
58
|
of OOP. It is a port of Moose/Moo from Perl to Ruby world.
|
59
59
|
email:
|
@@ -73,7 +73,18 @@ files:
|
|
73
73
|
- lib/moosex.rb
|
74
74
|
- lib/moosex/version.rb
|
75
75
|
- moosex.gemspec
|
76
|
+
- samples/point.rb
|
77
|
+
- spec/baz_spec.rb
|
78
|
+
- spec/build_spec.rb
|
79
|
+
- spec/buildargs_spec.rb
|
80
|
+
- spec/coerce_spec.rb
|
81
|
+
- spec/foo_spec.rb
|
82
|
+
- spec/lazy_spec.rb
|
83
|
+
- spec/lol_spec.rb
|
76
84
|
- spec/moosex_spec.rb
|
85
|
+
- spec/point_spec.rb
|
86
|
+
- spec/proxy_spec.rb
|
87
|
+
- spec/trigger_spec.rb
|
77
88
|
homepage: http://github.com/peczenyj/MooseX
|
78
89
|
licenses:
|
79
90
|
- MIT
|
@@ -97,6 +108,16 @@ rubyforge_project:
|
|
97
108
|
rubygems_version: 2.2.1
|
98
109
|
signing_key:
|
99
110
|
specification_version: 4
|
100
|
-
summary: A postmodern object
|
111
|
+
summary: A postmodern object DSL for Ruby
|
101
112
|
test_files:
|
113
|
+
- spec/baz_spec.rb
|
114
|
+
- spec/build_spec.rb
|
115
|
+
- spec/buildargs_spec.rb
|
116
|
+
- spec/coerce_spec.rb
|
117
|
+
- spec/foo_spec.rb
|
118
|
+
- spec/lazy_spec.rb
|
119
|
+
- spec/lol_spec.rb
|
102
120
|
- spec/moosex_spec.rb
|
121
|
+
- spec/point_spec.rb
|
122
|
+
- spec/proxy_spec.rb
|
123
|
+
- spec/trigger_spec.rb
|