ccp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'must', '>= 0.2.5'
4
+ gem 'dsl_accessor', '>= 0.4.0'
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/ccp.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ccp/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ccp"
7
+ s.version = Ccp::VERSION
8
+ s.authors = ["maiha"]
9
+ s.email = ["maiha@wota.jp"]
10
+ s.homepage = "http://github.com/maiha/ccp"
11
+ s.summary = %q{A Ruby library for Composite Command Programming}
12
+ s.description = %q{CCP}
13
+
14
+ s.rubyforge_project = "ccp"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "activesupport"
22
+ s.add_dependency "must", ">= 0.2.5"
23
+ s.add_dependency "dsl_accessor", ">= 0.4.0"
24
+
25
+ s.add_development_dependency "rspec"
26
+ end
data/lib/ccp.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "must"
2
+ require "active_support/core_ext"
3
+ require "ccp/version"
4
+ require "ccp/data"
5
+
6
+ module Ccp
7
+ autoload :Colorize, 'ccp/colorize'
8
+ autoload :Commands, 'ccp/commands'
9
+ autoload :Invokers, 'ccp/invokers'
10
+ autoload :Receivers, 'ccp/receivers'
11
+ end
@@ -0,0 +1,13 @@
1
+ module Ccp
2
+ module Colorize
3
+ def colorize(text, ansi); "#{ansi}#{text}\e[0m"; end
4
+ def red (text); colorize(text, "\e[31m"); end
5
+ def green (text); colorize(text, "\e[32m"); end
6
+ def yellow(text); colorize(text, "\e[33m"); end
7
+ def blue (text); colorize(text, "\e[34m"); end
8
+ def pink (text); colorize(text, "\e[35m"); end
9
+ def aqua (text); colorize(text, "\e[36m"); end
10
+
11
+ extend self
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module Ccp
2
+ module Commands
3
+ autoload :CommandNotFound, 'ccp/commands/command_not_found'
4
+ autoload :Composite , 'ccp/commands/composite'
5
+ autoload :Executable , 'ccp/commands/executable'
6
+ autoload :Receivable , 'ccp/commands/receivable'
7
+ autoload :RuntimeArgs , 'ccp/commands/runtime_args'
8
+ autoload :Commentable , 'ccp/commands/commentable'
9
+ autoload :Core , 'ccp/commands/core'
10
+ autoload :Resolvable , 'ccp/commands/resolvable'
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ module Ccp
2
+ module Commands
3
+ CommandNotFound = Class.new(RuntimeError)
4
+ end
5
+ end
6
+
@@ -0,0 +1,21 @@
1
+ module Ccp
2
+ module Commands
3
+ module Commentable
4
+ def MEMO(*messages)
5
+ from = caller.is_a?(Array) ? caller.first : self.class
6
+ receiver.comment("MEMO: #{_build_comment(*messages)}\n #{from}")
7
+ end
8
+
9
+ def TODO(*messages)
10
+ from = caller.is_a?(Array) ? caller.first : self.class
11
+ receiver.comment("TODO: #{_build_comment(*messages)}\n #{from}", :warn)
12
+ end
13
+
14
+ private
15
+ def _build_comment(*objs)
16
+ objs = objs.first if objs.size == 1
17
+ objs.is_a?(String) ? objs : objs.inspect
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,93 @@
1
+ module Ccp
2
+ module Commands
3
+ module Composite
4
+ def self.included(base)
5
+ base.class_eval do
6
+ extend ClassMethods
7
+ end
8
+ end
9
+
10
+ CommandClass = Struct.new(:klass, :args, :cond) unless defined?(CommandClass)
11
+ class CommandClass
12
+ def inspect
13
+ name = klass.name.split(/Commands::/,2).last
14
+ "<%s args=%s cond=%s>" % [name, args.inspect, cond.inspect]
15
+ end
16
+
17
+ def to_s
18
+ inspect
19
+ end
20
+ end
21
+
22
+ ######################################################################
23
+ ### Class Methods
24
+
25
+ module ClassMethods
26
+ include Resolvable
27
+
28
+ def prepend_command(klass, *args, &block)
29
+ commands.unshift CommandClass.new(resolve(klass), args, block)
30
+ end
31
+
32
+ def append_command(klass, *args, &block)
33
+ klass = resolve(klass)
34
+ if commands.find{|cc| cc.klass == klass}
35
+ # ignore: already added
36
+ else
37
+ commands << CommandClass.new(klass, args, block)
38
+ end
39
+ end
40
+
41
+ def command(*args)
42
+ append_command(*args)
43
+ end
44
+
45
+ def commands
46
+ @commands ||= []
47
+ end
48
+ end
49
+
50
+ ######################################################################
51
+ ### Instance Methods
52
+
53
+ include Core
54
+ include Enumerable
55
+
56
+ ######################################################################
57
+ ### Enumerable
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
+ def commands
66
+ @commands ||= build_commands.must(Array)
67
+ end
68
+
69
+ ######################################################################
70
+ ### Commands
71
+
72
+ def execute
73
+ benchmark
74
+ end
75
+
76
+ def benchmark
77
+ pre if respond_to?(:pre)
78
+ commands.each(&:benchmark)
79
+ post if respond_to?(:post)
80
+ end
81
+
82
+ private
83
+ def build_commands
84
+ array = self.class.commands.select{|c| c.cond.nil? or instance_eval(&c.cond)}
85
+ array.map{|c|
86
+ c = c.klass.new(*c.args)
87
+ c.receiver = receiver
88
+ c
89
+ }
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,14 @@
1
+ module Ccp
2
+ module Commands
3
+ module Core
4
+ include Receivable
5
+ include Executable
6
+ include Commentable
7
+
8
+ def inspect
9
+ klass_name = self.class.name.to_s.split(/::/).last
10
+ "#<#{klass_name}>"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Ccp
2
+ module Commands
3
+ module Executable
4
+
5
+ ### Command
6
+
7
+ def execute
8
+ end
9
+
10
+ ### Profiling
11
+
12
+ def benchmark(method = :execute)
13
+ receiver.profile(self, method)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Ccp
2
+ module Commands
3
+ module Receivable
4
+ ######################################################################
5
+ ### Receiver Methods
6
+
7
+ def receiver
8
+ @receiver ||= Ccp::Receivers::None.new
9
+ end
10
+
11
+ def receiver=(value)
12
+ @receiver = value.must(Ccp::Receivers::Base)
13
+ end
14
+
15
+ ######################################################################
16
+ ### Delegate Methods
17
+
18
+ delegate :data, :data?, :to=>"receiver"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Ccp
2
+ module Commands
3
+ module Resolvable
4
+ def resolve(klass)
5
+ klass.must.coerced(Class, Module) {
6
+ raise CommandNotFound, "expected Class or Module, but got #{klass.class}"
7
+ }
8
+
9
+ if klass.ancestors.include?(Commands::Core)
10
+ return klass # ok
11
+ end
12
+
13
+ if klass.must.duck?("#execute")
14
+ # dynamically assign core
15
+ klass.class_eval{ include Commands::Core }
16
+ return klass
17
+ end
18
+
19
+ raise CommandNotFound, "#{klass} found but it misses 'execute' method"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
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
data/lib/ccp/data.rb ADDED
@@ -0,0 +1,107 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'pathname'
4
+
5
+ module Ccp
6
+ module Data
7
+ NotDefined = Class.new(RuntimeError)
8
+
9
+ class KVS
10
+ delegate :[]=, :to=>"@hash"
11
+
12
+ LazyValue = Struct.new(:block)
13
+
14
+ class Default
15
+ def initialize(kvs)
16
+ @kvs = kvs
17
+ end
18
+
19
+ def []=(key, val)
20
+ return if @kvs.exist?(key)
21
+ @kvs[key] = val
22
+ end
23
+
24
+ def regsiter_lazy(key, block)
25
+ return if @kvs.exist?(key)
26
+ raise ArgumentError, "Lazy default value needs block: #{key}" unless block
27
+ @kvs[key] = LazyValue.new(block)
28
+ end
29
+ end
30
+
31
+ def initialize
32
+ @hash = {}
33
+ @default = Default.new(self)
34
+ end
35
+
36
+ ######################################################################
37
+ ### Default values
38
+
39
+ def default(key = nil, &block)
40
+ if key
41
+ @default.regsiter_lazy(key, block)
42
+ else
43
+ @default
44
+ end
45
+ end
46
+
47
+ ######################################################################
48
+ ### Accessor
49
+
50
+ def [](key)
51
+ if exist?(key)
52
+ return load(key)
53
+ else
54
+ from = caller.is_a?(Array) ? caller.first : self.class
55
+ raise NotDefined, "'#{key}' is not initialized\n#{from}"
56
+ end
57
+ end
58
+
59
+ ######################################################################
60
+ ### Testing
61
+
62
+ def exist?(key)
63
+ @hash.has_key?(key)
64
+ end
65
+
66
+ def set?(key)
67
+ !! (exist?(key) && self[key])
68
+ end
69
+
70
+ def check(key, type)
71
+ self[key].must.struct(type) {
72
+ summary = self[key].inspect
73
+ summary = summary[0,200] + "..." if summary.size > 200
74
+ raise TypeError, "'#{key}' expects '#{type.inspect}', but got #{summary}"
75
+ }
76
+ end
77
+
78
+ ######################################################################
79
+ ### Utils
80
+
81
+ def path(key)
82
+ self[key].must.coerced(Pathname, String=>proc{|i| Pathname(i)})
83
+ end
84
+
85
+ def inspect
86
+ keys = @hash.keys.map(&:to_s).sort.join(',')
87
+ "{#{keys}}"
88
+ end
89
+
90
+ private
91
+ def load(key)
92
+ # LazyValue should be evaluated at runtime
93
+ value = @hash[key]
94
+ value = value.block.call if value.is_a?(LazyValue)
95
+ return value
96
+ end
97
+ end
98
+
99
+ def data
100
+ @data ||= KVS.new
101
+ end
102
+
103
+ def data?(key)
104
+ data.set?(key)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,5 @@
1
+ module Ccp
2
+ module Invokers
3
+ autoload :Base , 'ccp/invokers/base'
4
+ end
5
+ end
@@ -0,0 +1,62 @@
1
+ require 'logger'
2
+
3
+ module Ccp
4
+ module Invokers
5
+ class Base
6
+ include Commands::Composite
7
+
8
+ dsl_accessor :receiver, Receivers::Base
9
+ delegate :show_profiles, :profiles, :to=>"receiver"
10
+ delegate :show_comments, :comments, :to=>"receiver"
11
+
12
+ DEFAULT_OPTIONS = {
13
+ :profile => false,
14
+ :comment => true,
15
+ }
16
+
17
+ ######################################################################
18
+ ### Instance Methods
19
+
20
+ def initialize(options = nil)
21
+ self.receiver = self.class.receiver.new
22
+ self.class.prepend_command Commands::RuntimeArgs, options
23
+ set_default_options
24
+ end
25
+
26
+ def set_default_options
27
+ self.class::DEFAULT_OPTIONS.each_pair do |key,val|
28
+ data.default[key] = val
29
+ end
30
+ data.default(:logger) { Logger.new($stderr) }
31
+ end
32
+
33
+ def execute
34
+ benchmark
35
+ end
36
+
37
+ def benchmark
38
+ before
39
+ super
40
+ after
41
+ return true
42
+ end
43
+
44
+ def receiver
45
+ @receiver.must(Receivers::Base)
46
+ end
47
+
48
+ def receiver=(value)
49
+ @receiver = value.must(Receivers::Base)
50
+ end
51
+
52
+ private
53
+ def before
54
+ end
55
+
56
+ def after
57
+ show_profiles if data?(:profile)
58
+ show_comments if data?(:comment)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,8 @@
1
+ module Ccp
2
+ module Receivers
3
+ autoload :Base , 'ccp/receivers/base'
4
+ autoload :None , 'ccp/receivers/none'
5
+ autoload :Commentable , 'ccp/receivers/commentable'
6
+ autoload :Profileable , 'ccp/receivers/profileable'
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ module Ccp
2
+ module Receivers
3
+ class Base
4
+ include Ccp::Data
5
+ include Profileable
6
+ include Commentable
7
+
8
+ def inspect
9
+ klass_name = self.class.name.to_s.split(/::/).last
10
+
11
+ "#<Receivers::#{klass_name} data:#{data.inspect}>"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module Ccp
2
+ module Receivers
3
+ module Commentable
4
+
5
+ Comment = Struct.new(:text, :level)
6
+ class Comment
7
+ include Colorize
8
+ def colorized
9
+ case level
10
+ when :warn ; yellow(text)
11
+ when :error, :fatal ; red(text)
12
+ when :info ; green(text)
13
+ else ; text
14
+ end
15
+ end
16
+ end
17
+
18
+ def comment(text, level = nil)
19
+ comments[text] ||= Comment.new(text, level)
20
+ end
21
+
22
+ def comments
23
+ @comments ||= ActiveSupport::OrderedHash.new
24
+ end
25
+
26
+ def show_comments(*args)
27
+ opts = Optionize.new(args, :output)
28
+ output = opts[:output] || $stderr
29
+ comments.each_value do |comment|
30
+ output.puts comment.colorized
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module Ccp
2
+ module Receivers
3
+ class None < Base
4
+ def self.new
5
+ @instance ||= super
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,57 @@
1
+ module Ccp
2
+ module Receivers
3
+ module Profileable
4
+ include Colorize
5
+
6
+ Profile = Struct.new(:target, :method, :time)
7
+ class Profile
8
+ def name
9
+ target.is_a?(Class) ? "#{target.name}.#{method}" : "#{target.class}##{method}"
10
+ end
11
+
12
+ def profile(total)
13
+ "[%4.1f%%] %.7f %s" % [(time*100/total), time, name]
14
+ end
15
+ end
16
+
17
+ def profile(target, method)
18
+ start = Time.new
19
+ target.pre if target.must.duck?(:pre)
20
+ target.__send__(method)
21
+ target.post if target.must.duck?(:post)
22
+ target.must.duck(:no_bench) {
23
+ profiles << Profile.new(target, method, (Time.new - start).to_f)
24
+ }
25
+ end
26
+
27
+ def profiles
28
+ @profiles ||= []
29
+ end
30
+
31
+ def show_profiles(*args, &block)
32
+ opts = Optionize.new(args, :benchs, :output)
33
+ benchs = opts[:benchs] || profiles
34
+ output = opts[:output] || $stderr
35
+
36
+ # search worst item
37
+ total = 0
38
+ worst = nil
39
+ benchs.each do |bench|
40
+ total += bench.time
41
+ worst = bench if !worst or bench.time > worst.time
42
+ end
43
+
44
+ benchs.each do |bench|
45
+ colorize = (bench == worst) ? :pink : :aqua
46
+ profiled = __send__(colorize, bench.profile(total))
47
+ if block
48
+ block.call(profiled)
49
+ else
50
+ output.puts profiled
51
+ end
52
+ end
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module Ccp
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
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(Ccp::Data::KVS) }
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
@@ -0,0 +1,85 @@
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
data/spec/data_spec.rb ADDED
@@ -0,0 +1,129 @@
1
+ require "spec_helper"
2
+
3
+ describe Ccp::Data::KVS do
4
+ ######################################################################
5
+ ### Accessor
6
+
7
+ it "should behave like hash" do
8
+ subject[:foo] = 1
9
+ subject[:foo].should == 1
10
+ end
11
+
12
+ describe "#[]" do
13
+ it "should raise NotDefined if no data exist for the key" do
14
+ lambda {
15
+ subject[:foo]
16
+ }.should raise_error(Ccp::Data::NotDefined)
17
+ end
18
+ end
19
+
20
+ describe "#[]=" do
21
+ it "can override values" do
22
+ subject[:foo] = 1
23
+ subject[:foo] = 2
24
+ subject[:foo].should == 2
25
+ end
26
+ end
27
+
28
+ ######################################################################
29
+ ### Testing
30
+
31
+ describe "#exist?" do
32
+ it "should return true if the value is set" do
33
+ subject[:foo] = 1
34
+ subject.exist?(:foo).should == true
35
+ end
36
+
37
+ it "should return false if the value is not set" do
38
+ subject.exist?(:foo).should == false
39
+ end
40
+ end
41
+
42
+ describe "#set?" do
43
+ it "should return true if the value is set and not (nil|false)" do
44
+ subject[:foo] = 0
45
+ subject.set?(:foo).should == true
46
+
47
+ subject.default[:bar] = 0
48
+ subject.set?(:bar).should == true
49
+
50
+ subject.default(:baz) { 0 }
51
+ subject.set?(:baz).should == true
52
+ end
53
+
54
+ it "should return false if the value is set but (nil|false)" do
55
+ subject[:foo] = nil
56
+ subject.set?(:foo).should == false
57
+
58
+ subject[:foo] = false
59
+ subject.set?(:foo).should == false
60
+ end
61
+ end
62
+
63
+ describe "#check" do
64
+ it "should satisfy its type" do
65
+ subject[:foo] = 1
66
+ lambda {
67
+ subject.check(:foo, Integer)
68
+ }.should_not raise_error
69
+ end
70
+
71
+ it "should satisfy its struct" do
72
+ subject[:foo] = {:a => "text"}
73
+ lambda {
74
+ subject.check(:foo, {Symbol => String})
75
+ }.should_not raise_error
76
+ end
77
+
78
+ it "should raise TypeError if not satisfied" do
79
+ subject[:foo] = {:a => "text"}
80
+ lambda {
81
+ subject.check(:foo, Integer)
82
+ }.should raise_error(TypeError)
83
+ end
84
+ end
85
+
86
+ ######################################################################
87
+ ### Default values
88
+
89
+ describe "#default" do
90
+ it "should set default value" do
91
+ subject.default[:foo] = 1
92
+ subject.exist?(:foo).should == true
93
+ subject[:foo].should == 1
94
+ end
95
+
96
+ it "should be overriden by []=" do
97
+ subject.default[:foo] = 1
98
+ subject[:foo] = 2
99
+ subject[:foo].should == 2
100
+ end
101
+
102
+ it "should not affect data when already set" do
103
+ subject[:foo] = 1
104
+ subject.default[:foo] = 2
105
+ subject[:foo].should == 1
106
+ end
107
+ end
108
+
109
+ describe "#default(&block)" do
110
+ it "should set lazy default value" do
111
+ @a = 1
112
+ subject.default(:foo) { @a }
113
+ @a = 2
114
+ subject[:foo].should == 2
115
+ end
116
+ end
117
+
118
+ ######################################################################
119
+ ### Utils
120
+
121
+ describe "#path" do
122
+ it "should return pathname" do
123
+ subject[:foo] = __FILE__
124
+ subject.path(:foo).should be_kind_of(Pathname)
125
+ subject.path(:foo).basename.should == Pathname("data_spec.rb")
126
+ end
127
+ end
128
+ end
129
+
@@ -0,0 +1,5 @@
1
+ # $:.unshift File.expand_path('..', __FILE__)
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ require 'rspec'
5
+ require 'ccp'
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ccp
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - maiha
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-02-09 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activesupport
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: must
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 29
44
+ segments:
45
+ - 0
46
+ - 2
47
+ - 5
48
+ version: 0.2.5
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: dsl_accessor
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 15
60
+ segments:
61
+ - 0
62
+ - 4
63
+ - 0
64
+ version: 0.4.0
65
+ type: :runtime
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: rspec
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id004
81
+ description: CCP
82
+ email:
83
+ - maiha@wota.jp
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files: []
89
+
90
+ files:
91
+ - .gitignore
92
+ - Gemfile
93
+ - README
94
+ - Rakefile
95
+ - ccp.gemspec
96
+ - lib/ccp.rb
97
+ - lib/ccp/colorize.rb
98
+ - lib/ccp/commands.rb
99
+ - lib/ccp/commands/command_not_found.rb
100
+ - lib/ccp/commands/commentable.rb
101
+ - lib/ccp/commands/composite.rb
102
+ - lib/ccp/commands/core.rb
103
+ - lib/ccp/commands/executable.rb
104
+ - lib/ccp/commands/receivable.rb
105
+ - lib/ccp/commands/resolvable.rb
106
+ - lib/ccp/commands/runtime_args.rb
107
+ - lib/ccp/data.rb
108
+ - lib/ccp/invokers.rb
109
+ - lib/ccp/invokers/base.rb
110
+ - lib/ccp/receivers.rb
111
+ - lib/ccp/receivers/base.rb
112
+ - lib/ccp/receivers/commentable.rb
113
+ - lib/ccp/receivers/none.rb
114
+ - lib/ccp/receivers/profileable.rb
115
+ - lib/ccp/version.rb
116
+ - spec/commands_spec.rb
117
+ - spec/composite_spec.rb
118
+ - spec/data_spec.rb
119
+ - spec/spec_helper.rb
120
+ has_rdoc: true
121
+ homepage: http://github.com/maiha/ccp
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options: []
126
+
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ hash: 3
144
+ segments:
145
+ - 0
146
+ version: "0"
147
+ requirements: []
148
+
149
+ rubyforge_project: ccp
150
+ rubygems_version: 1.3.7
151
+ signing_key:
152
+ specification_version: 3
153
+ summary: A Ruby library for Composite Command Programming
154
+ test_files: []
155
+