mr_darcy 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +95 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +267 -0
- data/Rakefile +6 -0
- data/lib/mr_darcy/context.rb +71 -0
- data/lib/mr_darcy/deferred.rb +25 -0
- data/lib/mr_darcy/drivers/celluloid.rb +23 -0
- data/lib/mr_darcy/drivers/synchronous.rb +15 -0
- data/lib/mr_darcy/drivers/thread.rb +22 -0
- data/lib/mr_darcy/drivers.rb +13 -0
- data/lib/mr_darcy/promise/base.rb +117 -0
- data/lib/mr_darcy/promise/celluloid.rb +52 -0
- data/lib/mr_darcy/promise/child_promise.rb +83 -0
- data/lib/mr_darcy/promise/dsl.rb +29 -0
- data/lib/mr_darcy/promise/em.rb +29 -0
- data/lib/mr_darcy/promise/state/base.rb +43 -0
- data/lib/mr_darcy/promise/state/rejected.rb +11 -0
- data/lib/mr_darcy/promise/state/resolved.rb +11 -0
- data/lib/mr_darcy/promise/state/unresolved.rb +19 -0
- data/lib/mr_darcy/promise/state.rb +25 -0
- data/lib/mr_darcy/promise/synchronous.rb +27 -0
- data/lib/mr_darcy/promise/thread.rb +64 -0
- data/lib/mr_darcy/promise.rb +31 -0
- data/lib/mr_darcy/role.rb +45 -0
- data/lib/mr_darcy/version.rb +3 -0
- data/lib/mr_darcy.rb +26 -0
- data/mr_darcy.gemspec +29 -0
- data/spec/acceptance/dci_bank_transfer_spec.rb +62 -0
- data/spec/acceptance/em_http_request_spec.rb +22 -0
- data/spec/acceptance/open-uri_http_request_spec.rb +21 -0
- data/spec/acceptance/simple_promise_spec.rb +25 -0
- data/spec/acceptance/simple_promise_with_chained_fail.rb +25 -0
- data/spec/acceptance/simple_promise_with_fail_spec.rb +25 -0
- data/spec/acceptance/simple_promise_with_then_spec.rb +25 -0
- data/spec/lib/mr_darcy/context_spec.rb +22 -0
- data/spec/lib/mr_darcy/promise/base_spec.rb +197 -0
- data/spec/lib/mr_darcy/promise/child_promise_spec.rb +169 -0
- data/spec/lib/mr_darcy/promise/dsl_spec.rb +43 -0
- data/spec/lib/mr_darcy/promise/state/base_spec.rb +24 -0
- data/spec/lib/mr_darcy/promise/state/rejected_spec.rb +12 -0
- data/spec/lib/mr_darcy/promise/state/resolved_spec.rb +12 -0
- data/spec/lib/mr_darcy/promise/state/unresolved_spec.rb +22 -0
- data/spec/lib/mr_darcy/promise/state_spec.rb +30 -0
- data/spec/lib/mr_darcy/promise/synchronous_spec.rb +21 -0
- data/spec/lib/mr_darcy/promise_spec.rb +72 -0
- data/spec/lib/mr_darcy/role_spec.rb +89 -0
- data/spec/lib/mr_darcy_spec.rb +19 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/context_helpers.rb +19 -0
- data/spec/support/shared_examples_for_promise.rb +47 -0
- data/spec/support/shared_examples_for_thennable.rb +10 -0
- metadata +279 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def initialize block
|
6
|
+
state
|
7
|
+
schedule_promise do
|
8
|
+
evaluate_promise &block
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def then &block
|
13
|
+
@child_promise ||= generate_child_promise
|
14
|
+
child_promise.resolve_block = block
|
15
|
+
resolve_child_promise if resolved?
|
16
|
+
reject_child_promise if rejected?
|
17
|
+
child_promise.promise
|
18
|
+
end
|
19
|
+
|
20
|
+
def fail &block
|
21
|
+
@child_promise ||= generate_child_promise
|
22
|
+
child_promise.reject_block = block
|
23
|
+
resolve_child_promise if resolved?
|
24
|
+
reject_child_promise if rejected?
|
25
|
+
child_promise.promise
|
26
|
+
end
|
27
|
+
|
28
|
+
def result
|
29
|
+
Kernel::raise "Subclasses must implement me"
|
30
|
+
end
|
31
|
+
|
32
|
+
def final
|
33
|
+
Kernel::raise "Subclasses must implement me"
|
34
|
+
end
|
35
|
+
|
36
|
+
def raise
|
37
|
+
r = result
|
38
|
+
Kernel::raise r if rejected?
|
39
|
+
end
|
40
|
+
|
41
|
+
%w| resolved? unresolved? rejected? |.map(&:to_sym).each do |method|
|
42
|
+
define_method method do |*args|
|
43
|
+
state_machine.public_send(method, *args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def resolve value
|
48
|
+
set_value_to value
|
49
|
+
state_machine_resolve
|
50
|
+
resolve_child_promise
|
51
|
+
end
|
52
|
+
|
53
|
+
def reject exception
|
54
|
+
set_value_to exception
|
55
|
+
state_machine_reject
|
56
|
+
reject_child_promise
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_accessor :value, :child_promise, :state
|
62
|
+
|
63
|
+
def state
|
64
|
+
@state ||= :unresolved
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_value_to value
|
68
|
+
@value = value
|
69
|
+
end
|
70
|
+
|
71
|
+
def state_machine_resolve
|
72
|
+
state_machine.resolve
|
73
|
+
end
|
74
|
+
|
75
|
+
def state_machine_reject
|
76
|
+
state_machine.reject
|
77
|
+
end
|
78
|
+
|
79
|
+
def state_machine
|
80
|
+
State.state(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
def has_child_promise?
|
84
|
+
!!child_promise
|
85
|
+
end
|
86
|
+
|
87
|
+
def resolve_child_promise
|
88
|
+
schedule_promise do
|
89
|
+
child_promise.parent_resolved(value) if has_child_promise?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def reject_child_promise
|
94
|
+
schedule_promise do
|
95
|
+
child_promise.parent_rejected(value) if has_child_promise?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def schedule_promise
|
100
|
+
Kernel::raise "Subclasses must implement me"
|
101
|
+
end
|
102
|
+
|
103
|
+
def evaluate_promise &block
|
104
|
+
begin
|
105
|
+
block.call DSL.new(self)
|
106
|
+
rescue Exception => e
|
107
|
+
reject e
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def generate_child_promise
|
112
|
+
Kernel::raise "Subclasses must implement me"
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'celluloid/autostart'
|
2
|
+
|
3
|
+
module MrDarcy
|
4
|
+
module Promise
|
5
|
+
class Celluloid < Base
|
6
|
+
|
7
|
+
def initialize *args
|
8
|
+
@waiting = false
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def resolve value
|
13
|
+
super
|
14
|
+
condition.signal if @waiting
|
15
|
+
end
|
16
|
+
|
17
|
+
def reject exception
|
18
|
+
super
|
19
|
+
condition.signal if @waiting
|
20
|
+
end
|
21
|
+
|
22
|
+
def result
|
23
|
+
wait_until_not_unresolved
|
24
|
+
value
|
25
|
+
end
|
26
|
+
|
27
|
+
def final
|
28
|
+
wait_until_not_unresolved
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def schedule_promise &block
|
35
|
+
::Celluloid::Future.new &block
|
36
|
+
end
|
37
|
+
|
38
|
+
def condition
|
39
|
+
@condition ||= ::Celluloid::Condition.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def wait_until_not_unresolved
|
43
|
+
@waiting = true
|
44
|
+
condition.wait if unresolved?
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_child_promise
|
48
|
+
ChildPromise.new driver: :thread
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
class ChildPromise < MrDarcy::Deferred
|
4
|
+
|
5
|
+
attr_accessor :resolve_block, :reject_block
|
6
|
+
|
7
|
+
def initialize opts={}
|
8
|
+
@driver = opts[:driver] if opts.has_key? :driver
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def parent_resolved value
|
13
|
+
begin
|
14
|
+
return resolve_with value unless handles_resolve?
|
15
|
+
new_value = result_for :resolve, value
|
16
|
+
if thenable? new_value
|
17
|
+
defer_resolution_via new_value
|
18
|
+
else
|
19
|
+
resolve_with new_value
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
reject_with e
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def parent_rejected value
|
27
|
+
begin
|
28
|
+
return reject_with value unless handles_reject?
|
29
|
+
new_value = result_for :reject, value
|
30
|
+
if thenable? new_value
|
31
|
+
defer_resolution_via new_value
|
32
|
+
else
|
33
|
+
resolve_with new_value
|
34
|
+
end
|
35
|
+
rescue Exception => e
|
36
|
+
reject_with e
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def result_for which, value
|
43
|
+
block = public_send("#{which}_block")
|
44
|
+
if block
|
45
|
+
block.call value
|
46
|
+
else
|
47
|
+
value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def handles_reject?
|
52
|
+
!!reject_block
|
53
|
+
end
|
54
|
+
|
55
|
+
def handles_resolve?
|
56
|
+
!!resolve_block
|
57
|
+
end
|
58
|
+
|
59
|
+
def thenable? object
|
60
|
+
object.respond_to?(:then) && object.respond_to?(:fail)
|
61
|
+
end
|
62
|
+
|
63
|
+
def defer_resolution_via child_promise
|
64
|
+
child_promise.then do |value|
|
65
|
+
resolve_with value
|
66
|
+
value
|
67
|
+
end
|
68
|
+
child_promise.fail do |exception|
|
69
|
+
reject_with exception
|
70
|
+
exception
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def resolve_with value
|
75
|
+
promise.resolve value
|
76
|
+
end
|
77
|
+
|
78
|
+
def reject_with exception
|
79
|
+
promise.reject exception
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
class DSL
|
4
|
+
|
5
|
+
def initialize promise
|
6
|
+
@promise = promise
|
7
|
+
end
|
8
|
+
|
9
|
+
def resolve(value)
|
10
|
+
promise.resolve value
|
11
|
+
end
|
12
|
+
|
13
|
+
def reject(exception)
|
14
|
+
promise.reject exception
|
15
|
+
end
|
16
|
+
|
17
|
+
%w| unresolved? resolved? rejected? then fail result final |.map(&:to_sym).each do |method|
|
18
|
+
define_method method do |*args|
|
19
|
+
promise.public_send method, *args
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_accessor :promise
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
module MrDarcy
|
4
|
+
module Promise
|
5
|
+
class EM < Thread
|
6
|
+
|
7
|
+
def initialize *args
|
8
|
+
unless EventMachine.reactor_running?
|
9
|
+
::Thread.new { EventMachine.run }
|
10
|
+
::Thread.pass until EventMachine.reactor_running?
|
11
|
+
end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def schedule_promise
|
18
|
+
EventMachine.schedule proc do
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_child_promise
|
24
|
+
ChildPromise.new driver: :em
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
module State
|
4
|
+
class Base
|
5
|
+
attr_accessor :stateful
|
6
|
+
|
7
|
+
def initialize stateful
|
8
|
+
self.stateful = stateful
|
9
|
+
end
|
10
|
+
|
11
|
+
def unresolved?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolved?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def rejected?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def resolve
|
24
|
+
raise "Can't resolve from #{get_state} state"
|
25
|
+
end
|
26
|
+
|
27
|
+
def reject
|
28
|
+
raise "Cant reject from #{get_state} state"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def get_state
|
34
|
+
stateful.send :state
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_state state
|
38
|
+
stateful.send :state=, state
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
module State
|
4
|
+
autoload :Base, File.expand_path('../state/base', __FILE__)
|
5
|
+
autoload :Unresolved, File.expand_path('../state/unresolved', __FILE__)
|
6
|
+
autoload :Resolved, File.expand_path('../state/resolved', __FILE__)
|
7
|
+
autoload :Rejected, File.expand_path('../state/rejected', __FILE__)
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def state stateful
|
12
|
+
case stateful.send :state
|
13
|
+
when :unresolved
|
14
|
+
Unresolved.new stateful
|
15
|
+
when :resolved
|
16
|
+
Resolved.new stateful
|
17
|
+
when :rejected
|
18
|
+
Rejected.new stateful
|
19
|
+
else
|
20
|
+
raise "Unknown state #{stateful.state}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This class implements a synchronous interface to promise execution.
|
2
|
+
# It's not much use, except for unit testing.
|
3
|
+
|
4
|
+
module MrDarcy
|
5
|
+
module Promise
|
6
|
+
class Synchronous < Base
|
7
|
+
|
8
|
+
def result
|
9
|
+
value
|
10
|
+
end
|
11
|
+
|
12
|
+
def final
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def schedule_promise
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_child_promise
|
23
|
+
ChildPromise.new driver: :synchronous
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
class Thread < Base
|
4
|
+
|
5
|
+
def initialize *args
|
6
|
+
@wait_lock = Mutex.new
|
7
|
+
@wait_cond = ConditionVariable.new
|
8
|
+
@wait_lock.lock
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def result
|
13
|
+
wait_if_unresolved
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
def final
|
18
|
+
wait_if_unresolved
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def resolve value
|
23
|
+
super
|
24
|
+
@wait_cond.signal
|
25
|
+
end
|
26
|
+
|
27
|
+
def reject value
|
28
|
+
super
|
29
|
+
@wait_cond.signal
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def schedule_promise &block
|
35
|
+
::Thread.new &block
|
36
|
+
end
|
37
|
+
|
38
|
+
def wait_if_unresolved
|
39
|
+
@wait_cond.wait @wait_lock if unresolved?
|
40
|
+
end
|
41
|
+
|
42
|
+
def semaphore
|
43
|
+
@semaphore ||= Mutex.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_child_promise
|
47
|
+
ChildPromise.new driver: :thread
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_value_to value
|
51
|
+
semaphore.synchronize { super }
|
52
|
+
end
|
53
|
+
|
54
|
+
def state_machine_resolve
|
55
|
+
semaphore.synchronize { super }
|
56
|
+
end
|
57
|
+
|
58
|
+
def state_machine_reject
|
59
|
+
semaphore.synchronize { super }
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
module Promise
|
3
|
+
autoload :State, File.expand_path('../promise/state', __FILE__)
|
4
|
+
autoload :Base, File.expand_path('../promise/base', __FILE__)
|
5
|
+
autoload :DSL, File.expand_path('../promise/dsl', __FILE__)
|
6
|
+
autoload :ChildPromise, File.expand_path('../promise/child_promise', __FILE__)
|
7
|
+
|
8
|
+
autoload :Synchronous, File.expand_path('../promise/synchronous', __FILE__)
|
9
|
+
autoload :Thread, File.expand_path('../promise/thread', __FILE__)
|
10
|
+
autoload :Celluloid, File.expand_path('../promise/celluloid', __FILE__)
|
11
|
+
autoload :EM, File.expand_path('../promise/em', __FILE__)
|
12
|
+
|
13
|
+
module_function
|
14
|
+
|
15
|
+
def new driver: ::MrDarcy.driver, &block
|
16
|
+
case driver
|
17
|
+
when :thread, :Thread
|
18
|
+
::MrDarcy::Promise::Thread.new block
|
19
|
+
when :synchronous, :Synchronous
|
20
|
+
::MrDarcy::Promise::Synchronous.new block
|
21
|
+
when :celluloid, :Celluloid
|
22
|
+
::MrDarcy::Promise::Celluloid.new block
|
23
|
+
when :em, :EM, :event_machine, :eventmachine, :EventMachine
|
24
|
+
::MrDarcy::Promise::EM.new block
|
25
|
+
else
|
26
|
+
raise "Unknown driver #{driver}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module MrDarcy
|
2
|
+
class Role
|
3
|
+
attr_accessor :name, :options
|
4
|
+
|
5
|
+
def initialize name, opts={}, &block
|
6
|
+
self.name = name
|
7
|
+
self.options = opts
|
8
|
+
@module = Module.new(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def pollute player
|
12
|
+
guard_against_false_players player
|
13
|
+
|
14
|
+
@module.instance_methods.each do |method_name|
|
15
|
+
implementation = @module.instance_method method_name
|
16
|
+
player.define_singleton_method method_name, implementation
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def clean player
|
21
|
+
@module.instance_methods.each do |method_name|
|
22
|
+
player.singleton_class.send :remove_method, method_name if player.respond_to? method_name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def guard_against_false_players player
|
29
|
+
options.each do |test_type, values|
|
30
|
+
case test_type
|
31
|
+
when :must_respond_to
|
32
|
+
Array(values).each do |method_name|
|
33
|
+
raise ArgumentError, "player must implement #{method_name}" unless player.respond_to? method_name
|
34
|
+
end
|
35
|
+
when :must_not_respond_to
|
36
|
+
Array(values).each do |method_name|
|
37
|
+
raise ArgumentError, "player must not implement #{method_name}" if player.respond_to? method_name
|
38
|
+
end
|
39
|
+
else
|
40
|
+
raise ArgumentError, "unknown restriction #{test_type}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/mr_darcy.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "mr_darcy/version"
|
2
|
+
require "mr_darcy/role"
|
3
|
+
require "mr_darcy/context"
|
4
|
+
require "mr_darcy/deferred"
|
5
|
+
require "mr_darcy/promise"
|
6
|
+
|
7
|
+
module MrDarcy
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def driver=(driver)
|
12
|
+
@driver=driver
|
13
|
+
end
|
14
|
+
|
15
|
+
def driver
|
16
|
+
@driver ||= :Thread
|
17
|
+
end
|
18
|
+
|
19
|
+
def all_drivers
|
20
|
+
%w| synchronous thread celluloid em |.map(&:to_sym)
|
21
|
+
end
|
22
|
+
|
23
|
+
def promise driver: driver, &block
|
24
|
+
MrDarcy::Promise.new driver: driver, &block
|
25
|
+
end
|
26
|
+
end
|
data/mr_darcy.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mr_darcy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mr_darcy"
|
8
|
+
spec.version = MrDarcy::VERSION
|
9
|
+
spec.authors = ["James Harton"]
|
10
|
+
spec.email = ["james@resistor.io"]
|
11
|
+
spec.summary = %q{A mashup of async Promises and DCI in Ruby.}
|
12
|
+
spec.description = <<-EOF
|
13
|
+
MrDarcy takes async promises from the javascript word, DCI from Jim
|
14
|
+
Gay's brain and sprinkles some ruby on top for great justice!
|
15
|
+
EOF
|
16
|
+
spec.homepage = "https://github.com/jamesotron/MrDarcy"
|
17
|
+
spec.license = "MIT"
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
25
|
+
%w| rake rspec guard guard-rspec guard-bundler terminal-notifier-guard
|
26
|
+
pry eventmachine em-http-request celluloid |.each do |gem|
|
27
|
+
spec.add_development_dependency gem
|
28
|
+
end
|
29
|
+
end
|