characterizable 0.0.0 → 0.0.1
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/VERSION +1 -1
- data/lib/characterizable.rb +46 -11
- data/test/test_characterizable.rb +40 -0
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1
|
data/lib/characterizable.rb
CHANGED
@@ -17,15 +17,23 @@ module Characterizable
|
|
17
17
|
klass.extend ClassMethods
|
18
18
|
end
|
19
19
|
|
20
|
+
def characteristics
|
21
|
+
@_characteristics ||= ArrayOfBoundCharacteristics.new self
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear_characteristics
|
25
|
+
@_characteristics = nil
|
26
|
+
end
|
27
|
+
|
20
28
|
def known_characteristics
|
21
|
-
|
22
|
-
c.known?
|
29
|
+
characteristics.select do |c|
|
30
|
+
c.known? and not c.trumped?
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
34
|
def unknown_characteristics
|
27
|
-
|
28
|
-
c.unknown?
|
35
|
+
characteristics.select do |c|
|
36
|
+
c.unknown? and c.requited? and not c.trumped?
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
@@ -57,6 +65,22 @@ module Characterizable
|
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
68
|
+
class ArrayOfBoundCharacteristics < ArrayOfCharacteristics
|
69
|
+
attr_reader :bound_obj
|
70
|
+
def initialize(*args)
|
71
|
+
@bound_obj = args.pop
|
72
|
+
super
|
73
|
+
load_bound_characteristics
|
74
|
+
end
|
75
|
+
def load_bound_characteristics
|
76
|
+
bound_obj.characterizable_base.characteristics.each do |c|
|
77
|
+
b_c = c.dup
|
78
|
+
b_c.bound_obj = bound_obj
|
79
|
+
push b_c
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
60
84
|
class Base
|
61
85
|
attr_reader :klass
|
62
86
|
def initialize(klass)
|
@@ -72,6 +96,8 @@ module Characterizable
|
|
72
96
|
end
|
73
97
|
|
74
98
|
class Characteristic
|
99
|
+
class TreatedBoundAsUnbound < RuntimeError; end
|
100
|
+
class TreatedUnboundAsBound < RuntimeError; end
|
75
101
|
attr_reader :base
|
76
102
|
attr_reader :name
|
77
103
|
attr_reader :trumps
|
@@ -88,20 +114,29 @@ module Characterizable
|
|
88
114
|
Blockenspiel.invoke block, self if block_given?
|
89
115
|
end
|
90
116
|
delegate :characteristics, :to => :base
|
91
|
-
|
92
|
-
|
117
|
+
attr_accessor :bound_obj
|
118
|
+
def effective_obj(obj = nil)
|
119
|
+
raise TreatedBoundAsUnbound, "Can't treat as unbound if bound object is set" if obj and bound_obj
|
120
|
+
raise TreatedUnboundAsBound, "Need an object if unbound" unless obj or bound_obj
|
121
|
+
obj || bound_obj
|
122
|
+
end
|
123
|
+
def value(obj = nil)
|
124
|
+
effective_obj(obj).send name
|
125
|
+
end
|
126
|
+
def unknown?(obj = nil)
|
127
|
+
value(obj).nil?
|
93
128
|
end
|
94
|
-
def known?(obj)
|
129
|
+
def known?(obj = nil)
|
95
130
|
not unknown?(obj)
|
96
131
|
end
|
97
|
-
def trumped?(obj)
|
98
|
-
characteristics.any? do |c|
|
132
|
+
def trumped?(obj = nil)
|
133
|
+
effective_obj(obj).characteristics.any? do |c|
|
99
134
|
c.known?(obj) and c.trumps.include?(name)
|
100
135
|
end
|
101
136
|
end
|
102
|
-
def requited?(obj)
|
137
|
+
def requited?(obj = nil)
|
103
138
|
return true if prerequisite.nil?
|
104
|
-
characteristics[prerequisite].known? obj
|
139
|
+
effective_obj(obj).characteristics[prerequisite].known? obj
|
105
140
|
end
|
106
141
|
def hidden?
|
107
142
|
hidden
|
@@ -120,4 +120,44 @@ class TestCharacterizable < Test::Unit::TestCase
|
|
120
120
|
assert a.known_characteristics.map(&:name).include?(:record_creation_date)
|
121
121
|
assert !a.visible_known_characteristics.map(&:name).include?(:record_creation_date)
|
122
122
|
end
|
123
|
+
|
124
|
+
should "be able to access values" do
|
125
|
+
a = Automobile.new
|
126
|
+
a.make = 'Ford'
|
127
|
+
b = Automobile.new
|
128
|
+
b.make = 'Pontiac'
|
129
|
+
assert_equal 'Ford', Automobile.characteristics[:make].value(a)
|
130
|
+
assert_equal 'Pontiac', Automobile.characteristics[:make].value(b)
|
131
|
+
end
|
132
|
+
|
133
|
+
should "give back characteristics with values when accessed from an instance" do
|
134
|
+
a = Automobile.new
|
135
|
+
a.make = 'Ford'
|
136
|
+
assert_equal 'Ford', a.characteristics[:make].value
|
137
|
+
end
|
138
|
+
|
139
|
+
should "not allow treating [unbound] characteristics like bound ones" do
|
140
|
+
a = Automobile.new
|
141
|
+
a.make = 'Ford'
|
142
|
+
assert_raises(Characterizable::Characteristic::TreatedUnboundAsBound) do
|
143
|
+
Automobile.characteristics[:make].value
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
should "not allow treating bound characteristics like unbound ones" do
|
148
|
+
a = Automobile.new
|
149
|
+
a.make = 'Ford'
|
150
|
+
b = Automobile.new
|
151
|
+
b.make = 'Pontiac'
|
152
|
+
assert_raises(Characterizable::Characteristic::TreatedBoundAsUnbound) do
|
153
|
+
a.characteristics[:make].value :anything
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
should "eagely populate bound characteristics" do
|
158
|
+
a = Automobile.new
|
159
|
+
a.make = 'Ford'
|
160
|
+
assert_equal ['Ford'], a.known_characteristics.map(&:value)
|
161
|
+
assert_equal [:make], a.known_characteristics.map(&:name)
|
162
|
+
end
|
123
163
|
end
|