deterministic 0.0.1 → 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 +4 -4
- data/.rspec +2 -0
- data/Guardfile +15 -0
- data/README.md +76 -5
- data/deterministic.gemspec +5 -0
- data/lib/deterministic/either/attempt_all.rb +42 -0
- data/lib/deterministic/either/failure.rb +3 -0
- data/lib/deterministic/either/match.rb +44 -0
- data/lib/deterministic/either/success.rb +3 -0
- data/lib/deterministic/either.rb +58 -0
- data/lib/deterministic/version.rb +1 -1
- data/lib/deterministic.rb +7 -3
- data/spec/lib/deterministic/attempt_all_spec.rb +98 -0
- data/spec/lib/deterministic/either/match_spec.rb +54 -0
- data/spec/lib/deterministic/either/success_spec.rb +27 -0
- data/spec/spec_helper.rb +23 -0
- metadata +88 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 925b4c6bf8684358c92969bd99bfaae834ecc96d
|
4
|
+
data.tar.gz: b9e69ef69dbd5fe6e050265d41a39375471b4acc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1d622aec6a69088627ab300883863815e85b7f67b4080072271644aaba31591942f2d23249751047f5d25e850a933414804a59641bb216a3e572a817aebde75
|
7
|
+
data.tar.gz: 9637ca25bc179cfc53464b618e3c8e09332bd3e52085a1c750aaf2715feea65c5ccd701be4cf5388f334f5835007b532ff5f87d8b8edd142592e59bf3656f9a0
|
data/.rspec
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
guard :bundler do
|
2
|
+
watch('Gemfile')
|
3
|
+
watch(/^.+\.gemspec/)
|
4
|
+
end
|
5
|
+
|
6
|
+
guard :rspec do
|
7
|
+
watch(%r{^spec/.+_spec\.rb$})
|
8
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
9
|
+
watch('spec/spec_helper.rb') { "spec" }
|
10
|
+
|
11
|
+
# Turnip features and steps
|
12
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
13
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
14
|
+
end
|
15
|
+
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# Deterministic
|
2
2
|
|
3
|
-
|
3
|
+
This is a spiritual successor of the [Monadic gem](http://github.com/pzol/monadic)
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
gem '
|
9
|
+
gem 'deterministic'
|
10
10
|
|
11
11
|
And then execute:
|
12
12
|
|
@@ -14,11 +14,77 @@ And then execute:
|
|
14
14
|
|
15
15
|
Or install it yourself as:
|
16
16
|
|
17
|
-
$ gem install
|
17
|
+
$ gem install deterministic
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
### Either#attempt_all
|
22
|
+
The basic idea is to execute a chain of units of work and make sure all return either `Success` or `Failure`.
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
Either.attempt_all do
|
26
|
+
try { 1 }
|
27
|
+
try { |prev| prev + 1 }
|
28
|
+
end # => Success(2)
|
29
|
+
```
|
30
|
+
Take notice, that the result of of unit of work will be passed to the next one. So the result of prepare_somehing will be something in the second try.
|
31
|
+
|
32
|
+
If any of the units of work in between fail, the rest will not be executed and the last `Failure` will be returned.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
Either.attempt_all do
|
36
|
+
try { 1 }
|
37
|
+
try { raise "error" }
|
38
|
+
try { 2 }
|
39
|
+
end # => Failure(RuntimeError("error"))
|
40
|
+
```
|
41
|
+
|
42
|
+
However, the real fun starts if you use it with your own context. You can use this as a state container (meh!) or to pass a dependency locator:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
class Context
|
46
|
+
attr_accessor :env, :settings
|
47
|
+
def some_service
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# exemplary unit of work
|
52
|
+
module LoadSettings
|
53
|
+
def self.call(env)
|
54
|
+
settings = load(env)
|
55
|
+
settings.nil? ? Failure('could not load settings') : Success(settings)
|
56
|
+
end
|
57
|
+
|
58
|
+
def load(env)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Either.attempt_all(context) do
|
63
|
+
# this unit of work explicitly returns success or failure
|
64
|
+
# no exceptions are catched and if they occur, well, they behave as expected
|
65
|
+
# methods from the context can be accessed, the use of self for setters is necessary
|
66
|
+
let { self.settings = LoadSettings.call(env) }
|
67
|
+
|
68
|
+
# with #try all exceptions will be transformed into a Failure
|
69
|
+
try { do_something }
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
### Pattern matching
|
74
|
+
Now that you have some result, you want to control flow by providing patterns.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
Success(1).match do
|
78
|
+
success { |v| "success #{v}"}
|
79
|
+
failure { |v| "failure #{v}"}
|
80
|
+
either { |v| "either #{v}"}
|
81
|
+
end # => "either 1"
|
82
|
+
```
|
83
|
+
Note: the inner value has been unwrapped!
|
84
|
+
|
85
|
+
Note2: only the last matching pattern block will be executed
|
86
|
+
|
87
|
+
The result returned will be the result of the last `#try` or `#let`
|
22
88
|
|
23
89
|
## Contributing
|
24
90
|
|
@@ -27,3 +93,8 @@ TODO: Write usage instructions here
|
|
27
93
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
94
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
95
|
5. Create new Pull Request
|
96
|
+
|
97
|
+
## Inspirations
|
98
|
+
* My [Monadic gem](http://github.com/pzol/monadic) of course
|
99
|
+
* `#attempt_all` was somewhat inspired by [An error monad in Clojure](http://brehaut.net/blog/2011/error_monads)
|
100
|
+
* [Pithyless' rumblings](https://gist.github.com/pithyless/2216519)
|
data/deterministic.gemspec
CHANGED
@@ -20,4 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "guard"
|
25
|
+
spec.add_development_dependency "guard-bundler"
|
26
|
+
spec.add_development_dependency "guard-rspec"
|
27
|
+
spec.add_development_dependency "simplecov"
|
23
28
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
module Deterministic::Either
|
3
|
+
def self.attempt_all(context=OpenStruct.new, &block)
|
4
|
+
AttemptAll.new(context, &block).call
|
5
|
+
end
|
6
|
+
|
7
|
+
class AttemptAll
|
8
|
+
class EitherExpectedError < StandardError; end
|
9
|
+
def initialize(context, &block)
|
10
|
+
@context = context || self
|
11
|
+
@tries = []
|
12
|
+
instance_eval(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(initial=nil)
|
16
|
+
result = @tries.inject(Success(initial)) do |acc, try|
|
17
|
+
acc.success? ? acc.bind(try.call(acc)) : acc
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def try(&block)
|
22
|
+
try_p = ->(acc) {
|
23
|
+
begin
|
24
|
+
value = @context.instance_exec(acc.value, &block)
|
25
|
+
Success(value)
|
26
|
+
rescue => ex
|
27
|
+
Failure(ex)
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
@tries << try_p
|
32
|
+
end
|
33
|
+
|
34
|
+
def let(sym=nil, &block)
|
35
|
+
@tries << ->(acc) {
|
36
|
+
@context.instance_exec(acc, &block).tap do |value|
|
37
|
+
raise EitherExpectedError unless value.is_a? Either
|
38
|
+
end
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Deterministic::Either
|
2
|
+
def match(proc=nil, &block)
|
3
|
+
match = Match.new(self)
|
4
|
+
match.instance_eval &(proc || block)
|
5
|
+
match.result
|
6
|
+
end
|
7
|
+
|
8
|
+
class Match
|
9
|
+
def initialize(either)
|
10
|
+
@either = either
|
11
|
+
@collection = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def success(value=nil, &block)
|
15
|
+
q(:success, value, block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure(value=nil, &block)
|
19
|
+
q(:failure, value, block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def either(value=nil, &block)
|
23
|
+
q(:either, value, block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def result
|
27
|
+
matcher = @collection.select { |m| m.first.call(@either.value) }.last
|
28
|
+
matcher.last.call(@either.value)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def q(type, condition, block)
|
33
|
+
if condition.nil?
|
34
|
+
condition_p = ->(v) { true }
|
35
|
+
elsif condition.is_a?(Proc)
|
36
|
+
condition_p = condition
|
37
|
+
else
|
38
|
+
condition_p = ->(v) { condition == @either.value }
|
39
|
+
end
|
40
|
+
|
41
|
+
@collection << [condition_p, block] if @either.is? type
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Deterministic::Either
|
2
|
+
def Success(value)
|
3
|
+
Success.unit(value)
|
4
|
+
end
|
5
|
+
|
6
|
+
def Failure(value)
|
7
|
+
Failure.unit(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
class Either
|
11
|
+
def self.unit(value)
|
12
|
+
return value if value.is_a? Either
|
13
|
+
# return Failure.new(value) if value.nil? || (value.respond_to?(:empty?) && value.empty?) || !value
|
14
|
+
# return Success.new(value)
|
15
|
+
return new(value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def is?(s)
|
19
|
+
const_name = s.slice(0,1).capitalize + s.slice(1..-1)
|
20
|
+
is_a? Module.const_get(const_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def success?
|
24
|
+
is_a? Success
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure?
|
28
|
+
is_a? Failure
|
29
|
+
end
|
30
|
+
|
31
|
+
def bind(other)
|
32
|
+
return self if failure?
|
33
|
+
return other if other.is_a? Either
|
34
|
+
# return concat(proc) if proc.is_a? Either
|
35
|
+
|
36
|
+
# begin
|
37
|
+
# Either(call(proc, block))
|
38
|
+
# rescue StandardError => error
|
39
|
+
# Failure(error)
|
40
|
+
# end
|
41
|
+
end
|
42
|
+
|
43
|
+
# get the underlying value
|
44
|
+
def value
|
45
|
+
@value
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(other)
|
49
|
+
return false unless other.is_a? self.class
|
50
|
+
@value == other.instance_variable_get(:@value)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def initialize(value)
|
55
|
+
@value = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/deterministic.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require "deterministic/version"
|
2
2
|
|
3
|
-
module Deterministic
|
4
|
-
|
5
|
-
|
3
|
+
module Deterministic; end
|
4
|
+
|
5
|
+
require 'deterministic/either'
|
6
|
+
require 'deterministic/either/match'
|
7
|
+
require 'deterministic/either/attempt_all'
|
8
|
+
require 'deterministic/either/success'
|
9
|
+
require 'deterministic/either/failure'
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'deterministic'
|
3
|
+
|
4
|
+
include Deterministic::Either
|
5
|
+
include Deterministic
|
6
|
+
|
7
|
+
describe Deterministic::Either::AttemptAll do
|
8
|
+
it "#try evaluates the result as Success" do
|
9
|
+
expect(
|
10
|
+
Either.attempt_all do
|
11
|
+
try { @a = 1 }
|
12
|
+
try { @b = @a + 1 }
|
13
|
+
end
|
14
|
+
).to eq Success(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "#try values are passed to the next command" do
|
18
|
+
expect(
|
19
|
+
Either.attempt_all do
|
20
|
+
try { 1 }
|
21
|
+
try { |v| v + 1 }
|
22
|
+
end
|
23
|
+
).to eq Success(2)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "try treat exceptions as Failure" do
|
27
|
+
attempt = Either.attempt_all do
|
28
|
+
try { 1 }
|
29
|
+
try { raise "error" }
|
30
|
+
end.value
|
31
|
+
expect(attempt).to be_a RuntimeError
|
32
|
+
expect(attempt.message).to eq "error"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "don't continue on failure" do
|
36
|
+
fake = double()
|
37
|
+
expect(
|
38
|
+
Either.attempt_all do
|
39
|
+
try { 1 }
|
40
|
+
let { Failure(2) }
|
41
|
+
try { fake.should_not_be_called }
|
42
|
+
end
|
43
|
+
).to eq Failure(2)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "#let expects Success or Failure" do
|
47
|
+
expect(
|
48
|
+
Either.attempt_all do
|
49
|
+
let { Success(1) }
|
50
|
+
end
|
51
|
+
).to eq Success(1)
|
52
|
+
|
53
|
+
expect {
|
54
|
+
Either.attempt_all do
|
55
|
+
let { 1 }
|
56
|
+
end
|
57
|
+
}.to raise_error(Deterministic::Either::AttemptAll::EitherExpectedError)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "#let will not catch errors" do
|
61
|
+
expect {
|
62
|
+
Either.attempt_all do
|
63
|
+
let { raise "error" }
|
64
|
+
end
|
65
|
+
}.to raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
it "works with an OpenStruct" do
|
69
|
+
context = OpenStruct.new
|
70
|
+
attempt = Either.attempt_all(context) do
|
71
|
+
let { Success(self.alpha = 2) }
|
72
|
+
try { self.res = 1 }
|
73
|
+
end
|
74
|
+
|
75
|
+
expect(context.res).to eq 1
|
76
|
+
expect(context.alpha).to eq 2
|
77
|
+
end
|
78
|
+
|
79
|
+
it "can operate in the context of a host" do
|
80
|
+
class Host
|
81
|
+
attr_accessor :a
|
82
|
+
def initialize
|
83
|
+
@a = 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
host = Host.new
|
88
|
+
|
89
|
+
expect(
|
90
|
+
Either.attempt_all(host) do
|
91
|
+
try { self.a += 1 }
|
92
|
+
try { self.a + 1 }
|
93
|
+
end
|
94
|
+
).to eq Success(3)
|
95
|
+
|
96
|
+
expect(host.a).to eq 2
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'deterministic'
|
3
|
+
|
4
|
+
include Deterministic::Either
|
5
|
+
|
6
|
+
describe Deterministic::Either::Match do
|
7
|
+
it "can match Success" do
|
8
|
+
expect(
|
9
|
+
Success(1).match do
|
10
|
+
success { |v| "Success #{v}" }
|
11
|
+
failure { |v| "Failure #{v}" }
|
12
|
+
end
|
13
|
+
).to eq "Success 1"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can match Failure" do
|
17
|
+
expect(
|
18
|
+
Failure(1).match do
|
19
|
+
success { |v| "Success #{v}" }
|
20
|
+
failure { |v| "Failure #{v}" }
|
21
|
+
end
|
22
|
+
).to eq "Failure 1"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "can match with values" do
|
26
|
+
expect(
|
27
|
+
Failure(2).match do
|
28
|
+
success { |v| "not matched s" }
|
29
|
+
success(1) { |v| "not matched s1" }
|
30
|
+
failure(1) { |v| "not matched f1" }
|
31
|
+
failure(2) { |v| "matched #{v}" }
|
32
|
+
failure(3) { |v| "not matched f3" }
|
33
|
+
end
|
34
|
+
).to eq "matched 2"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can match either" do
|
38
|
+
expect(
|
39
|
+
Failure(2).match do
|
40
|
+
success { |v| "not matched s" }
|
41
|
+
either(2) { |v| "either #{v}" }
|
42
|
+
failure(3) { |v| "not matched f3" }
|
43
|
+
end
|
44
|
+
).to eq "either 2"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "can mach with lambdas" do
|
48
|
+
expect(
|
49
|
+
Success(1).match do
|
50
|
+
success ->(v) { v == 1 } { |v| "matched #{v}" }
|
51
|
+
end
|
52
|
+
).to eq "matched 1"
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'deterministic'
|
3
|
+
|
4
|
+
include Deterministic::Either
|
5
|
+
|
6
|
+
describe Deterministic::Either::Success do
|
7
|
+
subject { described_class.unit(1) }
|
8
|
+
|
9
|
+
specify { expect(subject).to be_an_instance_of described_class }
|
10
|
+
specify { expect(subject.value).to eq 1 }
|
11
|
+
specify { expect(subject).to be_success }
|
12
|
+
specify { expect(subject).not_to be_failure }
|
13
|
+
|
14
|
+
# public constructor #Success[]
|
15
|
+
specify { expect(described_class.unit(1)).to be_an_instance_of described_class }
|
16
|
+
specify { expect(subject).to eq(described_class.unit(1))}
|
17
|
+
|
18
|
+
it "handles chaining using &" do
|
19
|
+
expect(Success(1).bind Success(2)).to eq(Success(2))
|
20
|
+
expect(Success(1).bind Failure(2)).to eq(Failure(2))
|
21
|
+
end
|
22
|
+
|
23
|
+
specify { expect(Success(Success(1))).to eq Success(1) }
|
24
|
+
specify { expect(Success(1).is? :success).to be true }
|
25
|
+
specify { expect(Success(1).is? :either).to be true }
|
26
|
+
specify { expect(Success(1).is? :failure).to be false }
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Limit the spec run to only specs with the focus metadata. If no specs have
|
6
|
+
# the filtering metadata and `run_all_when_everything_filtered = true` then
|
7
|
+
# all specs will run.
|
8
|
+
config.filter_run :focus
|
9
|
+
|
10
|
+
# Run all specs when none match the provided filter. This works well in
|
11
|
+
# conjunction with `config.filter_run :focus`, as it will run the entire
|
12
|
+
# suite when no specs have `:filter` metadata.
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
|
15
|
+
# Run specs in random order to surface order dependencies. If you find an
|
16
|
+
# order dependency and want to debug it, you can fix the order by providing
|
17
|
+
# the seed, which is printed after each run.
|
18
|
+
# --seed 1234
|
19
|
+
config.expect_with :rspec do |c|
|
20
|
+
c.syntax = :expect
|
21
|
+
end
|
22
|
+
config.order = 'random'
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deterministic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Zolnierek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,76 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
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: guard
|
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: guard-bundler
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
41
111
|
description: A gem providing failsafe flow
|
42
112
|
email:
|
43
113
|
- pz@anixe.pl
|
@@ -46,14 +116,25 @@ extensions: []
|
|
46
116
|
extra_rdoc_files: []
|
47
117
|
files:
|
48
118
|
- .gitignore
|
119
|
+
- .rspec
|
49
120
|
- Gemfile
|
121
|
+
- Guardfile
|
50
122
|
- LICENSE.txt
|
51
123
|
- README.md
|
52
124
|
- Rakefile
|
53
125
|
- deterministic.gemspec
|
54
126
|
- either.rb
|
55
127
|
- lib/deterministic.rb
|
128
|
+
- lib/deterministic/either.rb
|
129
|
+
- lib/deterministic/either/attempt_all.rb
|
130
|
+
- lib/deterministic/either/failure.rb
|
131
|
+
- lib/deterministic/either/match.rb
|
132
|
+
- lib/deterministic/either/success.rb
|
56
133
|
- lib/deterministic/version.rb
|
134
|
+
- spec/lib/deterministic/attempt_all_spec.rb
|
135
|
+
- spec/lib/deterministic/either/match_spec.rb
|
136
|
+
- spec/lib/deterministic/either/success_spec.rb
|
137
|
+
- spec/spec_helper.rb
|
57
138
|
homepage: http://github.com/pzol/deterministic
|
58
139
|
licenses:
|
59
140
|
- MIT
|
@@ -78,4 +159,8 @@ rubygems_version: 2.0.14
|
|
78
159
|
signing_key:
|
79
160
|
specification_version: 4
|
80
161
|
summary: see above
|
81
|
-
test_files:
|
162
|
+
test_files:
|
163
|
+
- spec/lib/deterministic/attempt_all_spec.rb
|
164
|
+
- spec/lib/deterministic/either/match_spec.rb
|
165
|
+
- spec/lib/deterministic/either/success_spec.rb
|
166
|
+
- spec/spec_helper.rb
|