moosex 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.rspec +2 -0
- data/Changelog +12 -8
- data/Gemfile.lock +9 -1
- data/README.md +62 -3
- data/lib/moosex.rb +95 -74
- data/lib/moosex/version.rb +1 -1
- data/moosex.gemspec +1 -0
- data/samples/roles.rb +63 -0
- data/spec/baserole_spec.rb +174 -0
- data/spec/baz_spec.rb +1 -0
- data/spec/coerce_spec.rb +0 -4
- data/spec/moosex_spec.rb +1 -0
- data/spec/point_spec.rb +22 -15
- data/spec/role_spec.rb +83 -0
- data/spec/spec_helper.rb +7 -0
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 145aae5f2007ffa2f565296a4a256b27c32d5baa
|
4
|
+
data.tar.gz: e454cd3f240e2b47c53446bf14b44fd94aaab26e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f8761c2e4f9fbb9458f4bc7b4dc5db5f5dc1e1efa08b3d51d58da8595ec232178630afeb8909fb6b6252dabb287772e367dbc7eb2bad4c14ac38b1dc64e6094
|
7
|
+
data.tar.gz: b613aa258cc7a06e7f0f44ea7f00bfdcb8aff52bd122c512f330e4f025dcf83d61a875395158e9162dd4a88355e14d9861106c904e0bb86b42f741e1fa6a1af8
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
repo_token: CROa4WDRvgcQjh5zATUpjPRURmXEgATMt
|
data/.rspec
ADDED
data/Changelog
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
+
0.0.12 - 2013-02-05
|
2
|
+
- basic support override attributes #19
|
3
|
+
- basic support to roles #17
|
4
|
+
|
1
5
|
0.0.11 - 2013-02-04
|
2
6
|
- basic support to after/before/around #12
|
3
7
|
- improve exception #15
|
4
8
|
- improve type system via MooseX::Types #16
|
5
9
|
|
6
10
|
0.0.10 - 2014-02-03
|
7
|
-
- improve readme
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
- improve readme
|
12
|
+
- BUILDARGS should accept different signatures #36
|
13
|
+
- clearer create by default clear_#{attr_name}! public method
|
14
|
+
- add attr :private #35
|
15
|
+
- methods predicate, clearer and handles are no longer singleton methods #34
|
12
16
|
|
13
17
|
0.0.9 - 2014-02-02
|
14
18
|
- support to BUILD and BUILDARGS #5 and #6
|
@@ -24,9 +28,9 @@
|
|
24
28
|
- add min version of ruby should be 2.0.x
|
25
29
|
|
26
30
|
0.0.6 - 2014-02-01
|
27
|
-
|
28
|
-
|
29
|
-
|
31
|
+
- fix bug when extends subclass, now it is safe #18
|
32
|
+
- required attr with default value will no longer throw exception #30
|
33
|
+
- supports handles for: single method, array, Class or Module #27
|
30
34
|
|
31
35
|
0.0.5 - 2014-01-31
|
32
36
|
- should support handles #13 (partial)
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
moosex (0.0.
|
4
|
+
moosex (0.0.12)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
diff-lcs (1.2.5)
|
10
|
+
docile (1.1.3)
|
11
|
+
multi_json (1.8.4)
|
10
12
|
rake (10.1.1)
|
11
13
|
rspec (2.14.1)
|
12
14
|
rspec-core (~> 2.14.0)
|
@@ -16,6 +18,11 @@ GEM
|
|
16
18
|
rspec-expectations (2.14.5)
|
17
19
|
diff-lcs (>= 1.1.3, < 2.0)
|
18
20
|
rspec-mocks (2.14.5)
|
21
|
+
simplecov (0.8.2)
|
22
|
+
docile (~> 1.1.0)
|
23
|
+
multi_json
|
24
|
+
simplecov-html (~> 0.8.0)
|
25
|
+
simplecov-html (0.8.0)
|
19
26
|
|
20
27
|
PLATFORMS
|
21
28
|
ruby
|
@@ -25,3 +32,4 @@ DEPENDENCIES
|
|
25
32
|
moosex!
|
26
33
|
rake
|
27
34
|
rspec
|
35
|
+
simplecov
|
data/README.md
CHANGED
@@ -382,6 +382,10 @@ end
|
|
382
382
|
|
383
383
|
instead redefine the 'clear!' method in the subclass, we just add a piece of code, a lambda, and it will be executed after the normal 'clear!' method.
|
384
384
|
|
385
|
+
Each after/before/around will **redefine** the original method in order. If you want override the method in some subclass, you will loose all hooks. The best way to preserve all hooks is using after/before/around to modify the behavior if possible.
|
386
|
+
|
387
|
+
**IMPORTANT** This behavior is temporary, there is an issue for this [here](https://github.com/peczenyj/MooseX/issues/41 "issue in github").
|
388
|
+
|
385
389
|
### after
|
386
390
|
|
387
391
|
The after hook should receive the name of the method as a Symbol and a lambda. This lambda will, in the argument list, one reference for the object (self) and the rest of the arguments. This will redefine the the original method, add the code to run after the method. The after does not affect the return value of the original method, if you need this, use the 'around' hook.
|
@@ -422,15 +426,19 @@ The around hook is agressive: it will substitute the original method for a lambd
|
|
422
426
|
|
423
427
|
it is useful to manipulate the return value if you need.
|
424
428
|
|
425
|
-
## Types
|
429
|
+
## MooseX::Types
|
426
430
|
|
427
|
-
MooseX has a built-in type system to be helpful in many circunstances. How many times you need check if some argument is_a? Something? Or it respond_to? :some_method ? Now it is over. If you include the MooseX::Types module in your MooseX class you can use:
|
431
|
+
MooseX has a built-in type system to be helpful in many circunstances. How many times you need check if some argument is_a? Something? Or it respond_to? :some_method ? Now it is over. If you include the **MooseX::Types** module in your MooseX class you can use:
|
428
432
|
|
429
433
|
### isAny
|
430
434
|
|
431
435
|
will accept any type. Useful to combine with other types.
|
432
436
|
|
433
437
|
```ruby
|
438
|
+
class Example
|
439
|
+
include MooseX
|
440
|
+
include MooseX::Types
|
441
|
+
|
434
442
|
has x: { is: :rw, isa: isAny }
|
435
443
|
```
|
436
444
|
|
@@ -568,9 +576,60 @@ will combine all types and will fail if all of the condition fails.
|
|
568
576
|
}
|
569
577
|
```
|
570
578
|
|
579
|
+
## Roles
|
580
|
+
|
581
|
+
Roles are Modules with steroids. If you include the MooseX module in another module, this module became a "Role", capable of store attributes to be reuse in other MooseX classes. For example:
|
582
|
+
|
583
|
+
```ruby
|
584
|
+
require 'moosex'
|
585
|
+
|
586
|
+
module Eq
|
587
|
+
include MooseX.disable_warnings() # or enable_warningss (default)
|
588
|
+
|
589
|
+
requires :equal
|
590
|
+
|
591
|
+
def no_equal(other)
|
592
|
+
! self.equal(other)
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
module Valuable
|
597
|
+
include MooseX
|
598
|
+
|
599
|
+
has value: { is: :ro, required: true }
|
600
|
+
end
|
601
|
+
|
602
|
+
class Currency
|
603
|
+
include Valuable
|
604
|
+
include Eq # will warn unless disable_warnings was called.
|
605
|
+
# to avoid warnings, you should include after
|
606
|
+
# define all required modules,
|
607
|
+
|
608
|
+
def equal(other)
|
609
|
+
self.value == other.value
|
610
|
+
end
|
611
|
+
|
612
|
+
# include Eq # warning 'safe' include, after equal declaration
|
613
|
+
end
|
614
|
+
|
615
|
+
c1 = ComplexRole::Currency.new( value: 12 )
|
616
|
+
c2 = ComplexRole::Currency.new( value: 12 )
|
617
|
+
|
618
|
+
c1.equal(c2) # true, they have the same value
|
619
|
+
c1.no_equal(c2) # will return false
|
620
|
+
```
|
621
|
+
|
622
|
+
Roles can support has to describe attributes, and you can reuse code easily. You can also use after/before/around only in methods defined/imported in that Module.
|
623
|
+
|
624
|
+
For example, we can add a 'after' block for no_equal inside Eq, but not for equal - this limitation will be fixed soon (see issue #41 @ github).
|
625
|
+
|
626
|
+
### requires
|
627
|
+
|
628
|
+
You can also mark one or more methods as 'required'. When you do this, we will raise one exception if you try to create a new instance and the class does not implement it. It is a safe way to create interfaces or abstract classes. It uses respond_to? to verify.
|
629
|
+
|
571
630
|
## BUILD
|
572
631
|
|
573
|
-
If you need run some code after the creation of the object (like some extra validation), you should
|
632
|
+
If you need run some code after the creation of the object (like some extra validation), you should implement the BUILD method.
|
574
633
|
|
575
634
|
```ruby
|
576
635
|
class BuildExample
|
data/lib/moosex.rb
CHANGED
@@ -9,30 +9,56 @@ require "moosex/version"
|
|
9
9
|
require "moosex/types"
|
10
10
|
|
11
11
|
module MooseX
|
12
|
+
$MOOSEX_DEBUG = true
|
13
|
+
|
14
|
+
def MooseX.enable_warnings()
|
15
|
+
$MOOSEX_DEBUG = false
|
16
|
+
MooseX
|
17
|
+
end
|
18
|
+
|
19
|
+
def MooseX.disable_warnings()
|
20
|
+
$MOOSEX_DEBUG = false
|
21
|
+
MooseX
|
22
|
+
end
|
23
|
+
|
24
|
+
class RequiredMethodNotFoundError < NameError
|
25
|
+
end
|
12
26
|
|
13
27
|
def MooseX.included(c)
|
14
|
-
|
28
|
+
|
15
29
|
c.extend(MooseX::Core)
|
16
|
-
|
17
|
-
c.
|
18
|
-
|
30
|
+
|
31
|
+
def c.included(x)
|
32
|
+
MooseX.included(x)
|
33
|
+
x.__meta.load_from(self.__meta)
|
34
|
+
|
35
|
+
return unless x.is_a? Class
|
19
36
|
|
20
|
-
|
37
|
+
x.__meta.requires.each do |method|
|
38
|
+
unless x.public_instance_methods.include? method
|
39
|
+
warn "[MooseX] you must implement method '#{method}' in #{x} #{x.class}: required" if $MOOSEX_DEBUG
|
40
|
+
end
|
41
|
+
end
|
21
42
|
end
|
22
43
|
|
44
|
+
meta = MooseX::Meta.new
|
45
|
+
|
46
|
+
unless c.respond_to? :__meta
|
47
|
+
c.class_exec do
|
48
|
+
define_singleton_method(:__meta) { meta }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
23
52
|
def initialize(*args)
|
24
|
-
|
53
|
+
if self.respond_to? :BUILDARGS
|
54
|
+
args = self.BUILDARGS(*args)
|
55
|
+
else
|
56
|
+
args = args[0]
|
57
|
+
end
|
25
58
|
|
26
59
|
self.class.__meta().init(self, args || {})
|
27
60
|
|
28
|
-
BUILD()
|
29
|
-
end
|
30
|
-
|
31
|
-
def BUILDARGS(*args)
|
32
|
-
args[0]
|
33
|
-
end
|
34
|
-
|
35
|
-
def BUILD
|
61
|
+
self.BUILD() if self.respond_to? :BUILD
|
36
62
|
end
|
37
63
|
|
38
64
|
def c.inherited(subclass)
|
@@ -48,40 +74,45 @@ module MooseX
|
|
48
74
|
end
|
49
75
|
|
50
76
|
class Meta
|
51
|
-
attr_reader :attrs, :
|
77
|
+
attr_reader :attrs, :requires
|
52
78
|
|
53
79
|
def initialize(old_meta=nil)
|
54
|
-
@attrs
|
55
|
-
@
|
56
|
-
@before= Hash.new {|hash, key| hash[key] = []}
|
57
|
-
@around= Hash.new {|hash, key| hash[key] = []}
|
58
|
-
|
80
|
+
@attrs = {}
|
81
|
+
@requires = []
|
59
82
|
if old_meta
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@
|
83
|
+
old_meta.attrs.each_pair do |key, value|
|
84
|
+
@attrs[key] = value.clone
|
85
|
+
end
|
86
|
+
@requires = old_meta.requires.clone
|
64
87
|
end
|
65
88
|
end
|
66
|
-
|
67
|
-
def add(attr)
|
68
|
-
@attrs << attr
|
69
|
-
end
|
70
89
|
|
71
|
-
def
|
72
|
-
|
90
|
+
def load_from(other_meta)
|
91
|
+
other_meta.attrs.each_pair do |key, value|
|
92
|
+
@attrs[key] = value.clone
|
93
|
+
end
|
94
|
+
@requires += other_meta.requires
|
73
95
|
end
|
74
96
|
|
75
|
-
def
|
76
|
-
@
|
97
|
+
def add(attr)
|
98
|
+
@attrs[attr.attr_symbol] = attr
|
77
99
|
end
|
78
100
|
|
79
|
-
def
|
80
|
-
@
|
101
|
+
def add_requires(method)
|
102
|
+
@requires << method
|
81
103
|
end
|
82
104
|
|
83
105
|
def init(object, args)
|
84
|
-
@attrs.
|
106
|
+
@attrs.each_pair{ |symbol, attr| attr.init(object, args) }
|
107
|
+
|
108
|
+
warn "[MooseX] unused attributes #{args} for #{object.class}" if $MOOSEX_DEBUG && ! args.empty?
|
109
|
+
|
110
|
+
@requires.each do |method|
|
111
|
+
unless object.respond_to? method
|
112
|
+
raise RequiredMethodNotFoundError,
|
113
|
+
"you must implement method '#{method}' in #{object.class}: required"
|
114
|
+
end
|
115
|
+
end
|
85
116
|
end
|
86
117
|
end
|
87
118
|
|
@@ -95,7 +126,7 @@ module MooseX
|
|
95
126
|
result
|
96
127
|
end
|
97
128
|
|
98
|
-
__meta.add_after(method_name, block)
|
129
|
+
# __meta.add_after(method_name, block)
|
99
130
|
end
|
100
131
|
|
101
132
|
def before(method_name, &block)
|
@@ -106,7 +137,7 @@ module MooseX
|
|
106
137
|
method.bind(self).call(*args)
|
107
138
|
end
|
108
139
|
|
109
|
-
__meta.add_before(method_name, block)
|
140
|
+
# __meta.add_before(method_name, block)
|
110
141
|
end
|
111
142
|
|
112
143
|
def around(method_name, &block)
|
@@ -117,7 +148,14 @@ module MooseX
|
|
117
148
|
block.call(method, self,*args)
|
118
149
|
|
119
150
|
end
|
120
|
-
__meta.add_around(method, block)
|
151
|
+
# __meta.add_around(method, block)
|
152
|
+
end
|
153
|
+
|
154
|
+
def requires(*methods)
|
155
|
+
|
156
|
+
methods.each do |method_name|
|
157
|
+
__meta.add_requires(method_name)
|
158
|
+
end
|
121
159
|
end
|
122
160
|
|
123
161
|
def has(attr_name, attr_options = {})
|
@@ -131,7 +169,7 @@ module MooseX
|
|
131
169
|
end
|
132
170
|
else
|
133
171
|
|
134
|
-
attr = MooseX::Attribute.new(attr_name, attr_options)
|
172
|
+
attr = MooseX::Attribute.new(attr_name, attr_options, self)
|
135
173
|
|
136
174
|
attr.methods.each_pair do |method, proc|
|
137
175
|
define_method method, &proc
|
@@ -149,25 +187,6 @@ module MooseX
|
|
149
187
|
end
|
150
188
|
end
|
151
189
|
|
152
|
-
module Hook
|
153
|
-
class Base
|
154
|
-
attr_reader :method, :block
|
155
|
-
def initialize(method, block)
|
156
|
-
@method= method
|
157
|
-
@block = block
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
class After < Base
|
162
|
-
end
|
163
|
-
|
164
|
-
class Before < Base
|
165
|
-
end
|
166
|
-
|
167
|
-
class Around < Base
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
190
|
class InvalidAttributeError < TypeError
|
172
191
|
|
173
192
|
end
|
@@ -323,7 +342,7 @@ module MooseX
|
|
323
342
|
end,
|
324
343
|
};
|
325
344
|
|
326
|
-
def initialize(a, o)
|
345
|
+
def initialize(a, o, x)
|
327
346
|
#o ||= {}
|
328
347
|
# todo extract this to a framework, see issue #21 on facebook
|
329
348
|
o = DEFAULTS.merge({
|
@@ -361,22 +380,24 @@ module MooseX
|
|
361
380
|
end
|
362
381
|
|
363
382
|
@attr_symbol = a
|
364
|
-
@is = o
|
365
|
-
@isa = o
|
366
|
-
@default = o
|
367
|
-
@required = o
|
368
|
-
@predicate = o
|
369
|
-
@clearer = o
|
370
|
-
@handles = o
|
371
|
-
@lazy = o
|
372
|
-
@reader = o
|
373
|
-
@writter = o
|
374
|
-
@builder = o
|
375
|
-
@init_arg = o
|
376
|
-
@trigger = o
|
377
|
-
@coerce = o
|
383
|
+
@is = o.delete(:is)
|
384
|
+
@isa = o.delete(:isa)
|
385
|
+
@default = o.delete(:default)
|
386
|
+
@required = o.delete(:required)
|
387
|
+
@predicate = o.delete(:predicate)
|
388
|
+
@clearer = o.delete(:clearer)
|
389
|
+
@handles = o.delete(:handles)
|
390
|
+
@lazy = o.delete(:lazy)
|
391
|
+
@reader = o.delete(:reader)
|
392
|
+
@writter = o.delete(:writter)
|
393
|
+
@builder = o.delete(:builder)
|
394
|
+
@init_arg = o.delete(:init_arg)
|
395
|
+
@trigger = o.delete(:trigger)
|
396
|
+
@coerce = o.delete(:coerce)
|
378
397
|
@methods = {}
|
379
398
|
|
399
|
+
warn "[MooseX] unused attributes #{o} for attribute #{a} @ #{x} #{x.class}" if $MOOSEX_DEBUG && ! o.empty?
|
400
|
+
|
380
401
|
if @reader
|
381
402
|
@methods[@reader] = generate_reader
|
382
403
|
end
|
@@ -412,7 +433,7 @@ module MooseX
|
|
412
433
|
value_from_default = false
|
413
434
|
|
414
435
|
if args.has_key? @init_arg
|
415
|
-
value = args
|
436
|
+
value = args.delete(@init_arg)
|
416
437
|
elsif @default
|
417
438
|
value = @default.call
|
418
439
|
value_from_default = true
|
data/lib/moosex/version.rb
CHANGED
data/moosex.gemspec
CHANGED
data/samples/roles.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'moosex'
|
2
|
+
|
3
|
+
|
4
|
+
module Eq
|
5
|
+
include MooseX.disable_warnings()
|
6
|
+
|
7
|
+
requires :equal
|
8
|
+
|
9
|
+
def no_equal(other)
|
10
|
+
! self.equal(other)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Valuable
|
15
|
+
include MooseX
|
16
|
+
|
17
|
+
has value: { is: :ro, requires: true }
|
18
|
+
end
|
19
|
+
|
20
|
+
class Currency
|
21
|
+
include Valuable
|
22
|
+
include Eq # will warn unless disable_warnings was called.
|
23
|
+
# to avoid warnings, you should include after
|
24
|
+
# define all required modules,
|
25
|
+
|
26
|
+
def equal(other)
|
27
|
+
self.value == other.value
|
28
|
+
end
|
29
|
+
|
30
|
+
# include Eq # warning safe include
|
31
|
+
end
|
32
|
+
|
33
|
+
class Comparator
|
34
|
+
include MooseX
|
35
|
+
|
36
|
+
has compare_to: {
|
37
|
+
is: :ro,
|
38
|
+
isa: Eq,
|
39
|
+
handles: Eq,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
module Wrapper
|
44
|
+
include Eq
|
45
|
+
end
|
46
|
+
|
47
|
+
class WrongClass
|
48
|
+
include Wrapper
|
49
|
+
|
50
|
+
has one: { is: :rw }
|
51
|
+
end
|
52
|
+
|
53
|
+
c1 = Currency.new( value: 12 )
|
54
|
+
c2 = Currency.new( value: 12 )
|
55
|
+
c3 = Currency.new( value: 24 )
|
56
|
+
|
57
|
+
c1.equal(c2) # true
|
58
|
+
c1.equal(c3) # false
|
59
|
+
|
60
|
+
Comparator.new(compare_to: c1).no_equal(c2) # false
|
61
|
+
Comparator.new(compare_to: c1).no_equal(c3) # true
|
62
|
+
|
63
|
+
WrongClass.new(one: 1, two: 2) # will raise exception
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'moosex'
|
2
|
+
|
3
|
+
module RoleTest
|
4
|
+
module Name
|
5
|
+
include MooseX
|
6
|
+
|
7
|
+
has name: { is: :rw , required: true }
|
8
|
+
end
|
9
|
+
|
10
|
+
module Address
|
11
|
+
include MooseX
|
12
|
+
|
13
|
+
has address: { is: :rw , required: true }
|
14
|
+
end
|
15
|
+
|
16
|
+
class Person
|
17
|
+
include Name
|
18
|
+
include Address
|
19
|
+
|
20
|
+
has age: { is: :rw, required: true }
|
21
|
+
end
|
22
|
+
|
23
|
+
class Alien
|
24
|
+
include Name
|
25
|
+
include Address
|
26
|
+
|
27
|
+
has race: { is: :rw, required: true }
|
28
|
+
end
|
29
|
+
|
30
|
+
class FederationCitizen < Person
|
31
|
+
has starship: { is: :rw, required: true }
|
32
|
+
end
|
33
|
+
|
34
|
+
module Nameadress
|
35
|
+
include Name
|
36
|
+
include Address
|
37
|
+
|
38
|
+
has complement: { is: :rw, required: true}
|
39
|
+
end
|
40
|
+
|
41
|
+
class Enemy
|
42
|
+
include Nameadress
|
43
|
+
|
44
|
+
has weapons: { is: :rw, required: true}
|
45
|
+
end
|
46
|
+
|
47
|
+
class AlienX
|
48
|
+
include MooseX
|
49
|
+
include Name
|
50
|
+
include Address
|
51
|
+
|
52
|
+
has race: { is: :rw, required: true }
|
53
|
+
has x: { is: :rw, required: true }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe RoleTest::Person do
|
58
|
+
it "should create a new instance" do
|
59
|
+
RoleTest::Person.new( name: "john", address: "vulcano", age: 18)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should has a name" do
|
63
|
+
a = RoleTest::Person.new(name: "john", address: "vulcano", age: 18)
|
64
|
+
|
65
|
+
a.name.should == "john"
|
66
|
+
a.address.should == "vulcano"
|
67
|
+
a.age.should == 18
|
68
|
+
|
69
|
+
a.name = "b"
|
70
|
+
a.address = "Earth"
|
71
|
+
a.age = 120
|
72
|
+
|
73
|
+
a.name.should == "b"
|
74
|
+
a.address.should == "Earth"
|
75
|
+
a.age.should == 120
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe RoleTest::Alien do
|
80
|
+
it "should create a new instance" do
|
81
|
+
RoleTest::Alien.new( name: "john", address: "vulcano", race: :klingon)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should has a name" do
|
85
|
+
a = RoleTest::Alien.new(name: "john", address: "vulcano", race: :klingon)
|
86
|
+
|
87
|
+
a.name.should == "john"
|
88
|
+
a.address.should == "vulcano"
|
89
|
+
a.race.should == :klingon
|
90
|
+
|
91
|
+
a.name = "b"
|
92
|
+
a.address = "Earth"
|
93
|
+
a.race = :borg
|
94
|
+
|
95
|
+
a.name.should == "b"
|
96
|
+
a.address.should == "Earth"
|
97
|
+
a.race.should == :borg
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe RoleTest::FederationCitizen do
|
102
|
+
it "should create a new instance" do
|
103
|
+
RoleTest::FederationCitizen.new( name: "john", address: "vulcano", age: 18, starship: :enterprise)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should has a name" do
|
107
|
+
a = RoleTest::FederationCitizen.new(name: "john", address: "vulcano", age: 18, starship: :enterprise)
|
108
|
+
|
109
|
+
a.name.should == "john"
|
110
|
+
a.address.should == "vulcano"
|
111
|
+
a.age.should == 18
|
112
|
+
a.starship.should == :enterprise
|
113
|
+
|
114
|
+
a.name = "b"
|
115
|
+
a.address = "Earth"
|
116
|
+
a.age = 120
|
117
|
+
a.starship = :yamato
|
118
|
+
|
119
|
+
a.name.should == "b"
|
120
|
+
a.address.should == "Earth"
|
121
|
+
a.age.should == 120
|
122
|
+
a.starship.should == :yamato
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe RoleTest::Enemy do
|
127
|
+
it "should create a new instance" do
|
128
|
+
RoleTest::Enemy.new( name: "john", address: "vulcano", complement: 1, weapons: :phaser)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should has a name" do
|
132
|
+
a = RoleTest::Enemy.new(name: "john", address: "vulcano", complement: 1, weapons: :phaser)
|
133
|
+
|
134
|
+
a.name.should == "john"
|
135
|
+
a.address.should == "vulcano"
|
136
|
+
a.weapons.should == :phaser
|
137
|
+
a.complement.should == 1
|
138
|
+
|
139
|
+
a.name = "b"
|
140
|
+
a.address = "Earth"
|
141
|
+
a.weapons = :disruptor
|
142
|
+
a.complement = 7
|
143
|
+
|
144
|
+
a.name.should == "b"
|
145
|
+
a.address.should == "Earth"
|
146
|
+
a.weapons.should == :disruptor
|
147
|
+
a.complement.should == 7
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe RoleTest::AlienX do
|
152
|
+
it "should create a new instance" do
|
153
|
+
RoleTest::AlienX.new( name: "john", address: "vulcano", race: :klingon, x: 0)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should has a name" do
|
157
|
+
a = RoleTest::AlienX.new(name: "john", address: "vulcano", race: :klingon, x: 0)
|
158
|
+
|
159
|
+
a.name.should == "john"
|
160
|
+
a.address.should == "vulcano"
|
161
|
+
a.race.should == :klingon
|
162
|
+
a.x.should == 0
|
163
|
+
|
164
|
+
a.name = "b"
|
165
|
+
a.address = "Earth"
|
166
|
+
a.race = :borg
|
167
|
+
a.x = -1
|
168
|
+
|
169
|
+
a.name.should == "b"
|
170
|
+
a.address.should == "Earth"
|
171
|
+
a.race.should == :borg
|
172
|
+
a.x.should == -1
|
173
|
+
end
|
174
|
+
end
|
data/spec/baz_spec.rb
CHANGED
data/spec/coerce_spec.rb
CHANGED
data/spec/moosex_spec.rb
CHANGED
data/spec/point_spec.rb
CHANGED
@@ -110,13 +110,12 @@ describe "Point" do
|
|
110
110
|
end
|
111
111
|
|
112
112
|
class Point3D < Point
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
default: 1,
|
113
|
+
has x: {
|
114
|
+
is: :rw, # Redefine attribute
|
115
|
+
isa: String, # should be String
|
116
|
+
default: "5", # default value is "5" (constant)
|
118
117
|
}
|
119
|
-
|
118
|
+
|
120
119
|
has z: {
|
121
120
|
is: :rw, # read-write (mandatory)
|
122
121
|
isa: Integer, # should be Integer
|
@@ -131,8 +130,8 @@ class Point3D < Point
|
|
131
130
|
}
|
132
131
|
|
133
132
|
def clear
|
134
|
-
self.x= 0 # to run with type-check you must
|
135
|
-
self.y= 0
|
133
|
+
self.x= "0" # to run with type-check you must
|
134
|
+
self.y= 0 # use the setter instad @x=
|
136
135
|
self.z= 0
|
137
136
|
end
|
138
137
|
end
|
@@ -141,27 +140,35 @@ describe "Point3D" do
|
|
141
140
|
describe "should has an intelligent constructor" do
|
142
141
|
it "without arguments, should initialize with default values" do
|
143
142
|
p = Point3D.new
|
144
|
-
p.x.should ==
|
143
|
+
p.x.should == "5"
|
145
144
|
p.y.should be_zero
|
146
145
|
p.z.should be_zero
|
147
146
|
p.what_is_the_color_of_this_point.should == :red
|
148
147
|
end
|
149
148
|
|
150
149
|
it "should initialize only y" do
|
151
|
-
p = Point3D.new( x:
|
152
|
-
p.x.should ==
|
150
|
+
p = Point3D.new( x: "7" )
|
151
|
+
p.x.should == "7"
|
153
152
|
p.y.should be_zero
|
154
153
|
p.z.should be_zero
|
155
154
|
p.what_is_the_color_of_this_point.should == :red
|
156
155
|
end
|
157
156
|
|
158
157
|
it "should initialize x and y" do
|
159
|
-
p = Point3D.new( x: 5, y: 4, z: 8, color: :yellow)
|
160
|
-
p.x.should == 5
|
158
|
+
p = Point3D.new( x: "5", y: 4, z: 8, color: :yellow)
|
159
|
+
p.x.should == "5"
|
161
160
|
p.y.should == 4
|
162
161
|
p.z.should == 8
|
163
162
|
p.what_is_the_color_of_this_point.should == :yellow
|
164
163
|
end
|
164
|
+
|
165
|
+
it "for x, with type check" do
|
166
|
+
p = Point3D.new
|
167
|
+
expect {
|
168
|
+
p.x = 666
|
169
|
+
}.to raise_error(MooseX::Types::TypeCheckError,
|
170
|
+
"isa check for x=: Type violation: value '666' (Fixnum) is not an instance of [Type String]")
|
171
|
+
end
|
165
172
|
end
|
166
173
|
|
167
174
|
describe "should create a getter and a setter" do
|
@@ -187,9 +194,9 @@ describe "Point3D" do
|
|
187
194
|
end
|
188
195
|
|
189
196
|
it "clear should clean attributes" do
|
190
|
-
p = Point3D.new( x: 5, y: 4, z: 9)
|
197
|
+
p = Point3D.new( x: "5", y: 4, z: 9)
|
191
198
|
p.clear
|
192
|
-
p.x.should
|
199
|
+
p.x.should == "0"
|
193
200
|
p.y.should be_zero
|
194
201
|
p.z.should be_zero
|
195
202
|
end
|
data/spec/role_spec.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'moosex'
|
2
|
+
|
3
|
+
module ComplexRole
|
4
|
+
module Eq
|
5
|
+
include MooseX #.disable_warnings()
|
6
|
+
|
7
|
+
requires :equal
|
8
|
+
|
9
|
+
def no_equal(other)
|
10
|
+
! self.equal(other)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Valuable
|
15
|
+
include MooseX
|
16
|
+
|
17
|
+
has value: { is: :ro, required: true }
|
18
|
+
end
|
19
|
+
|
20
|
+
class Currency
|
21
|
+
include Valuable
|
22
|
+
include Eq # will warn unless disable_warnings was called.
|
23
|
+
# to avoid warnings, you should include after
|
24
|
+
# define all required modules,
|
25
|
+
|
26
|
+
def equal(other)
|
27
|
+
self.value == other.value
|
28
|
+
end
|
29
|
+
|
30
|
+
# include Eq # warning safe include
|
31
|
+
end
|
32
|
+
|
33
|
+
class Comparator
|
34
|
+
include MooseX
|
35
|
+
|
36
|
+
has compare_to: {
|
37
|
+
is: :ro,
|
38
|
+
isa: Eq,
|
39
|
+
handles: Eq,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
module Wrapper
|
44
|
+
include Eq
|
45
|
+
end
|
46
|
+
|
47
|
+
class WrongClass
|
48
|
+
include Wrapper
|
49
|
+
|
50
|
+
has one: { is: :rw }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "ComplexRole::Currency" do
|
55
|
+
it "should compare based on value" do
|
56
|
+
c1 = ComplexRole::Currency.new( value: 12 )
|
57
|
+
c2 = ComplexRole::Currency.new( value: 12 )
|
58
|
+
c3 = ComplexRole::Currency.new( value: 24 )
|
59
|
+
|
60
|
+
c1.equal(c2).should be_true
|
61
|
+
c1.equal(c3).should be_false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe ComplexRole::Comparator do
|
66
|
+
it "should compare two Currency instances" do
|
67
|
+
c1 = ComplexRole::Currency.new( value: 12 )
|
68
|
+
c2 = ComplexRole::Currency.new( value: 12 )
|
69
|
+
c3 = ComplexRole::Currency.new( value: 24 )
|
70
|
+
|
71
|
+
ComplexRole::Comparator.new(compare_to: c1).no_equal(c2).should be_false
|
72
|
+
ComplexRole::Comparator.new(compare_to: c1).no_equal(c3).should be_true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe ComplexRole::WrongClass do
|
77
|
+
it "should die unless implement missing method" do
|
78
|
+
expect {
|
79
|
+
ComplexRole::WrongClass.new(one: 1, two: 2)
|
80
|
+
}.to raise_error(MooseX::RequiredMethodNotFoundError,
|
81
|
+
"you must implement method 'equal' in ComplexRole::WrongClass: required")
|
82
|
+
end
|
83
|
+
end
|
data/spec/spec_helper.rb
ADDED
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.12
|
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-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: MooseX is an extension of Ruby object DSL. The main goal of MooseX is
|
56
70
|
to make Ruby Object Oriented programming easier, more consistent, and less tedious.
|
57
71
|
With MooseX you can think more about what you want to do and less about the mechanics
|
@@ -62,7 +76,9 @@ executables: []
|
|
62
76
|
extensions: []
|
63
77
|
extra_rdoc_files: []
|
64
78
|
files:
|
79
|
+
- ".coveralls.yml"
|
65
80
|
- ".gitignore"
|
81
|
+
- ".rspec"
|
66
82
|
- ".travis.yml"
|
67
83
|
- Changelog
|
68
84
|
- Gemfile
|
@@ -75,6 +91,8 @@ files:
|
|
75
91
|
- lib/moosex/version.rb
|
76
92
|
- moosex.gemspec
|
77
93
|
- samples/point.rb
|
94
|
+
- samples/roles.rb
|
95
|
+
- spec/baserole_spec.rb
|
78
96
|
- spec/baz_spec.rb
|
79
97
|
- spec/build_spec.rb
|
80
98
|
- spec/buildargs_spec.rb
|
@@ -87,6 +105,8 @@ files:
|
|
87
105
|
- spec/moosex_spec.rb
|
88
106
|
- spec/point_spec.rb
|
89
107
|
- spec/proxy_spec.rb
|
108
|
+
- spec/role_spec.rb
|
109
|
+
- spec/spec_helper.rb
|
90
110
|
- spec/trigger_spec.rb
|
91
111
|
- spec/types_spec.rb
|
92
112
|
homepage: http://github.com/peczenyj/MooseX
|
@@ -114,6 +134,7 @@ signing_key:
|
|
114
134
|
specification_version: 4
|
115
135
|
summary: A postmodern object DSL for Ruby
|
116
136
|
test_files:
|
137
|
+
- spec/baserole_spec.rb
|
117
138
|
- spec/baz_spec.rb
|
118
139
|
- spec/build_spec.rb
|
119
140
|
- spec/buildargs_spec.rb
|
@@ -126,5 +147,8 @@ test_files:
|
|
126
147
|
- spec/moosex_spec.rb
|
127
148
|
- spec/point_spec.rb
|
128
149
|
- spec/proxy_spec.rb
|
150
|
+
- spec/role_spec.rb
|
151
|
+
- spec/spec_helper.rb
|
129
152
|
- spec/trigger_spec.rb
|
130
153
|
- spec/types_spec.rb
|
154
|
+
has_rdoc:
|