manacle 0.1.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.
- checksums.yaml +7 -0
- data/lib/manacle/constraint.rb +70 -0
- data/lib/manacle/constraint/actuator.rb +15 -0
- data/lib/manacle/constraint/actuator/base.rb +46 -0
- data/lib/manacle/constraint/actuator/nested.rb +45 -0
- data/lib/manacle/constraint/method.rb +17 -0
- data/lib/manacle/proxy.rb +31 -0
- data/lib/manacle/proxy/factory.rb +20 -0
- data/lib/manacle/proxy/method.rb +9 -0
- data/lib/manacle/proxy/method/constrained.rb +35 -0
- data/lib/manacle/proxy/method/unconstrained.rb +18 -0
- data/lib/manacle/proxy/template.rb +36 -0
- data/lib/manacle/proxy/template/factory.rb +18 -0
- data/lib/manacle/proxy/templates.rb +40 -0
- data/test/integration/manacle/constraint/actuator_test.rb +0 -0
- data/test/integration/manacle/constraint_test.rb +155 -0
- data/test/integration/manacle/proxy_test.rb +7 -0
- data/test/integration/manacle_test.rb +151 -0
- data/test/integration/test_helper.rb +7 -0
- data/test/unit/manacle/constraint/actuator/base_test.rb +58 -0
- data/test/unit/manacle/constraint/actuator/nested_test.rb +62 -0
- data/test/unit/manacle/constraint_test.rb +65 -0
- data/test/unit/manacle/proxy/factory_test.rb +0 -0
- data/test/unit/manacle/proxy/template_test.rb +48 -0
- data/test/unit/manacle/proxy_test.rb +42 -0
- data/test/unit/test_helper.rb +16 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4c15b4fe1557d5ec2312bb4223ac342bd6b7432d
|
4
|
+
data.tar.gz: e1fadac4c7532ef3533daafa688ae4171c98886b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a954e2e91239354668392b1a8cc2026a31a908f19658157cb93785890633e8ce59ef0f028e4efdd20211d0eb3a683300abe918c0f64e2c16e761ab77c4628ebb
|
7
|
+
data.tar.gz: ad2fce07cb9bbf6b2488d6b4265c2c424dadf3e111da3ff65ea527eecb005d268d772844912f6caeeb13e950627bc20e30f3a7dc41b7c5f9e8af6240653939f7
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'manacle/constraint/actuator/base'
|
2
|
+
require 'manacle/constraint/actuator/nested'
|
3
|
+
|
4
|
+
module Manacle
|
5
|
+
# Include this, and magically each of your decorators will get a time
|
6
|
+
# attached, as well as delegation to all the modules contained therein.
|
7
|
+
#
|
8
|
+
# You can then override the parts of Time you want to change.
|
9
|
+
module Constraint
|
10
|
+
module InstanceMethods
|
11
|
+
|
12
|
+
def initialize(obj)
|
13
|
+
if obj.nil?
|
14
|
+
raise
|
15
|
+
end
|
16
|
+
|
17
|
+
if obj.class < Manacle::Proxy
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
|
21
|
+
@actuator = if obj.class < Actuator
|
22
|
+
obj
|
23
|
+
else
|
24
|
+
Actuator.build(obj, self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :actuator
|
29
|
+
|
30
|
+
def constrainables
|
31
|
+
self.class.constrainables
|
32
|
+
end
|
33
|
+
|
34
|
+
def reconstrain(obj)
|
35
|
+
r = @actuator.reconstrain(obj)
|
36
|
+
self.class.new(r)
|
37
|
+
end
|
38
|
+
|
39
|
+
def unconstrain
|
40
|
+
@actuator.unconstrain
|
41
|
+
end
|
42
|
+
|
43
|
+
def constrain
|
44
|
+
@actuator.constrain
|
45
|
+
end
|
46
|
+
|
47
|
+
def proxy
|
48
|
+
proxy_class = @actuator.proxy
|
49
|
+
unless proxy_class.kind_of?(Class)
|
50
|
+
raise "#{@actuator.inspect} is proxying non-classes: #{self.levels}"
|
51
|
+
end
|
52
|
+
proxy_class.new(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
def klass
|
56
|
+
@actuator.constrain.class
|
57
|
+
end
|
58
|
+
|
59
|
+
def levels
|
60
|
+
["CONSTRAINT #{constraint}"] + @actuator.levels
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.included(base)
|
65
|
+
base.instance_eval do
|
66
|
+
include InstanceMethods
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Manacle
|
2
|
+
module Constraint
|
3
|
+
module Actuator
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def build(subject, constraint)
|
7
|
+
if subject.class < Constraint
|
8
|
+
Actuator::Nested.new(subject.actuator, constraint)
|
9
|
+
else
|
10
|
+
Actuator::Base.new(subject, constraint)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'manacle/constraint/actuator'
|
2
|
+
|
3
|
+
require 'manacle/proxy/templates'
|
4
|
+
|
5
|
+
module Manacle
|
6
|
+
# Include this, and magically each of your decorators will get a time
|
7
|
+
# attached, as well as delegation to all the modules contained therein.
|
8
|
+
#
|
9
|
+
# You can then override the parts of Time you want to change.
|
10
|
+
module Constraint
|
11
|
+
module Actuator
|
12
|
+
class Base
|
13
|
+
|
14
|
+
include Manacle::Constraint::Actuator
|
15
|
+
|
16
|
+
def initialize(val, constraint)
|
17
|
+
if val.kind_of?(self.class)
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
@val = val
|
21
|
+
@constraint = constraint
|
22
|
+
end
|
23
|
+
|
24
|
+
def unconstrain
|
25
|
+
@val
|
26
|
+
end
|
27
|
+
|
28
|
+
def levels
|
29
|
+
[self.class, @val.class]
|
30
|
+
end
|
31
|
+
|
32
|
+
def proxy
|
33
|
+
Manacle::Proxy::Templates.for(@val)
|
34
|
+
end
|
35
|
+
|
36
|
+
def reconstrain(obj)
|
37
|
+
self.class.new(obj, @constraint)
|
38
|
+
end
|
39
|
+
|
40
|
+
def constrain
|
41
|
+
@constrained ||= @constraint.base_constrain(@val)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'manacle/constraint/actuator'
|
2
|
+
|
3
|
+
module Manacle
|
4
|
+
module Constraint
|
5
|
+
module Actuator
|
6
|
+
class Nested
|
7
|
+
|
8
|
+
include Manacle::Constraint::Actuator
|
9
|
+
|
10
|
+
def initialize(nested, constraint)
|
11
|
+
@nested = nested
|
12
|
+
@constraint = constraint
|
13
|
+
end
|
14
|
+
|
15
|
+
def unconstrain
|
16
|
+
@nested.unconstrain
|
17
|
+
end
|
18
|
+
|
19
|
+
def reconstrain(obj)
|
20
|
+
res = @nested.reconstrain(obj)
|
21
|
+
self.class.new(res, @constraint)
|
22
|
+
end
|
23
|
+
|
24
|
+
def proxy
|
25
|
+
@nested.proxy
|
26
|
+
end
|
27
|
+
|
28
|
+
def levels
|
29
|
+
[self.class] + @nested.levels
|
30
|
+
end
|
31
|
+
|
32
|
+
def constrain
|
33
|
+
@constrained ||= build_constraint
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def build_constraint
|
39
|
+
res = @nested.constrain
|
40
|
+
@constraint.base_constrain(res)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'manacle/constraint'
|
2
|
+
|
3
|
+
module Manacle
|
4
|
+
module Constraint
|
5
|
+
module Method
|
6
|
+
def self.included(base)
|
7
|
+
base.instance_eval do
|
8
|
+
include Manacle::Constraint
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def base_constrain(val)
|
13
|
+
val.method(constraint).call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Manacle
|
2
|
+
class Proxy
|
3
|
+
module InstanceMethods
|
4
|
+
def inspect
|
5
|
+
"#<Manacle::Proxy::#{self.class} #<Manacle::Constraint::#{@constraint.class} #{@constraint.inspect}>"
|
6
|
+
end
|
7
|
+
|
8
|
+
def unproxy
|
9
|
+
@constraint
|
10
|
+
end
|
11
|
+
|
12
|
+
def constrain
|
13
|
+
@constrained ||= @constraint.constrain
|
14
|
+
end
|
15
|
+
|
16
|
+
def unconstrain
|
17
|
+
@constraint.unconstrain
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(constraint)
|
21
|
+
if constraint.nil?
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
unless constraint.kind_of?(Manacle::Constraint)
|
25
|
+
raise
|
26
|
+
end
|
27
|
+
@constraint = constraint
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'manacle/proxy/template'
|
2
|
+
module Manacle
|
3
|
+
class Proxy
|
4
|
+
class Factory
|
5
|
+
def initialize(constraint)
|
6
|
+
@constraint = constraint
|
7
|
+
@templates = Manacle::Proxy::Template::Collection.new(@constraint.constrainables)
|
8
|
+
end
|
9
|
+
|
10
|
+
def proxyable?(obj)
|
11
|
+
@templates.has_key?(obj.class)
|
12
|
+
end
|
13
|
+
|
14
|
+
def proxy(obj)
|
15
|
+
c = @constraint.new(obj)
|
16
|
+
@templates.fetch(obj.class).for(c)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'manacle/proxy/method'
|
2
|
+
|
3
|
+
module Manacle
|
4
|
+
class Proxy
|
5
|
+
module Method
|
6
|
+
class Constrained
|
7
|
+
class Postprocessor
|
8
|
+
def initialize(proxy)
|
9
|
+
@constraint = proxy.unproxy
|
10
|
+
end
|
11
|
+
|
12
|
+
def process(result)
|
13
|
+
if @constraint.constrainables.include?(result.class)
|
14
|
+
@constraint.reconstrain(result).proxy
|
15
|
+
else
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
include Manacle::Proxy::Method
|
22
|
+
|
23
|
+
def bind(proxy)
|
24
|
+
proxy.instance_exec(@name) do |name|
|
25
|
+
define_method(name) do |*args|
|
26
|
+
postprocessor = Postprocessor.new(self)
|
27
|
+
res = constrain.method(name).call(*args)
|
28
|
+
postprocessor.process(res)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'manacle/proxy/method'
|
2
|
+
|
3
|
+
module Manacle
|
4
|
+
class Proxy
|
5
|
+
module Method
|
6
|
+
class Unconstrained
|
7
|
+
include Manacle::Proxy::Method
|
8
|
+
def bind(proxy)
|
9
|
+
proxy.instance_exec(@name) do |name|
|
10
|
+
define_method(name) do |*args|
|
11
|
+
@constraint.method(name).call(*args)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
require 'manacle/proxy'
|
4
|
+
require 'manacle/proxy/method/constrained'
|
5
|
+
require 'manacle/proxy/method/unconstrained'
|
6
|
+
|
7
|
+
module Manacle
|
8
|
+
class Proxy
|
9
|
+
class Template
|
10
|
+
def self.cut(klass)
|
11
|
+
Class.new do |k|
|
12
|
+
include Manacle::Proxy::InstanceMethods
|
13
|
+
|
14
|
+
define_method(:proxied_klass) do
|
15
|
+
klass
|
16
|
+
end
|
17
|
+
private :proxied_klass
|
18
|
+
|
19
|
+
methods = klass.instance_methods.reject {|m|
|
20
|
+
[:inspect, :new, :class].include?(m)
|
21
|
+
}.map {|m|
|
22
|
+
Method::Constrained.new(m)
|
23
|
+
} +
|
24
|
+
Manacle::Constraint::InstanceMethods.instance_methods.map {|m|
|
25
|
+
Method::Unconstrained.new(m)
|
26
|
+
}
|
27
|
+
|
28
|
+
|
29
|
+
methods.each do |mth|
|
30
|
+
mth.bind(self)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'punchout/fabricable'
|
2
|
+
require 'punchout/puncher'
|
3
|
+
require 'punchout/puncher/matchable'
|
4
|
+
require 'punchout/matcher/class'
|
5
|
+
require 'manacle/proxy/template/factory'
|
6
|
+
|
7
|
+
module Manacle
|
8
|
+
class Proxy
|
9
|
+
module Templates
|
10
|
+
class Factory
|
11
|
+
def initialize
|
12
|
+
@factory = Manacle::Proxy::Template::Factory.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def build(obj)
|
16
|
+
matcher = Punchout::Matcher::Klass.new(obj.class)
|
17
|
+
built = @factory.build(obj)
|
18
|
+
|
19
|
+
Punchout::Puncher::Matchable.new(matcher, built)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
extend Punchout::Fabricable
|
24
|
+
|
25
|
+
module_function
|
26
|
+
|
27
|
+
def factory
|
28
|
+
@factory ||= Factory.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def for(obj)
|
32
|
+
res = puncher.punch(obj.class)
|
33
|
+
unless res.kind_of?(Class)
|
34
|
+
raise
|
35
|
+
end
|
36
|
+
res
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
require 'date'
|
5
|
+
require 'manacle/constraint/method'
|
6
|
+
|
7
|
+
class Manacle::Constraint::Test < Test::Unit::TestCase
|
8
|
+
test '#constrain' do
|
9
|
+
mock_constrainable = Class.new do
|
10
|
+
|
11
|
+
def self.constrainables
|
12
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
13
|
+
end
|
14
|
+
|
15
|
+
include Manacle::Constraint::Method
|
16
|
+
|
17
|
+
def constraint
|
18
|
+
:utc
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
time = Time.new
|
23
|
+
|
24
|
+
orig = mock_constrainable.new(time)
|
25
|
+
|
26
|
+
mod = orig.reconstrain(Time.now.utc)
|
27
|
+
end
|
28
|
+
|
29
|
+
test '#constrain comparisons' do
|
30
|
+
mock_constrainable = Class.new do
|
31
|
+
|
32
|
+
def self.constrainables
|
33
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
34
|
+
end
|
35
|
+
|
36
|
+
include Manacle::Constraint::Method
|
37
|
+
|
38
|
+
def constraint
|
39
|
+
:utc
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
time = Time.new
|
44
|
+
|
45
|
+
orig_cons = mock_constrainable.new(time)
|
46
|
+
|
47
|
+
orig = orig_cons.proxy
|
48
|
+
|
49
|
+
steps = [60*60*24, 60*60*5, 60*30]
|
50
|
+
|
51
|
+
mod = steps.reduce(orig) {|d, s|
|
52
|
+
d + s
|
53
|
+
}
|
54
|
+
assert_equal 1, mod <=> orig
|
55
|
+
assert_equal -1, orig <=> mod
|
56
|
+
assert_equal 0, orig <=> orig
|
57
|
+
|
58
|
+
assert mod.kind_of?(::Time), "Result of kind #{mod.class.ancestors} instead of Time"
|
59
|
+
assert_equal mod.constrain, (time + 60*60*24 + 60*60*5 + 60*30).utc
|
60
|
+
end
|
61
|
+
|
62
|
+
test '#constrain nesting' do
|
63
|
+
mock_constrainable = Class.new do
|
64
|
+
def self.constrainables
|
65
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
66
|
+
end
|
67
|
+
|
68
|
+
include Manacle::Constraint::Method
|
69
|
+
|
70
|
+
def constraint
|
71
|
+
:utc
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
mock_other_constrainable = Class.new do
|
76
|
+
def self.constrainables
|
77
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
78
|
+
end
|
79
|
+
|
80
|
+
include Manacle::Constraint::Method
|
81
|
+
|
82
|
+
def constraint
|
83
|
+
:beginning_of_day
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
time = Time.now.in_time_zone('PST8PDT')
|
88
|
+
|
89
|
+
orig_cons = mock_constrainable.new(time)
|
90
|
+
oo_cons = mock_other_constrainable.new(orig_cons)
|
91
|
+
oo = oo_cons.proxy
|
92
|
+
|
93
|
+
|
94
|
+
mod = oo + (1.day + 5.hours + 30.minutes)
|
95
|
+
|
96
|
+
|
97
|
+
assert mod.kind_of?(::Time)
|
98
|
+
assert_equal mod.constrain, (time + 1.day).utc.beginning_of_day
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
test '#constrain repeated' do
|
103
|
+
mock_constrainable = Class.new do
|
104
|
+
|
105
|
+
def self.constrainables
|
106
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
107
|
+
end
|
108
|
+
|
109
|
+
include Manacle::Constraint::Method
|
110
|
+
|
111
|
+
def constraint
|
112
|
+
:utc
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
mock_other_constrainable = Class.new do
|
117
|
+
def self.constrainables
|
118
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
119
|
+
end
|
120
|
+
|
121
|
+
include Manacle::Constraint::Method
|
122
|
+
|
123
|
+
def constraint
|
124
|
+
:beginning_of_day
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
time = Time.now.in_time_zone('PST8PDT')
|
129
|
+
|
130
|
+
orig_cons = mock_constrainable.new(time)
|
131
|
+
oo_cons = mock_other_constrainable.new(orig_cons)
|
132
|
+
|
133
|
+
oo = oo_cons.proxy
|
134
|
+
|
135
|
+
|
136
|
+
5.times do
|
137
|
+
oo = oo + (1.day + 5.hours + 30.minutes)
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
5.times do
|
142
|
+
oo = oo.in_time_zone("PST8PDT")
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
assert_kind_of ::Time, oo
|
147
|
+
constrained = oo.constrain
|
148
|
+
assert_kind_of ::Time, constrained
|
149
|
+
|
150
|
+
expected_time = (time + 5.day).utc.beginning_of_day
|
151
|
+
assert_equal expected_time, constrained
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
require 'date'
|
5
|
+
require 'manacle/constraint/method'
|
6
|
+
|
7
|
+
class Manacle::ConstraintTest < Test::Unit::TestCase
|
8
|
+
test '#constrain' do
|
9
|
+
mock_constrainable = Class.new do
|
10
|
+
|
11
|
+
def self.constrainables
|
12
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
13
|
+
end
|
14
|
+
|
15
|
+
include Manacle::Constraint::Method
|
16
|
+
|
17
|
+
def constraint
|
18
|
+
:utc
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
time = Time.new
|
23
|
+
|
24
|
+
orig = mock_constrainable.new(time).proxy
|
25
|
+
|
26
|
+
mod = orig + 1.day + 5.hours + 30.minutes
|
27
|
+
|
28
|
+
assert mod.kind_of?(::Time), "Result of kind #{mod.class.ancestors} instead of Time"
|
29
|
+
assert_equal mod.constrain, (time + 1.day + 5.hours + 30.minutes).utc
|
30
|
+
end
|
31
|
+
|
32
|
+
test '#constrain comparisons' do
|
33
|
+
mock_constrainable = Class.new do
|
34
|
+
|
35
|
+
def self.constrainables
|
36
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
37
|
+
end
|
38
|
+
|
39
|
+
include Manacle::Constraint::Method
|
40
|
+
|
41
|
+
def constraint
|
42
|
+
:utc
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
time = Time.new
|
47
|
+
|
48
|
+
orig = mock_constrainable.new(time).proxy
|
49
|
+
|
50
|
+
|
51
|
+
mod = orig + 1.day + 5.hours + 30.minutes
|
52
|
+
|
53
|
+
assert_equal 1, mod <=> orig
|
54
|
+
assert_equal -1, orig <=> mod
|
55
|
+
assert_equal 0, orig <=> orig
|
56
|
+
|
57
|
+
assert mod.kind_of?(::Time), "Result of kind #{mod.class.ancestors} instead of Time"
|
58
|
+
assert_equal mod.constrain, (time + 1.day + 5.hours + 30.minutes).utc
|
59
|
+
end
|
60
|
+
|
61
|
+
test '#constrain nesting' do
|
62
|
+
mock_constrainable = Class.new do
|
63
|
+
def self.constrainables
|
64
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
65
|
+
end
|
66
|
+
|
67
|
+
include Manacle::Constraint::Method
|
68
|
+
|
69
|
+
def constraint
|
70
|
+
:utc
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
mock_other_constrainable = Class.new do
|
75
|
+
def self.constrainables
|
76
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
77
|
+
end
|
78
|
+
|
79
|
+
include Manacle::Constraint::Method
|
80
|
+
|
81
|
+
def constraint
|
82
|
+
:beginning_of_day
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
time = Time.now.in_time_zone('PST8PDT')
|
87
|
+
|
88
|
+
orig_cons = mock_constrainable.new(time)
|
89
|
+
oo_cons = mock_other_constrainable.new(orig_cons)
|
90
|
+
oo = oo_cons.proxy
|
91
|
+
|
92
|
+
mod = oo + (1.day + 5.hours + 30.minutes)
|
93
|
+
|
94
|
+
assert mod.kind_of?(::Time)
|
95
|
+
assert_equal mod.constrain, (time + 1.day).utc.beginning_of_day
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
test '#constrain repeated' do
|
100
|
+
mock_constrainable = Class.new do
|
101
|
+
|
102
|
+
def self.constrainables
|
103
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
104
|
+
end
|
105
|
+
|
106
|
+
include Manacle::Constraint::Method
|
107
|
+
|
108
|
+
def constraint
|
109
|
+
:utc
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
mock_other_constrainable = Class.new do
|
114
|
+
def self.constrainables
|
115
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
116
|
+
end
|
117
|
+
|
118
|
+
include Manacle::Constraint::Method
|
119
|
+
|
120
|
+
def constraint
|
121
|
+
:beginning_of_day
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
time = Time.now.in_time_zone('PST8PDT')
|
126
|
+
|
127
|
+
orig_cons = mock_constrainable.new(time)
|
128
|
+
oo_cons = mock_other_constrainable.new(orig_cons)
|
129
|
+
|
130
|
+
oo = oo_cons.proxy
|
131
|
+
|
132
|
+
|
133
|
+
5.times do
|
134
|
+
oo = oo + (1.day + 5.hours + 30.minutes)
|
135
|
+
end
|
136
|
+
|
137
|
+
5.times do
|
138
|
+
oo = oo.in_time_zone("PST8PDT")
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
assert_kind_of ::Time, oo
|
143
|
+
constrained = oo.constrain
|
144
|
+
assert_kind_of ::Time, constrained
|
145
|
+
|
146
|
+
expected_time = (time + 5.day).utc.beginning_of_day
|
147
|
+
assert_equal expected_time, constrained
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path('../../../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'manacle/constraint/actuator/base'
|
4
|
+
|
5
|
+
class Manacle::Constraint::Actuator::BaseTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@mock_value = mock
|
8
|
+
@mock_constraint = mock
|
9
|
+
|
10
|
+
@actuator = Manacle::Constraint::Actuator::Base.new(@mock_value, @mock_constraint)
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
puts Test::Unit::TestCase.method(:test).inspect
|
15
|
+
|
16
|
+
test '#constrain uncached' do
|
17
|
+
|
18
|
+
mock_constrained = mock
|
19
|
+
@mock_constraint.expects(:base_constrain).returns(mock_constrained)
|
20
|
+
|
21
|
+
result = @actuator.constrain
|
22
|
+
|
23
|
+
assert_equal mock_constrained, result
|
24
|
+
end
|
25
|
+
|
26
|
+
test '#constrain cached' do
|
27
|
+
|
28
|
+
mock_constrained = mock
|
29
|
+
|
30
|
+
@mock_value.expects(:constrain).never
|
31
|
+
|
32
|
+
@actuator.instance_variable_set(:@constrained, mock_constrained)
|
33
|
+
|
34
|
+
result = @actuator.constrain
|
35
|
+
|
36
|
+
assert_equal mock_constrained, result
|
37
|
+
end
|
38
|
+
|
39
|
+
test '#reconstrain' do
|
40
|
+
mock_new_value = mock
|
41
|
+
|
42
|
+
mock_actuator = mock
|
43
|
+
Manacle::Constraint::Actuator::Base.expects(:new).with(mock_new_value, @mock_constraint).returns(mock_actuator)
|
44
|
+
|
45
|
+
result = @actuator.reconstrain(mock_new_value)
|
46
|
+
|
47
|
+
assert_equal mock_actuator, result
|
48
|
+
end
|
49
|
+
|
50
|
+
test '#proxy' do
|
51
|
+
mock_proxy = mock
|
52
|
+
Manacle::Proxy::Templates.expects(:for).with(@mock_value).returns(mock_proxy)
|
53
|
+
|
54
|
+
result = @actuator.proxy
|
55
|
+
|
56
|
+
assert_equal mock_proxy, result
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.expand_path('../../../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'manacle/constraint/actuator/nested'
|
4
|
+
|
5
|
+
class Manacle::Constraint::Actuator::NestedTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@mock_nested = mock
|
8
|
+
@mock_constraint = mock
|
9
|
+
|
10
|
+
@actuator = Manacle::Constraint::Actuator::Nested.new(@mock_nested, @mock_constraint)
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
test '#constrain uncached' do
|
15
|
+
|
16
|
+
mock_ascending_value = mock
|
17
|
+
@mock_nested.expects(:constrain).returns(mock_ascending_value)
|
18
|
+
|
19
|
+
mock_constrained = mock
|
20
|
+
@mock_constraint.expects(:base_constrain).returns(mock_constrained)
|
21
|
+
|
22
|
+
result = @actuator.constrain
|
23
|
+
|
24
|
+
assert_equal mock_constrained, result
|
25
|
+
end
|
26
|
+
|
27
|
+
test '#constrain cached' do
|
28
|
+
mock_constrained = mock
|
29
|
+
|
30
|
+
@mock_nested.expects(:constrain).never
|
31
|
+
|
32
|
+
@actuator.instance_variable_set(:@constrained, mock_constrained)
|
33
|
+
|
34
|
+
result = @actuator.constrain
|
35
|
+
|
36
|
+
assert_equal mock_constrained, result
|
37
|
+
end
|
38
|
+
|
39
|
+
test '#reconstrain' do
|
40
|
+
mock_object = mock
|
41
|
+
|
42
|
+
mock_new_nested = mock
|
43
|
+
@mock_nested.expects(:reconstrain).with(mock_object).returns(mock_new_nested)
|
44
|
+
|
45
|
+
mock_new_actuator = mock
|
46
|
+
Manacle::Constraint::Actuator::Nested.expects(:new).with(mock_new_nested, @mock_constraint).returns(mock_new_actuator)
|
47
|
+
|
48
|
+
result = @actuator.reconstrain(mock_object)
|
49
|
+
|
50
|
+
assert_equal mock_new_actuator, result
|
51
|
+
end
|
52
|
+
|
53
|
+
test '#proxy' do
|
54
|
+
mock_proxy = mock
|
55
|
+
@mock_nested.expects(:proxy).returns(mock_proxy)
|
56
|
+
|
57
|
+
result = @actuator.proxy
|
58
|
+
assert_equal mock_proxy, result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'manacle/constraint'
|
4
|
+
|
5
|
+
class Manacle::ConstraintTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@mock_constrainable = Class.new do
|
8
|
+
|
9
|
+
def self.constrainables
|
10
|
+
[ActiveSupport::TimeWithZone, ::Time, ::Date]
|
11
|
+
end
|
12
|
+
|
13
|
+
include Manacle::Constraint
|
14
|
+
|
15
|
+
def constraint=(constraint)
|
16
|
+
@constraint = constraint
|
17
|
+
end
|
18
|
+
|
19
|
+
def constraint
|
20
|
+
@constraint
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@mock_obj = mock
|
25
|
+
|
26
|
+
@mock_actuator = mock
|
27
|
+
|
28
|
+
Manacle::Constraint::Actuator.expects(:build).with(@mock_obj, instance_of(@mock_constrainable)).returns(@mock_actuator)
|
29
|
+
|
30
|
+
@constraint = @mock_constrainable.new(@mock_obj)
|
31
|
+
|
32
|
+
@mock_constraint = mock
|
33
|
+
|
34
|
+
@constraint.constraint = @mock_constraint
|
35
|
+
end
|
36
|
+
|
37
|
+
test "#klass" do
|
38
|
+
mock_val = mock
|
39
|
+
@mock_actuator.expects(:constrain).returns(mock_val)
|
40
|
+
|
41
|
+
mock_val_class = mock
|
42
|
+
mock_val.expects(:class).returns(mock_val_class)
|
43
|
+
|
44
|
+
result = @constraint.klass
|
45
|
+
assert_equal mock_val_class, result
|
46
|
+
end
|
47
|
+
|
48
|
+
test "#unconstrain" do
|
49
|
+
@mock_actuator.expects(:unconstrain).returns(@mock_obj)
|
50
|
+
|
51
|
+
result = @constraint.unconstrain
|
52
|
+
|
53
|
+
assert_equal @mock_obj, result
|
54
|
+
end
|
55
|
+
|
56
|
+
test "#reconstrain" do
|
57
|
+
mock_new_obj = mock
|
58
|
+
@mock_actuator.expects(:reconstrain).returns(mock_new_obj)
|
59
|
+
|
60
|
+
mock_new_actuator = mock
|
61
|
+
Manacle::Constraint::Actuator.expects(:build).with(mock_new_obj, instance_of(@mock_constrainable)).returns(mock_new_actuator)
|
62
|
+
|
63
|
+
result = @constraint.reconstrain(mock_new_obj)
|
64
|
+
end
|
65
|
+
end
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'manacle/proxy/template'
|
4
|
+
|
5
|
+
class Manacle::Proxy::TemplateTest < Test::Unit::TestCase
|
6
|
+
class MockClass ; end
|
7
|
+
|
8
|
+
|
9
|
+
test ".ancestors" do
|
10
|
+
mock_klass = MockClass
|
11
|
+
|
12
|
+
mock_instance_methods = 5.times.map {|x|
|
13
|
+
"method_#{x}".to_sym
|
14
|
+
}
|
15
|
+
|
16
|
+
mock_klass.expects(:instance_methods).returns(mock_instance_methods)
|
17
|
+
|
18
|
+
mock_proxy_klass = Manacle::Proxy::Template.cut(mock_klass)
|
19
|
+
|
20
|
+
mock_proxy_klass.ancestors.include?(MockClass)
|
21
|
+
end
|
22
|
+
|
23
|
+
test ".cut" do
|
24
|
+
mock_klass = MockClass
|
25
|
+
|
26
|
+
mock_instance_methods = 5.times.map {|x|
|
27
|
+
"method_#{x}".to_sym
|
28
|
+
}
|
29
|
+
|
30
|
+
mock_instance_methods.each {|m|
|
31
|
+
mock_method_obj = mock
|
32
|
+
#mock_klass.expects(:instance_method).returns(mock_method_obj)
|
33
|
+
}
|
34
|
+
|
35
|
+
mock_klass.expects(:instance_methods).returns(mock_instance_methods)
|
36
|
+
|
37
|
+
mock_proxy_klass = Manacle::Proxy::Template.cut(mock_klass)
|
38
|
+
|
39
|
+
mock_constraint = mock
|
40
|
+
mock_constraint.expects(:kind_of?).with(Manacle::Constraint).returns(true)
|
41
|
+
|
42
|
+
mock_proxy_instance = mock_proxy_klass.new(mock_constraint)
|
43
|
+
|
44
|
+
mock_instance_methods.each {|m|
|
45
|
+
assert mock_proxy_instance.respond_to?(m), "mock class does not respond to #{m}"
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'manacle/proxy'
|
4
|
+
|
5
|
+
class Manacle::ProxyTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@mock_constraint = mock
|
9
|
+
|
10
|
+
@mock_constraint.expects(:kind_of?).with(Manacle::Constraint).returns(true)
|
11
|
+
|
12
|
+
proxy_class = Class.new do
|
13
|
+
include Manacle::Proxy::InstanceMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
@proxy = proxy_class.new(@mock_constraint)
|
17
|
+
end
|
18
|
+
|
19
|
+
test "#constrained uncached" do
|
20
|
+
mock_constrained = mock
|
21
|
+
|
22
|
+
@mock_constraint.expects(:constrain).returns(mock_constrained)
|
23
|
+
|
24
|
+
result = @proxy.constrain
|
25
|
+
|
26
|
+
assert_equal mock_constrained, result
|
27
|
+
end
|
28
|
+
|
29
|
+
test "#constrained cached" do
|
30
|
+
mock_constrained = mock
|
31
|
+
|
32
|
+
@proxy.instance_variable_set(:@constrained, mock_constrained)
|
33
|
+
|
34
|
+
@mock_constraint.expects(:constrain).never
|
35
|
+
|
36
|
+
result = @proxy.constrain
|
37
|
+
|
38
|
+
assert_equal mock_constrained, result
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.push('lib')
|
2
|
+
|
3
|
+
require 'coveralls'
|
4
|
+
Coveralls.wear!
|
5
|
+
|
6
|
+
if ENV["ENABLE_SIMPLE_COV"]
|
7
|
+
require 'simplecov'
|
8
|
+
SimpleCov.start do
|
9
|
+
add_filter "test"
|
10
|
+
add_group 'API', "lib"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'test/unit/testcase'
|
15
|
+
require "mocha/setup"
|
16
|
+
|
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: manacle
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ed Carrel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: punchout
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mocha
|
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'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: |2
|
84
|
+
Manacle will allow you to attach constraints to your objects that will persist across new instances of similar objects.
|
85
|
+
|
86
|
+
As an example, you can constrain a Time object to always advance to the next hour. Then, if you add even one minute to that Time, it will snap to the next hour.
|
87
|
+
email:
|
88
|
+
- ed@pocketchange.com
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- lib/manacle/constraint/actuator/base.rb
|
94
|
+
- lib/manacle/constraint/actuator/nested.rb
|
95
|
+
- lib/manacle/constraint/actuator.rb
|
96
|
+
- lib/manacle/constraint/method.rb
|
97
|
+
- lib/manacle/constraint.rb
|
98
|
+
- lib/manacle/proxy/factory.rb
|
99
|
+
- lib/manacle/proxy/method/constrained.rb
|
100
|
+
- lib/manacle/proxy/method/unconstrained.rb
|
101
|
+
- lib/manacle/proxy/method.rb
|
102
|
+
- lib/manacle/proxy/template/factory.rb
|
103
|
+
- lib/manacle/proxy/template.rb
|
104
|
+
- lib/manacle/proxy/templates.rb
|
105
|
+
- lib/manacle/proxy.rb
|
106
|
+
- test/integration/manacle/constraint/actuator_test.rb
|
107
|
+
- test/integration/manacle/constraint_test.rb
|
108
|
+
- test/integration/manacle/proxy_test.rb
|
109
|
+
- test/integration/manacle_test.rb
|
110
|
+
- test/integration/test_helper.rb
|
111
|
+
- test/unit/manacle/constraint/actuator/base_test.rb
|
112
|
+
- test/unit/manacle/constraint/actuator/nested_test.rb
|
113
|
+
- test/unit/manacle/constraint_test.rb
|
114
|
+
- test/unit/manacle/proxy/factory_test.rb
|
115
|
+
- test/unit/manacle/proxy/template_test.rb
|
116
|
+
- test/unit/manacle/proxy_test.rb
|
117
|
+
- test/unit/test_helper.rb
|
118
|
+
homepage:
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.1.10
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: A sticky constraint gem
|
142
|
+
test_files: []
|
143
|
+
has_rdoc:
|