ccp 0.1.5 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -2
- data/README.rdoc +78 -4
- data/ccp.gemspec +2 -1
- data/lib/ccp.rb +1 -0
- data/lib/ccp/commands/composite.rb +5 -1
- data/lib/ccp/commands/core.rb +7 -1
- data/lib/ccp/commands/executable.rb +15 -6
- data/lib/ccp/commands/receivable.rb +2 -1
- data/lib/ccp/data.rb +18 -2
- data/lib/ccp/fixtures.rb +6 -0
- data/lib/ccp/fixtures/observer.rb +23 -0
- data/lib/ccp/fixtures/writers.rb +35 -0
- data/lib/ccp/invokers/base.rb +13 -45
- data/lib/ccp/receivers.rb +3 -0
- data/lib/ccp/receivers/aroundable.rb +11 -0
- data/lib/ccp/receivers/base.rb +6 -1
- data/lib/ccp/receivers/executable.rb +9 -0
- data/lib/ccp/receivers/profileable.rb +4 -6
- data/lib/ccp/receivers/save_fixture.rb +45 -0
- data/lib/ccp/version.rb +1 -1
- data/spec/commands_composite_spec.rb +4 -8
- data/spec/commands_core_spec.rb +5 -19
- data/spec/commands_executable_spec.rb +19 -0
- data/spec/invokers_spec.rb +8 -29
- data/spec/save_fixture_spec.rb +47 -0
- data/spec/spec_helper.rb +7 -0
- metadata +35 -11
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -95,17 +95,91 @@ Just call a "execute" instance method.
|
|
95
95
|
|
96
96
|
=== invokers
|
97
97
|
|
98
|
-
Invokers::Base
|
98
|
+
Invokers::Base is a top level composite command.
|
99
|
+
It acts same as composite except some special options.
|
100
|
+
Those are profile, comment, logger.
|
99
101
|
|
100
102
|
class SomeOperation < Ccp::Invokers::Base
|
101
|
-
command FetchData
|
103
|
+
command FetchData # same as composite
|
104
|
+
command Calculate # same as composite
|
102
105
|
...
|
103
106
|
|
107
|
+
profile true # default false
|
108
|
+
comment false # default true
|
109
|
+
...
|
104
110
|
|
105
|
-
|
111
|
+
This profile option prints benchmarks of commands.
|
106
112
|
|
107
|
-
ruby -r some_operation -e 'SomeOperation.
|
113
|
+
ruby -r some_operation -e 'SomeOperation.execute'
|
108
114
|
[43.3%] 2.5834830 FetchData#execute
|
109
115
|
[35.9%] 2.0710440 Calculate#execute
|
110
116
|
...
|
111
117
|
|
118
|
+
|
119
|
+
== Fixtures
|
120
|
+
|
121
|
+
Let's imagine a following command that just read :a and write :x.
|
122
|
+
|
123
|
+
class TSFC # TestSaveFixtureCmd
|
124
|
+
include Ccp::Commands::Core
|
125
|
+
|
126
|
+
def execute
|
127
|
+
data[:a] # read
|
128
|
+
data[:x] = 10 # write
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
This may be a part of sequncial commands.
|
133
|
+
When we want to test only this command, usually we should prepare
|
134
|
+
some fixture data for the 'data' object.
|
135
|
+
|
136
|
+
=== Generating fixtures
|
137
|
+
|
138
|
+
Ccp can automatically generate fixture data for each commands.
|
139
|
+
Pass :save_fixture option to 'execute' class method to enable it.
|
140
|
+
|
141
|
+
* save_fixture : enable write fixture mode if true
|
142
|
+
* save_fixture_dir : set root dir of fixture (default: tmp/fixtures)
|
143
|
+
|
144
|
+
In above example, we can kick it with data[:a] like this.
|
145
|
+
|
146
|
+
TSFC.execute(:a => 1)
|
147
|
+
|
148
|
+
And if you want to geneate fixures for this command, just add :save_fixture.
|
149
|
+
|
150
|
+
TSFC.execute(:a => 1, :save_fixture => true)
|
151
|
+
|
152
|
+
This will create following files.
|
153
|
+
|
154
|
+
% tree tmp/fixtures
|
155
|
+
tmp/fixtures
|
156
|
+
└── tsfc
|
157
|
+
├── in.yaml
|
158
|
+
└── out.yaml
|
159
|
+
|
160
|
+
1 directory, 2 files
|
161
|
+
% cat tmp/fixtures/tsfc/*
|
162
|
+
---
|
163
|
+
:a: 1
|
164
|
+
---
|
165
|
+
:x: 10
|
166
|
+
|
167
|
+
=== Writing tests
|
168
|
+
|
169
|
+
Use them as stubs and expected data as you like.
|
170
|
+
|
171
|
+
describe TSFC do
|
172
|
+
it "should work" do
|
173
|
+
data = YAML.load(Pathname("tmp/fixtures/tsfc/in.yaml").read{})
|
174
|
+
expected = YAML.load(Pathname("tmp/fixtures/tsfc/out.yaml").read{})
|
175
|
+
|
176
|
+
cmd = TSFC.execute(data)
|
177
|
+
|
178
|
+
expected.each_pair do |key, val|
|
179
|
+
cmd.data[key].should == val
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
This code is highly versatile.
|
185
|
+
|
data/ccp.gemspec
CHANGED
@@ -18,7 +18,8 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency "typed", ">= 0.1.
|
21
|
+
s.add_dependency "typed", ">= 0.1.5"
|
22
|
+
s.add_dependency "must", ">= 0.2.7"
|
22
23
|
s.add_dependency "dsl_accessor", ">= 0.4.0"
|
23
24
|
|
24
25
|
s.add_development_dependency "rspec"
|
data/lib/ccp.rb
CHANGED
@@ -2,8 +2,10 @@ module Ccp
|
|
2
2
|
module Commands
|
3
3
|
module Composite
|
4
4
|
def self.included(base)
|
5
|
+
super
|
5
6
|
base.class_eval do
|
6
7
|
extend ClassMethods
|
8
|
+
extend Executable::ClassMethods
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
@@ -64,7 +66,9 @@ module Ccp
|
|
64
66
|
### Commands
|
65
67
|
|
66
68
|
def execute
|
67
|
-
commands.each
|
69
|
+
commands.each do |c|
|
70
|
+
c.receiver.execute(c)
|
71
|
+
end
|
68
72
|
end
|
69
73
|
|
70
74
|
def receiver=(value)
|
data/lib/ccp/commands/core.rb
CHANGED
@@ -2,8 +2,14 @@ module Ccp
|
|
2
2
|
module Commands
|
3
3
|
module Core
|
4
4
|
include Receivable
|
5
|
-
include Executable
|
6
5
|
include Commentable
|
6
|
+
include Executable
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
extend ClassMethods
|
11
|
+
end
|
12
|
+
end
|
7
13
|
|
8
14
|
def inspect
|
9
15
|
klass_name = self.class.name.to_s.split(/::/).last
|
@@ -1,16 +1,25 @@
|
|
1
1
|
module Ccp
|
2
2
|
module Commands
|
3
3
|
module Executable
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
extend ClassMethods
|
7
|
+
end
|
8
|
+
end
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
10
|
+
module ClassMethods
|
11
|
+
def execute(options = {})
|
12
|
+
c = new
|
13
|
+
c.receiver = options.delete(:receiver)
|
14
|
+
c.receiver.parse!(options)
|
15
|
+
c.receiver.execute(c)
|
16
|
+
return c
|
17
|
+
end
|
8
18
|
end
|
9
19
|
|
10
|
-
###
|
20
|
+
### Command
|
11
21
|
|
12
|
-
def
|
13
|
-
receiver.profile(self, :execute)
|
22
|
+
def execute
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|
@@ -5,10 +5,11 @@ module Ccp
|
|
5
5
|
### Receiver Methods
|
6
6
|
|
7
7
|
def receiver
|
8
|
-
@receiver ||= Ccp::Receivers::Base.new
|
8
|
+
(@receiver ||= Ccp::Receivers::Base.new).must(Receivers::Base)
|
9
9
|
end
|
10
10
|
|
11
11
|
def receiver=(value)
|
12
|
+
return unless value
|
12
13
|
@receiver = value.must(Ccp::Receivers::Base)
|
13
14
|
end
|
14
15
|
|
data/lib/ccp/data.rb
CHANGED
@@ -4,18 +4,34 @@ require 'pathname'
|
|
4
4
|
|
5
5
|
module Ccp
|
6
6
|
module Data
|
7
|
-
module
|
7
|
+
module Ext
|
8
8
|
def path(key)
|
9
9
|
self[key].must.coerced(Pathname, String=>proc{|i| Pathname(i)})
|
10
10
|
end
|
11
|
+
|
12
|
+
def merge(options)
|
13
|
+
options.each_pair do |key,val|
|
14
|
+
self[key] = val
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def merge_default(options)
|
19
|
+
options.each_pair do |key,val|
|
20
|
+
default[key] = val
|
21
|
+
end
|
22
|
+
end
|
11
23
|
end
|
12
24
|
|
13
25
|
def data
|
14
|
-
@data ||= Typed::Hash.new.extend
|
26
|
+
@data ||= Typed::Hash.new.extend Ext
|
15
27
|
end
|
16
28
|
|
17
29
|
def data?(key)
|
18
30
|
data.set?(key)
|
19
31
|
end
|
32
|
+
|
33
|
+
def parse!(options)
|
34
|
+
data.merge(options)
|
35
|
+
end
|
20
36
|
end
|
21
37
|
end
|
data/lib/ccp/fixtures.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Ccp
|
2
|
+
module Fixtures
|
3
|
+
class Observer
|
4
|
+
attr_reader :read, :write
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@data = data.must(Typed::Hash)
|
8
|
+
@read = {}
|
9
|
+
@write = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
@data.events.on(:read ) {|k,v| @read[k] ||= v}
|
14
|
+
@data.events.on(:write) {|k,v| @write[k] = v}
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop
|
18
|
+
# remove events (this depends on typed.gem)
|
19
|
+
# NotImplementedYet
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Ccp
|
2
|
+
module Fixtures
|
3
|
+
module Writers
|
4
|
+
class Base
|
5
|
+
def self.[]= (path, hash)
|
6
|
+
new(hash,path).execute
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(hash, path)
|
10
|
+
@hash = hash.must(Hash)
|
11
|
+
@path = path.must(Pathname)
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialize(data)
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def write(data)
|
19
|
+
@path.parent.mkpath
|
20
|
+
@path.open("w+"){|f| f.print data}
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute
|
24
|
+
write(serialize(@hash))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class YamlWriter < Base
|
29
|
+
def serialize(data)
|
30
|
+
YAML.dump(data)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/ccp/invokers/base.rb
CHANGED
@@ -6,68 +6,36 @@ module Ccp
|
|
6
6
|
include Commands::Composite
|
7
7
|
|
8
8
|
dsl_accessor :receiver, Receivers::Base
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
DEFAULT_OPTIONS = {
|
13
|
-
:profile => false,
|
14
|
-
:comment => true,
|
15
|
-
:logger => Logger.new($stderr),
|
16
|
-
}
|
9
|
+
dsl_accessor :profile , false
|
10
|
+
dsl_accessor :comment , true
|
11
|
+
dsl_accessor :logger , proc{ Logger.new($stderr) }
|
17
12
|
|
18
13
|
######################################################################
|
19
14
|
### Class Methods
|
20
15
|
|
21
16
|
def self.execute(options = {}, &block)
|
22
17
|
cmd = new(options)
|
23
|
-
if block_given?
|
24
|
-
|
25
|
-
end
|
26
|
-
cmd.benchmark
|
18
|
+
cmd.instance_eval(&block) if block_given?
|
19
|
+
cmd.receiver.execute(cmd)
|
27
20
|
return cmd
|
28
21
|
end
|
29
22
|
|
30
|
-
def self.
|
31
|
-
|
23
|
+
def self.default_options
|
24
|
+
{:profile => profile, :comment => comment, :logger => logger}
|
32
25
|
end
|
33
26
|
|
34
27
|
######################################################################
|
35
28
|
### Instance Methods
|
36
29
|
|
37
|
-
def initialize(options =
|
38
|
-
options
|
39
|
-
|
40
|
-
|
41
|
-
set_runtime_options(options)
|
42
|
-
end
|
43
|
-
|
44
|
-
def set_default_receiver(receiver)
|
45
|
-
self.receiver = receiver || self.class.receiver.new
|
46
|
-
end
|
47
|
-
|
48
|
-
def set_default_options
|
49
|
-
self.class::DEFAULT_OPTIONS.each_pair do |key,val|
|
50
|
-
data.default[key] = val
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def set_runtime_options(options)
|
55
|
-
options.each_pair do |key,val|
|
56
|
-
data[key] = val
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def receiver
|
61
|
-
@receiver.must(Receivers::Base)
|
62
|
-
end
|
63
|
-
|
64
|
-
def receiver=(value)
|
65
|
-
@receiver = value.must(Receivers::Base)
|
30
|
+
def initialize(options = {})
|
31
|
+
self.receiver = options.delete(:receiver) || self.class.receiver.new
|
32
|
+
receiver.data.merge_default(self.class.default_options)
|
33
|
+
receiver.data.merge(options)
|
66
34
|
end
|
67
35
|
|
68
36
|
def after
|
69
|
-
show_profiles if data?(:profile)
|
70
|
-
show_comments if data?(:comment)
|
37
|
+
receiver.show_profiles if data?(:profile)
|
38
|
+
receiver.show_comments if data?(:comment)
|
71
39
|
end
|
72
40
|
end
|
73
41
|
end
|
data/lib/ccp/receivers.rb
CHANGED
@@ -2,7 +2,10 @@ module Ccp
|
|
2
2
|
module Receivers
|
3
3
|
autoload :Base , 'ccp/receivers/base'
|
4
4
|
autoload :Global , 'ccp/receivers/global'
|
5
|
+
autoload :Executable , 'ccp/receivers/executable'
|
6
|
+
autoload :Aroundable , 'ccp/receivers/aroundable'
|
5
7
|
autoload :Commentable , 'ccp/receivers/commentable'
|
6
8
|
autoload :Profileable , 'ccp/receivers/profileable'
|
9
|
+
autoload :SaveFixture , 'ccp/receivers/save_fixture'
|
7
10
|
end
|
8
11
|
end
|
data/lib/ccp/receivers/base.rb
CHANGED
@@ -2,9 +2,14 @@ module Ccp
|
|
2
2
|
module Receivers
|
3
3
|
class Base
|
4
4
|
include Ccp::Data
|
5
|
-
include Profileable
|
6
5
|
include Commentable
|
7
6
|
|
7
|
+
# for execute
|
8
|
+
include Executable
|
9
|
+
include Profileable
|
10
|
+
include Aroundable
|
11
|
+
include SaveFixture
|
12
|
+
|
8
13
|
def inspect
|
9
14
|
klass_name = self.class.name.to_s.split(/::/).last
|
10
15
|
|
@@ -14,17 +14,15 @@ module Ccp
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def execute(cmd)
|
18
18
|
start = Time.new
|
19
|
-
|
20
|
-
target.__send__(method)
|
21
|
-
target.__send__(:after) if target.respond_to?(:after)
|
19
|
+
super
|
22
20
|
|
23
|
-
case
|
21
|
+
case cmd
|
24
22
|
when Ccp::Commands::Composite
|
25
23
|
# no profiles
|
26
24
|
else
|
27
|
-
profiles << Profile.new(
|
25
|
+
profiles << Profile.new(cmd, "execute", (Time.new - start).to_f)
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Ccp
|
2
|
+
module Receivers
|
3
|
+
module SaveFixture
|
4
|
+
attr_accessor :save_fixture_dir
|
5
|
+
|
6
|
+
def execute(cmd)
|
7
|
+
if save_fixture?(cmd)
|
8
|
+
observer = Ccp::Fixtures::Observer.new(data)
|
9
|
+
observer.start
|
10
|
+
super
|
11
|
+
observer.stop
|
12
|
+
path = save_fixture_path_for(cmd)
|
13
|
+
Ccp::Fixtures::Writers::YamlWriter[path + "in.yaml" ] = observer.read
|
14
|
+
Ccp::Fixtures::Writers::YamlWriter[path + "out.yaml"] = observer.write
|
15
|
+
else
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse!(options)
|
21
|
+
dir = options.delete(:save_fixture_dir)
|
22
|
+
@save_fixture_dir = dir if dir
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def save_fixture?(cmd)
|
28
|
+
if data?(:save_fixture)
|
29
|
+
return true
|
30
|
+
else
|
31
|
+
# indivisual fixture is not supported yet
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def save_fixture_path_for(cmd)
|
37
|
+
Pathname(save_fixture_dir || save_fixture_default_dir) + cmd.class.name.underscore
|
38
|
+
end
|
39
|
+
|
40
|
+
def save_fixture_default_dir
|
41
|
+
"tmp/fixtures"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/ccp/version.rb
CHANGED
@@ -13,11 +13,9 @@ describe Ccp::Commands::Composite do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
describe "
|
16
|
+
describe ".execute" do
|
17
17
|
it "should call its and sub commands's {before,execute,after} in declared order" do
|
18
|
-
c = Program.
|
19
|
-
c.data[:breadcrumbs] = []
|
20
|
-
c.benchmark
|
18
|
+
c = Program.execute(:receiver=>breadcrumbs_receiver)
|
21
19
|
c.data[:breadcrumbs].should ==
|
22
20
|
["Program#before",
|
23
21
|
"Cmd1#before", "Cmd1#execute", "Cmd1#after",
|
@@ -85,11 +83,9 @@ describe "Ccp::Commands::Composite(nested)" do
|
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
88
|
-
describe "
|
86
|
+
describe ".execute" do
|
89
87
|
it "should call its and sub commands's {before,execute,after} in declared order" do
|
90
|
-
c = CompositeProgram.
|
91
|
-
c.data[:breadcrumbs] = []
|
92
|
-
c.benchmark
|
88
|
+
c = CompositeProgram.execute(:receiver=>breadcrumbs_receiver)
|
93
89
|
c.data[:breadcrumbs].should ==
|
94
90
|
["CompositeProgram#before",
|
95
91
|
"Cmd1#before", "Cmd1#execute", "Cmd1#after",
|
data/spec/commands_core_spec.rb
CHANGED
@@ -11,11 +11,15 @@ describe Ccp::Commands::Core do
|
|
11
11
|
|
12
12
|
# executable
|
13
13
|
it { should respond_to(:execute) }
|
14
|
-
it { should respond_to(:benchmark) }
|
15
14
|
|
16
15
|
# receivable
|
17
16
|
it { should respond_to(:receiver) }
|
18
17
|
its(:receiver) { should be_kind_of(Ccp::Receivers::Base) }
|
18
|
+
|
19
|
+
it "should ignore nil for receiver values" do
|
20
|
+
subject.receiver = nil
|
21
|
+
subject.receiver.should be_kind_of(Ccp::Receivers::Base)
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
describe "#execute" do
|
@@ -26,22 +30,4 @@ describe Ccp::Commands::Core do
|
|
26
30
|
cmd1.data[:breadcrumbs].should == ["Cmd1#execute"]
|
27
31
|
end
|
28
32
|
end
|
29
|
-
|
30
|
-
describe "#benchmark" do
|
31
|
-
it "should call {before,execute,after}" do
|
32
|
-
cmd1 = Cmd1.new
|
33
|
-
cmd1.data[:breadcrumbs] = []
|
34
|
-
cmd1.benchmark
|
35
|
-
cmd1.data[:breadcrumbs].should == ["Cmd1#before", "Cmd1#execute", "Cmd1#after"]
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should call receiver.profile" do
|
39
|
-
(receiver = Ccp::Receivers::Base.new).should_receive(:profile)
|
40
|
-
|
41
|
-
cmd1 = Cmd1.new
|
42
|
-
cmd1.receiver = receiver
|
43
|
-
cmd1.data[:breadcrumbs] = []
|
44
|
-
cmd1.benchmark
|
45
|
-
end
|
46
|
-
end
|
47
33
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Ccp::Commands::Executable do
|
4
|
+
describe "#execute" do
|
5
|
+
it "should call only execute" do
|
6
|
+
cmd1 = Cmd1.new
|
7
|
+
cmd1.data[:breadcrumbs] = []
|
8
|
+
cmd1.execute
|
9
|
+
cmd1.data[:breadcrumbs].should == ["Cmd1#execute"]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".execute" do
|
14
|
+
it "should call {before,execute,after}" do
|
15
|
+
cmd1 = Cmd1.execute(:breadcrumbs => [])
|
16
|
+
cmd1.data[:breadcrumbs].should == ["Cmd1#before", "Cmd1#execute", "Cmd1#after"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/invokers_spec.rb
CHANGED
@@ -20,25 +20,6 @@ describe Ccp::Invokers::Base do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe "#benchmark" do
|
24
|
-
it "should call its and sub commands's {before,execute,after} in declared order" do
|
25
|
-
c = CompositeInvoker.new
|
26
|
-
c.data[:breadcrumbs] = []
|
27
|
-
c.benchmark
|
28
|
-
c.data[:breadcrumbs].should ==
|
29
|
-
["CompositeInvoker#before",
|
30
|
-
"Cmd1#before", "Cmd1#execute", "Cmd1#after",
|
31
|
-
"Cmd23#before",
|
32
|
-
"Cmd23#execute:start",
|
33
|
-
"Cmd2#before", "Cmd2#execute", "Cmd2#after",
|
34
|
-
"Cmd3#before", "Cmd3#execute", "Cmd3#after",
|
35
|
-
"Cmd23#execute:end",
|
36
|
-
"Cmd23#after",
|
37
|
-
"Cmd4#before", "Cmd4#execute", "Cmd4#after",
|
38
|
-
"CompositeInvoker#after"]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
23
|
describe ".execute" do
|
43
24
|
it "should call its and sub commands's {before,execute,after} in declared order" do
|
44
25
|
c = CompositeInvoker.execute(:breadcrumbs => [])
|
@@ -75,13 +56,13 @@ describe Ccp::Invokers::Base do
|
|
75
56
|
end
|
76
57
|
end
|
77
58
|
|
78
|
-
describe ".
|
59
|
+
describe ".execute" do
|
79
60
|
it "should call its and sub commands's {before,execute,after} in declared order" do
|
80
61
|
r = Ccp::Receivers::Base.new
|
81
62
|
r.stub!(:show_comments) # disable output
|
82
63
|
r.stub!(:show_profiles) # disable output
|
83
64
|
|
84
|
-
c = CompositeInvoker.
|
65
|
+
c = CompositeInvoker.execute(:receiver => r, :breadcrumbs => [])
|
85
66
|
c.data[:breadcrumbs].should ==
|
86
67
|
["CompositeInvoker#before",
|
87
68
|
"Cmd1#before", "Cmd1#execute", "Cmd1#after",
|
@@ -98,22 +79,20 @@ describe Ccp::Invokers::Base do
|
|
98
79
|
it "should call only show_comments in default" do
|
99
80
|
r = Ccp::Receivers::Base.new
|
100
81
|
r.should_receive(:show_comments).once
|
101
|
-
r.should_receive(:show_profiles).
|
102
|
-
CompositeInvoker.
|
82
|
+
r.should_receive(:show_profiles).never
|
83
|
+
CompositeInvoker.execute(:receiver => r, :breadcrumbs => [])
|
103
84
|
end
|
104
85
|
|
105
|
-
it "should disable show_profiles if :profile option is
|
86
|
+
it "should disable show_profiles if :profile option is set" do
|
106
87
|
r = Ccp::Receivers::Base.new
|
107
|
-
r.should_receive(:
|
108
|
-
|
109
|
-
CompositeInvoker.benchmark(:receiver => r, :breadcrumbs => [], :profile => false)
|
88
|
+
r.should_receive(:show_profiles).once
|
89
|
+
CompositeInvoker.execute(:receiver => r, :breadcrumbs => [], :profile => true)
|
110
90
|
end
|
111
91
|
|
112
92
|
it "should disable show_comments if :comment option is false" do
|
113
93
|
r = Ccp::Receivers::Base.new
|
114
94
|
r.should_receive(:show_comments).never
|
115
|
-
|
116
|
-
CompositeInvoker.benchmark(:receiver => r, :breadcrumbs => [], :comment => false)
|
95
|
+
CompositeInvoker.execute(:receiver => r, :breadcrumbs => [], :comment => false)
|
117
96
|
end
|
118
97
|
end
|
119
98
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Ccp::Commands::Base do
|
4
|
+
describe ".execute(:save_fixture=>true)" do
|
5
|
+
class TSFC # TestSaveFixtureCmd
|
6
|
+
include Ccp::Commands::Core
|
7
|
+
|
8
|
+
def execute
|
9
|
+
data[:a] # read
|
10
|
+
data[:x] = 10 # write
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_yaml(path)
|
15
|
+
YAML.load(Pathname(path).read{})
|
16
|
+
end
|
17
|
+
|
18
|
+
def truncate(path)
|
19
|
+
require 'fileutils'
|
20
|
+
FileUtils.rm_rf(path.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should generate in/out fixtures in tmp/fixtures" do
|
24
|
+
path = Pathname("tmp/fixtures")
|
25
|
+
data = {:a=>"a", :b=>"b", :x=>1, :y=>2}
|
26
|
+
opts = {:save_fixture=>true}
|
27
|
+
|
28
|
+
truncate(path)
|
29
|
+
TSFC.execute(data.merge(opts))
|
30
|
+
|
31
|
+
load_yaml(path + "tsfc/in.yaml" ).should == {:a=>"a"}
|
32
|
+
load_yaml(path + "tsfc/out.yaml").should == {:x=>10}
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should generate in/out fixtures in <save_fixture_dir>" do
|
36
|
+
path = Pathname("tmp/test/fixtures")
|
37
|
+
data = {:a=>"a", :b=>"b", :x=>1, :y=>2}
|
38
|
+
opts = {:save_fixture=>true, :save_fixture_dir=>path}
|
39
|
+
|
40
|
+
truncate(path)
|
41
|
+
TSFC.execute(data.merge(opts))
|
42
|
+
|
43
|
+
load_yaml(path + "tsfc/in.yaml" ).should == {:a=>"a"}
|
44
|
+
load_yaml(path + "tsfc/out.yaml").should == {:x=>10}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ccp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- maiha
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-05-01 00:00:00 +09:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -26,18 +26,34 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 17
|
30
30
|
segments:
|
31
31
|
- 0
|
32
32
|
- 1
|
33
|
-
-
|
34
|
-
version: 0.1.
|
33
|
+
- 5
|
34
|
+
version: 0.1.5
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: must
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 25
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 2
|
49
|
+
- 7
|
50
|
+
version: 0.2.7
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: dsl_accessor
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
57
|
none: false
|
42
58
|
requirements:
|
43
59
|
- - ">="
|
@@ -49,11 +65,11 @@ dependencies:
|
|
49
65
|
- 0
|
50
66
|
version: 0.4.0
|
51
67
|
type: :runtime
|
52
|
-
version_requirements: *
|
68
|
+
version_requirements: *id003
|
53
69
|
- !ruby/object:Gem::Dependency
|
54
70
|
name: rspec
|
55
71
|
prerelease: false
|
56
|
-
requirement: &
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
57
73
|
none: false
|
58
74
|
requirements:
|
59
75
|
- - ">="
|
@@ -63,7 +79,7 @@ dependencies:
|
|
63
79
|
- 0
|
64
80
|
version: "0"
|
65
81
|
type: :development
|
66
|
-
version_requirements: *
|
82
|
+
version_requirements: *id004
|
67
83
|
description: CCP
|
68
84
|
email:
|
69
85
|
- maiha@wota.jp
|
@@ -91,21 +107,29 @@ files:
|
|
91
107
|
- lib/ccp/commands/receivable.rb
|
92
108
|
- lib/ccp/commands/resolvable.rb
|
93
109
|
- lib/ccp/data.rb
|
110
|
+
- lib/ccp/fixtures.rb
|
111
|
+
- lib/ccp/fixtures/observer.rb
|
112
|
+
- lib/ccp/fixtures/writers.rb
|
94
113
|
- lib/ccp/invokers.rb
|
95
114
|
- lib/ccp/invokers/base.rb
|
96
115
|
- lib/ccp/receivers.rb
|
116
|
+
- lib/ccp/receivers/aroundable.rb
|
97
117
|
- lib/ccp/receivers/base.rb
|
98
118
|
- lib/ccp/receivers/commentable.rb
|
119
|
+
- lib/ccp/receivers/executable.rb
|
99
120
|
- lib/ccp/receivers/global.rb
|
100
121
|
- lib/ccp/receivers/none.rb
|
101
122
|
- lib/ccp/receivers/profileable.rb
|
123
|
+
- lib/ccp/receivers/save_fixture.rb
|
102
124
|
- lib/ccp/version.rb
|
103
125
|
- spec/commands_base_spec.rb
|
104
126
|
- spec/commands_composite_spec.rb
|
105
127
|
- spec/commands_core_spec.rb
|
128
|
+
- spec/commands_executable_spec.rb
|
106
129
|
- spec/data_spec.rb
|
107
130
|
- spec/invokers_spec.rb
|
108
131
|
- spec/models.rb
|
132
|
+
- spec/save_fixture_spec.rb
|
109
133
|
- spec/spec_helper.rb
|
110
134
|
has_rdoc: true
|
111
135
|
homepage: http://github.com/maiha/ccp
|