ccp 0.1.2 → 0.1.3

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/README.rdoc ADDED
@@ -0,0 +1,111 @@
1
+ = ccp
2
+
3
+ CCP is a Ruby library for Composite Command Programming
4
+ that helps you to split spaghetti codes into pieces.
5
+
6
+ === Websites
7
+ * http://github.com/maiha/ccp
8
+
9
+ == What is a Composite Command Programming?
10
+
11
+ There are three principles.
12
+
13
+ 1. SRP (Single responsibility principle)
14
+ 2. Typed Variables (especially needed in Ruby)
15
+ 3. Explicit Data Dependencies
16
+
17
+ As you know, Ruby is a handy and powerful programming language.
18
+ We can use variables without definitions and re-assign them even if type mismatch.
19
+ Although it is very comfortable while you are writing, it would be painful for others.
20
+
21
+ CCP is a framework composed with above principles and a few debugging utils
22
+ that gives you(as writer) a little restrictions and gives you(as reader) a readability.
23
+
24
+
25
+ == Example
26
+ === usual ruby code
27
+
28
+ class SomeOperation
29
+ def execute
30
+ # fetching data
31
+ # calculating it
32
+ # print results
33
+ end
34
+ end
35
+
36
+ Later, it would be a more complex and longer code like this.
37
+
38
+ class SomeOperation
39
+ def execute
40
+ @data = fetch_data
41
+ ...
42
+ @result = calculate(@data)
43
+ ...
44
+ print_results(@result)
45
+ end
46
+
47
+ def fetching_data
48
+ # accessing instance variables, and long code here
49
+ ...
50
+
51
+ Let's imagine a situation that you need to replace above "fetch" code after several years.
52
+ It is too hard to see data dependencies especially about instance variables.
53
+
54
+ === with CCP
55
+
56
+ class SomeOperation
57
+ include Ccp::Commands::Composite
58
+
59
+ command FetchData
60
+ command Calculate
61
+ command PrintResult
62
+ end
63
+
64
+ class FetchData # 1. SRP
65
+ include Ccp::Commands::Core
66
+
67
+ # {pre,post} methods can be used like Design By Contract
68
+ def post
69
+ data.check(:fetched, {Symbol => [Float]}) # 2. Typed Variables
70
+ end
71
+
72
+ def execute
73
+ # fetching data...
74
+ data[:fetched] = ... # 3. Data Dependencies
75
+ end
76
+ end
77
+
78
+ class Calculate
79
+ ...
80
+
81
+
82
+ All sub commands like FetchData,Calculate,PrintResult are executed
83
+ in each scopes, and can share variables only via data object.
84
+
85
+ So you can easily refactor or replace FetchData unit
86
+ because there are no implicit instance variable dependencies
87
+ and futhermore all depencenies would be explicitly declared in "pre","post" method.
88
+
89
+ === execute
90
+
91
+ Just call a "execute" instance method.
92
+
93
+ cmd = SomeOperation.new
94
+ cmd.execute
95
+
96
+ === invokers
97
+
98
+ Invokers::Base can be used as a top level composite command.
99
+
100
+ class SomeOperation < Ccp::Invokers::Base
101
+ command FetchData
102
+ ...
103
+
104
+
105
+ Its "benchmark" method generates profile information.
106
+
107
+ ruby -r some_operation -e 'SomeOperation.new.benchmark'
108
+ [43.3%] 2.5834830 FetchData#execute
109
+ [35.9%] 2.0710440 Calculate#execute
110
+ ...
111
+
data/ccp.gemspec CHANGED
@@ -18,7 +18,7 @@ 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.0"
21
+ s.add_dependency "typed", ">= 0.1.2"
22
22
  s.add_dependency "dsl_accessor", ">= 0.4.0"
23
23
 
24
24
  s.add_development_dependency "rspec"
data/lib/ccp.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "typed"
2
+ require "dsl_accessor"
2
3
  require "active_support/core_ext"
3
4
  require "ccp/version"
4
5
  require "ccp/data"
@@ -56,12 +56,6 @@ module Ccp
56
56
  ######################################################################
57
57
  ### Enumerable
58
58
 
59
- def <<(command)
60
- command = command.new if command.is_a?(Class) and command.ancestors.include?(Core)
61
- command.must(Core)
62
- commands << command
63
- end
64
-
65
59
  def commands
66
60
  @commands ||= build_commands.must(Array)
67
61
  end
@@ -70,19 +64,18 @@ module Ccp
70
64
  ### Commands
71
65
 
72
66
  def execute
73
- benchmark
67
+ commands.each(&:benchmark)
74
68
  end
75
69
 
76
- def benchmark
77
- pre if respond_to?(:pre)
78
- commands.each(&:benchmark)
79
- post if respond_to?(:post)
70
+ def receiver=(value)
71
+ super
72
+ commands.each{|c| c.receiver = value}
80
73
  end
81
74
 
82
75
  private
83
76
  def build_commands
84
77
  array = self.class.commands.select{|c| c.cond.nil? or instance_eval(&c.cond)}
85
- array.map{|c|
78
+ cmds = array.map{|c|
86
79
  c = c.klass.new(*c.args)
87
80
  c.receiver = receiver
88
81
  c
@@ -9,8 +9,8 @@ module Ccp
9
9
 
10
10
  ### Profiling
11
11
 
12
- def benchmark(method = :execute)
13
- receiver.profile(self, method)
12
+ def benchmark
13
+ receiver.profile(self, :execute)
14
14
  end
15
15
  end
16
16
  end
@@ -5,7 +5,7 @@ module Ccp
5
5
  ### Receiver Methods
6
6
 
7
7
  def receiver
8
- @receiver ||= Ccp::Receivers::None.new
8
+ @receiver ||= Ccp::Receivers::Base.new
9
9
  end
10
10
 
11
11
  def receiver=(value)
@@ -12,26 +12,49 @@ module Ccp
12
12
  DEFAULT_OPTIONS = {
13
13
  :profile => false,
14
14
  :comment => true,
15
+ :logger => Logger.new($stderr),
15
16
  }
16
17
 
18
+ ######################################################################
19
+ ### Class Methods
20
+
21
+ def self.execute(options = {}, &block)
22
+ cmd = new(options)
23
+ if block_given?
24
+ cmd.instance_eval(&block)
25
+ end
26
+ cmd.benchmark
27
+ return cmd
28
+ end
29
+
30
+ def self.benchmark(options = {}, &block)
31
+ execute({:profile => true}.merge(options), &block)
32
+ end
33
+
17
34
  ######################################################################
18
35
  ### Instance Methods
19
36
 
20
37
  def initialize(options = nil)
21
- self.receiver = self.class.receiver.new
22
- self.class.prepend_command Commands::RuntimeArgs, options
38
+ options ||= {}
39
+ set_default_receiver(options[:receiver])
23
40
  set_default_options
41
+ set_runtime_options(options)
42
+ end
43
+
44
+ def set_default_receiver(receiver)
45
+ self.receiver = receiver || self.class.receiver.new
24
46
  end
25
47
 
26
48
  def set_default_options
27
49
  self.class::DEFAULT_OPTIONS.each_pair do |key,val|
28
50
  data.default[key] = val
29
51
  end
30
- data.default(:logger) { Logger.new($stderr) }
31
52
  end
32
53
 
33
- def execute
34
- benchmark
54
+ def set_runtime_options(options)
55
+ options.each_pair do |key,val|
56
+ data[key] = val
57
+ end
35
58
  end
36
59
 
37
60
  def benchmark
data/lib/ccp/receivers.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Ccp
2
2
  module Receivers
3
3
  autoload :Base , 'ccp/receivers/base'
4
- autoload :None , 'ccp/receivers/none'
4
+ autoload :Global , 'ccp/receivers/global'
5
5
  autoload :Commentable , 'ccp/receivers/commentable'
6
6
  autoload :Profileable , 'ccp/receivers/profileable'
7
7
  end
@@ -0,0 +1,9 @@
1
+ module Ccp
2
+ module Receivers
3
+ class Global < Base
4
+ def self.new
5
+ @instance ||= super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,6 +1,6 @@
1
1
  module Ccp
2
2
  module Receivers
3
- class None < Base
3
+ class Global < Base
4
4
  def self.new
5
5
  @instance ||= super
6
6
  end
@@ -16,12 +16,16 @@ module Ccp
16
16
 
17
17
  def profile(target, method)
18
18
  start = Time.new
19
- target.pre if target.must.duck?(:pre)
19
+ target.__send__(:pre) if target.respond_to?(:pre)
20
20
  target.__send__(method)
21
- target.post if target.must.duck?(:post)
22
- target.must.duck(:no_bench) {
21
+ target.__send__(:post) if target.respond_to?(:post)
22
+
23
+ case target
24
+ when Ccp::Commands::Composite
25
+ # no profiles
26
+ else
23
27
  profiles << Profile.new(target, method, (Time.new - start).to_f)
24
- }
28
+ end
25
29
  end
26
30
 
27
31
  def profiles
data/lib/ccp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ccp
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -0,0 +1,83 @@
1
+ require "spec_helper"
2
+
3
+ describe Ccp::Commands::Composite do
4
+ describe "#execute" do
5
+ it "should call its execute and sub commands's {pre,execute,post} in declared order" do
6
+ c = Program.new
7
+ c.data[:breadcrumbs] = []
8
+ c.execute
9
+ c.data[:breadcrumbs].should ==
10
+ ["Cmd1#pre", "Cmd1#execute", "Cmd1#post",
11
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
12
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post"]
13
+ end
14
+ end
15
+
16
+ describe "#benchmark" do
17
+ it "should call its and sub commands's {pre,execute,post} in declared order" do
18
+ c = Program.new
19
+ c.data[:breadcrumbs] = []
20
+ c.benchmark
21
+ c.data[:breadcrumbs].should ==
22
+ ["Program#pre",
23
+ "Cmd1#pre", "Cmd1#execute", "Cmd1#post",
24
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
25
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
26
+ "Program#post"]
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "Ccp::Commands::Composite(nested)" do
32
+ describe "#execute" do
33
+ it "should call its execute and sub commands's {pre,execute,post} in declared order" do
34
+ c = CompositeProgram.new
35
+ c.data[:breadcrumbs] = []
36
+ c.execute
37
+ c.data[:breadcrumbs].should ==
38
+ ["Cmd1#pre", "Cmd1#execute", "Cmd1#post",
39
+ "Cmd23#pre",
40
+ "Cmd23#execute:start",
41
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
42
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
43
+ "Cmd23#execute:end",
44
+ "Cmd23#post",
45
+ "Cmd4#pre", "Cmd4#execute", "Cmd4#post"]
46
+ end
47
+ end
48
+
49
+ describe "#benchmark" do
50
+ it "should call its and sub commands's {pre,execute,post} in declared order" do
51
+ c = CompositeProgram.new
52
+ c.data[:breadcrumbs] = []
53
+ c.benchmark
54
+ c.data[:breadcrumbs].should ==
55
+ ["CompositeProgram#pre",
56
+ "Cmd1#pre", "Cmd1#execute", "Cmd1#post",
57
+ "Cmd23#pre",
58
+ "Cmd23#execute:start",
59
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
60
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
61
+ "Cmd23#execute:end",
62
+ "Cmd23#post",
63
+ "Cmd4#pre", "Cmd4#execute", "Cmd4#post",
64
+ "CompositeProgram#post"]
65
+ end
66
+ end
67
+
68
+ it "should update receiver recursively" do
69
+ cmd = CompositeProgram.new
70
+ cmd.commands.each do |c|
71
+ c.receiver.should == cmd.receiver
72
+ end
73
+
74
+ new_receiver = Ccp::Receivers::Base.new
75
+ new_receiver.should_not == cmd.receiver
76
+
77
+ # update receiver
78
+ cmd.receiver = new_receiver
79
+ cmd.commands.each do |c|
80
+ c.receiver.should == cmd.receiver
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Ccp::Commands::Core do
4
+ describe "(accessor)" do
5
+ subject { Object.new.extend Ccp::Commands::Core }
6
+
7
+ # data container
8
+ it { should respond_to(:data?) }
9
+ it { should respond_to(:data) }
10
+ its(:data) { should be_kind_of(Typed::Hash) }
11
+
12
+ # executable
13
+ it { should respond_to(:execute) }
14
+ it { should respond_to(:benchmark) }
15
+
16
+ # receivable
17
+ it { should respond_to(:receiver) }
18
+ its(:receiver) { should be_kind_of(Ccp::Receivers::Base) }
19
+ end
20
+
21
+ describe "#execute" do
22
+ it "should call only execute" do
23
+ cmd1 = Cmd1.new
24
+ cmd1.data[:breadcrumbs] = []
25
+ cmd1.execute
26
+ cmd1.data[:breadcrumbs].should == ["Cmd1#execute"]
27
+ end
28
+ end
29
+
30
+ describe "#benchmark" do
31
+ it "should call {pre,execute,post}" do
32
+ cmd1 = Cmd1.new
33
+ cmd1.data[:breadcrumbs] = []
34
+ cmd1.benchmark
35
+ cmd1.data[:breadcrumbs].should == ["Cmd1#pre", "Cmd1#execute", "Cmd1#post"]
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
+ end
@@ -0,0 +1,121 @@
1
+ require "spec_helper"
2
+
3
+ describe Ccp::Invokers::Base do
4
+ def no_logger; Logger.new('/dev/null'); end
5
+
6
+ describe "#execute" do
7
+ it "should call its execute and sub commands's {pre,execute,post} in declared order" do
8
+ c = CompositeInvoker.new
9
+ c.data[:breadcrumbs] = []
10
+ c.execute
11
+ c.data[:breadcrumbs].should ==
12
+ ["Cmd1#pre", "Cmd1#execute", "Cmd1#post",
13
+ "Cmd23#pre",
14
+ "Cmd23#execute:start",
15
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
16
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
17
+ "Cmd23#execute:end",
18
+ "Cmd23#post",
19
+ "Cmd4#pre", "Cmd4#execute", "Cmd4#post"]
20
+ end
21
+ end
22
+
23
+ describe "#benchmark" do
24
+ it "should call its and sub commands's {pre,execute,post} in declared order" do
25
+ c = CompositeInvoker.new
26
+ c.data[:breadcrumbs] = []
27
+ c.benchmark
28
+ c.data[:breadcrumbs].should ==
29
+ ["CompositeInvoker#pre",
30
+ "Cmd1#pre", "Cmd1#execute", "Cmd1#post",
31
+ "Cmd23#pre",
32
+ "Cmd23#execute:start",
33
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
34
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
35
+ "Cmd23#execute:end",
36
+ "Cmd23#post",
37
+ "Cmd4#pre", "Cmd4#execute", "Cmd4#post",
38
+ "CompositeInvoker#post"]
39
+ end
40
+ end
41
+
42
+ describe ".execute" do
43
+ it "should call its and sub commands's {pre,execute,post} in declared order" do
44
+ c = CompositeInvoker.execute(:breadcrumbs => [])
45
+ c.data[:breadcrumbs].should ==
46
+ ["CompositeInvoker#pre",
47
+ "Cmd1#pre", "Cmd1#execute", "Cmd1#post",
48
+ "Cmd23#pre",
49
+ "Cmd23#execute:start",
50
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
51
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
52
+ "Cmd23#execute:end",
53
+ "Cmd23#post",
54
+ "Cmd4#pre", "Cmd4#execute", "Cmd4#post",
55
+ "CompositeInvoker#post"]
56
+ end
57
+
58
+ it "should call only show_comments in default" do
59
+ r = Ccp::Receivers::Base.new
60
+ r.should_receive(:show_comments).once
61
+ r.should_receive(:show_profiles).never
62
+ CompositeInvoker.execute(:receiver => r, :breadcrumbs => [])
63
+ end
64
+
65
+ it "should call show_profiles if :profile option is given" do
66
+ r = Ccp::Receivers::Base.new
67
+ r.should_receive(:show_profiles).once
68
+ CompositeInvoker.execute(:receiver => r, :breadcrumbs => [], :profile => true)
69
+ end
70
+
71
+ it "should disable show_comments if :comment option is false" do
72
+ r = Ccp::Receivers::Base.new
73
+ r.should_receive(:show_comments).never
74
+ CompositeInvoker.execute(:receiver => r, :breadcrumbs => [], :comment => false)
75
+ end
76
+ end
77
+
78
+ describe ".benchmark" do
79
+ it "should call its and sub commands's {pre,execute,post} in declared order" do
80
+ r = Ccp::Receivers::Base.new
81
+ r.stub!(:show_comments) # disable output
82
+ r.stub!(:show_profiles) # disable output
83
+
84
+ c = CompositeInvoker.benchmark(:receiver => r, :breadcrumbs => [])
85
+ c.data[:breadcrumbs].should ==
86
+ ["CompositeInvoker#pre",
87
+ "Cmd1#pre", "Cmd1#execute", "Cmd1#post",
88
+ "Cmd23#pre",
89
+ "Cmd23#execute:start",
90
+ "Cmd2#pre", "Cmd2#execute", "Cmd2#post",
91
+ "Cmd3#pre", "Cmd3#execute", "Cmd3#post",
92
+ "Cmd23#execute:end",
93
+ "Cmd23#post",
94
+ "Cmd4#pre", "Cmd4#execute", "Cmd4#post",
95
+ "CompositeInvoker#post"]
96
+ end
97
+
98
+ it "should call only show_comments in default" do
99
+ r = Ccp::Receivers::Base.new
100
+ r.should_receive(:show_comments).once
101
+ r.should_receive(:show_profiles).once
102
+ CompositeInvoker.benchmark(:receiver => r, :breadcrumbs => [])
103
+ end
104
+
105
+ it "should disable show_profiles if :profile option is false" do
106
+ r = Ccp::Receivers::Base.new
107
+ r.should_receive(:show_comments).once
108
+ r.should_receive(:show_profiles).never
109
+ CompositeInvoker.benchmark(:receiver => r, :breadcrumbs => [], :profile => false)
110
+ end
111
+
112
+ it "should disable show_comments if :comment option is false" do
113
+ r = Ccp::Receivers::Base.new
114
+ r.should_receive(:show_comments).never
115
+ r.should_receive(:show_profiles).once
116
+ CompositeInvoker.benchmark(:receiver => r, :breadcrumbs => [], :comment => false)
117
+ end
118
+ end
119
+ end
120
+
121
+
data/spec/models.rb ADDED
@@ -0,0 +1,98 @@
1
+ module Breadcrumbing
2
+ def this
3
+ "%s#%s" % [self.class.name, caller[0].to_s.scan(/`(.*?)'/).first]
4
+ end
5
+ end
6
+
7
+ class Cmd1
8
+ include Ccp::Commands::Core
9
+ include Breadcrumbing
10
+
11
+ def pre
12
+ data[:breadcrumbs] << this
13
+ end
14
+
15
+ def execute
16
+ data[:breadcrumbs] << this
17
+ end
18
+
19
+ def post
20
+ data[:breadcrumbs] << this
21
+ end
22
+ end
23
+
24
+ class Cmd2 < Cmd1; end
25
+ class Cmd3 < Cmd1; end
26
+ class Cmd4 < Cmd1; end
27
+
28
+ class Program
29
+ include Ccp::Commands::Composite
30
+ include Breadcrumbing
31
+
32
+ command Cmd1
33
+ command Cmd2
34
+ command Cmd3
35
+
36
+ def pre
37
+ data[:breadcrumbs] << this
38
+ end
39
+
40
+ def post
41
+ data[:breadcrumbs] << this
42
+ end
43
+ end
44
+
45
+ class Cmd23
46
+ include Ccp::Commands::Composite
47
+ include Breadcrumbing
48
+
49
+ command Cmd2
50
+ command Cmd3
51
+
52
+ def pre
53
+ data[:breadcrumbs] << this
54
+ end
55
+
56
+ def execute
57
+ data[:breadcrumbs] << this + ":start"
58
+ super
59
+ data[:breadcrumbs] << this + ":end"
60
+ end
61
+
62
+ def post
63
+ data[:breadcrumbs] << this
64
+ end
65
+ end
66
+
67
+ class CompositeProgram
68
+ include Ccp::Commands::Composite
69
+ include Breadcrumbing
70
+
71
+ command Cmd1
72
+ command Cmd23
73
+ command Cmd4
74
+
75
+ def pre
76
+ data[:breadcrumbs] << this
77
+ end
78
+
79
+ def post
80
+ data[:breadcrumbs] << this
81
+ end
82
+ end
83
+
84
+ class CompositeInvoker < Ccp::Invokers::Base
85
+ include Breadcrumbing
86
+
87
+ command Cmd1
88
+ command Cmd23
89
+ command Cmd4
90
+
91
+ def pre
92
+ data[:breadcrumbs] << this
93
+ end
94
+
95
+ def post
96
+ data[:breadcrumbs] << this
97
+ end
98
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,3 +3,5 @@ $:.unshift File.expand_path('../../lib', __FILE__)
3
3
 
4
4
  require 'rspec'
5
5
  require 'ccp'
6
+
7
+ require File.join(File.dirname(__FILE__), "models")
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: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
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-02-10 00:00:00 +09:00
18
+ date: 2012-02-14 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -26,12 +26,12 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- hash: 27
29
+ hash: 31
30
30
  segments:
31
31
  - 0
32
32
  - 1
33
- - 0
34
- version: 0.1.0
33
+ - 2
34
+ version: 0.1.2
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
@@ -76,7 +76,7 @@ extra_rdoc_files: []
76
76
  files:
77
77
  - .gitignore
78
78
  - Gemfile
79
- - README
79
+ - README.rdoc
80
80
  - Rakefile
81
81
  - ccp.gemspec
82
82
  - lib/ccp.rb
@@ -89,19 +89,21 @@ files:
89
89
  - lib/ccp/commands/executable.rb
90
90
  - lib/ccp/commands/receivable.rb
91
91
  - lib/ccp/commands/resolvable.rb
92
- - lib/ccp/commands/runtime_args.rb
93
92
  - lib/ccp/data.rb
94
93
  - lib/ccp/invokers.rb
95
94
  - lib/ccp/invokers/base.rb
96
95
  - lib/ccp/receivers.rb
97
96
  - lib/ccp/receivers/base.rb
98
97
  - lib/ccp/receivers/commentable.rb
98
+ - lib/ccp/receivers/global.rb
99
99
  - lib/ccp/receivers/none.rb
100
100
  - lib/ccp/receivers/profileable.rb
101
101
  - lib/ccp/version.rb
102
- - spec/commands_spec.rb
103
- - spec/composite_spec.rb
102
+ - spec/commands_composite_spec.rb
103
+ - spec/commands_core_spec.rb
104
104
  - spec/data_spec.rb
105
+ - spec/invokers_spec.rb
106
+ - spec/models.rb
105
107
  - spec/spec_helper.rb
106
108
  has_rdoc: true
107
109
  homepage: http://github.com/maiha/ccp
data/README DELETED
File without changes
@@ -1,24 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # map options to data
3
-
4
- module Ccp
5
- module Commands
6
- class RuntimeArgs
7
- include Core
8
-
9
- def initialize(options = {})
10
- @options = (options || {}).must(Hash)
11
- end
12
-
13
- def execute
14
- @options.each_pair do |key, val|
15
- data[key] = val
16
- end
17
- end
18
-
19
- def inspect
20
- super.sub(/>$/, " #{@options.inspect}>")
21
- end
22
- end
23
- end
24
- end
@@ -1,18 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Ccp::Commands::Core do
4
- subject { Object.new.extend Ccp::Commands::Core }
5
-
6
- # data container
7
- it { should respond_to(:data?) }
8
- it { should respond_to(:data) }
9
- its(:data) { should be_kind_of(Typed::Hash) }
10
-
11
- # executable
12
- it { should respond_to(:execute) }
13
- it { should respond_to(:benchmark) }
14
-
15
- # receivable
16
- it { should respond_to(:receiver) }
17
- its(:receiver) { should be_kind_of(Ccp::Receivers::Base) }
18
- end
@@ -1,85 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Ccp::Commands::Composite do
4
- module Breadcrumbing
5
- BREADCRUMBS = []
6
-
7
- def this
8
- "%s#%s" % [self.class.name, caller[0].to_s.scan(/`(.*?)'/).first]
9
- end
10
-
11
- def breadcrumbs
12
- BREADCRUMBS
13
- end
14
- end
15
-
16
- class Cmd1
17
- include Ccp::Commands::Core
18
- include Breadcrumbing
19
-
20
- def execute
21
- breadcrumbs << this
22
- data[:foo] = []
23
- end
24
-
25
- def post
26
- breadcrumbs << this
27
- end
28
- end
29
-
30
- class Cmd2
31
- include Ccp::Commands::Core
32
- include Breadcrumbing
33
-
34
- def pre
35
- breadcrumbs << this
36
- end
37
-
38
- def execute
39
- breadcrumbs << this
40
- data[:foo] << "cmd2"
41
- end
42
-
43
- def post
44
- breadcrumbs << this
45
- end
46
- end
47
-
48
- class Cmd3
49
- include Ccp::Commands::Core
50
- include Breadcrumbing
51
-
52
- def pre
53
- breadcrumbs << this
54
- end
55
-
56
- def execute
57
- breadcrumbs << this
58
- data[:foo] << "cmd3"
59
- end
60
- end
61
-
62
- class Program
63
- include Ccp::Commands::Composite
64
-
65
- command Cmd1
66
- command Cmd2
67
- command Cmd3
68
- end
69
-
70
- subject { Program.new }
71
-
72
- it { should be_kind_of(Ccp::Commands::Core) }
73
-
74
- it "should call sub commands's {pre,execute,post} in declared order" do
75
- Breadcrumbing::BREADCRUMBS.clear
76
- subject.execute
77
- Breadcrumbing::BREADCRUMBS.should ==
78
- ["Cmd1#execute", "Cmd1#post", "Cmd2#pre", "Cmd2#execute", "Cmd2#post", "Cmd3#pre", "Cmd3#execute"]
79
- end
80
-
81
- it "should share same data storage in each sub commands" do
82
- subject.execute
83
- subject.data[:foo].should == ["cmd2", "cmd3"]
84
- end
85
- end