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 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