manacle 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|