characterizable 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -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
- characterizable_base.characteristics.select do |c|
22
- c.known?(self) and not c.trumped?(self)
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
- characterizable_base.characteristics.select do |c|
28
- c.unknown?(self) and c.requited?(self) and not c.trumped?(self)
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
- def unknown?(obj)
92
- obj.send(name).nil?
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
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 0
9
- version: 0.0.0
8
+ - 1
9
+ version: 0.0.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Andy Rossmeissl