fear 0.0.1

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.
@@ -0,0 +1,79 @@
1
+ RSpec.describe Fear::Left do
2
+ include Fear::Either::Mixin
3
+
4
+ it_behaves_like Fear::RightBiased::Left do
5
+ let(:left) { described_class.new('value') }
6
+ end
7
+
8
+ describe '#detect' do
9
+ subject do
10
+ described_class.new('value').detect(default) { |v| v == 'value' }
11
+ end
12
+
13
+ context 'proc default' do
14
+ let(:default) { -> { -1 } }
15
+
16
+ it 'returns Left of evaluated default' do
17
+ is_expected.to eq(described_class.new(-1))
18
+ end
19
+ end
20
+
21
+ context 'default' do
22
+ let(:default) { -1 }
23
+
24
+ it 'return Left of default' do
25
+ is_expected.to eq(described_class.new(-1))
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#swap' do
31
+ subject { described_class.new('value').swap }
32
+ it { is_expected.to eq(Right('value')) }
33
+ end
34
+
35
+ describe '#reduce' do
36
+ subject do
37
+ described_class.new('value').reduce(
38
+ ->(left) { "Left: #{left}" },
39
+ ->(right) { "Right: #{right}" },
40
+ )
41
+ end
42
+
43
+ it { is_expected.to eq('Left: value') }
44
+ end
45
+
46
+ describe '#join_right' do
47
+ subject(:join_right) { either.join_right }
48
+
49
+ context 'value is Either' do
50
+ let(:either) { described_class.new(Left('error')) }
51
+ it { is_expected.to eq(either) }
52
+ end
53
+
54
+ context 'value s not Either' do
55
+ let(:either) { Left('error') }
56
+ it { is_expected.to eq(either) }
57
+ end
58
+ end
59
+
60
+ describe '#join_left' do
61
+ context 'value is Either' do
62
+ subject { either.join_left }
63
+ let(:either) { described_class.new(value) }
64
+ let(:value) { Left('error') }
65
+
66
+ it 'it returns value' do
67
+ is_expected.to eq(Left('error'))
68
+ end
69
+ end
70
+
71
+ context 'value is not Either' do
72
+ subject { proc { described_class.new('error').join_left } }
73
+
74
+ it 'fails with type error' do
75
+ is_expected.to raise_error(TypeError)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,37 @@
1
+ RSpec.describe Fear::None do
2
+ include Fear::Option::Mixin
3
+
4
+ it_behaves_like Fear::RightBiased::Left do
5
+ let(:left) { described_class.new }
6
+ end
7
+
8
+ subject(:none) { None() }
9
+
10
+ specify '#get fails with exception' do
11
+ expect do
12
+ none.get
13
+ end.to raise_error(NoMethodError)
14
+ end
15
+
16
+ specify '#or_nil returns nil' do
17
+ result = none.or_nil
18
+
19
+ expect(result).to eq nil
20
+ end
21
+
22
+ describe '#detect' do
23
+ subject { none.detect { |value| value > 42 } }
24
+
25
+ it 'always return None' do
26
+ is_expected.to eq(None())
27
+ end
28
+ end
29
+
30
+ describe '#reject' do
31
+ subject { none.reject { |value| value > 42 } }
32
+
33
+ it 'always return None' do
34
+ is_expected.to eq(None())
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ RSpec.describe Fear::Option do
2
+ include Fear::Option::Mixin
3
+
4
+ describe 'Option()' do
5
+ it 'returns Some if value is not nil' do
6
+ option = Option(double)
7
+
8
+ expect(option).to be_kind_of(Fear::Some)
9
+ end
10
+
11
+ it 'returns None if value is nil' do
12
+ option = Option(nil)
13
+
14
+ expect(option).to be_kind_of(Fear::None)
15
+ end
16
+ end
17
+
18
+ let(:some) { Some(42) }
19
+ let(:none) { None() }
20
+
21
+ describe '#empty?' do
22
+ context 'Some' do
23
+ subject { some.empty? }
24
+ it { is_expected.to eq(false) }
25
+ end
26
+
27
+ context 'None' do
28
+ subject { none.empty? }
29
+ it { is_expected.to eq(true) }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,67 @@
1
+ RSpec.shared_examples Fear::RightBiased::Left do
2
+ describe '#include?' do
3
+ subject { left }
4
+ it { is_expected.not_to include('value') }
5
+ end
6
+
7
+ describe '#get_or_else' do
8
+ context 'with block' do
9
+ subject { left.get_or_else { 'default' } }
10
+
11
+ it 'returns default value' do
12
+ is_expected.to eq('default')
13
+ end
14
+ end
15
+
16
+ context 'with default argument' do
17
+ subject { left.get_or_else('default') }
18
+
19
+ it 'returns default value' do
20
+ is_expected.to eq('default')
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#each' do
26
+ subject do
27
+ proc do |block|
28
+ expect(left.each(&block)).to eq(left)
29
+ end
30
+ end
31
+
32
+ it 'does not call the block' do
33
+ is_expected.not_to yield_control
34
+ end
35
+ end
36
+
37
+ describe '#map' do
38
+ subject { left.map(&:length) }
39
+
40
+ it 'returns self' do
41
+ is_expected.to eq(left)
42
+ end
43
+ end
44
+
45
+ describe '#flat_map' do
46
+ subject { left.flat_map(&:length) }
47
+
48
+ it 'returns self' do
49
+ is_expected.to eq(left)
50
+ end
51
+ end
52
+
53
+ describe '#to_a' do
54
+ subject { left.to_a }
55
+ it { is_expected.to eq([]) }
56
+ end
57
+
58
+ describe '#to_option' do
59
+ subject { left.to_option }
60
+ it { is_expected.to eq(Fear::None.new) }
61
+ end
62
+
63
+ describe '#any?' do
64
+ subject { left.any? { |v| v == 'value' } }
65
+ it { is_expected.to eq(false) }
66
+ end
67
+ end
@@ -0,0 +1,93 @@
1
+ RSpec.shared_examples Fear::RightBiased::Right do
2
+ describe '#include?' do
3
+ context 'contains value' do
4
+ subject { right.include?('value') }
5
+ it { is_expected.to eq(true) }
6
+ end
7
+
8
+ context 'does not contain value' do
9
+ subject { right.include?('another value') }
10
+ it { is_expected.to eq(false) }
11
+ end
12
+ end
13
+
14
+ describe '#get_or_else' do
15
+ context 'with block' do
16
+ subject { right.get_or_else { 'default' } }
17
+
18
+ it 'returns value' do
19
+ is_expected.to eq('value')
20
+ end
21
+ end
22
+
23
+ context 'with default argument' do
24
+ subject { right.get_or_else('default') }
25
+
26
+ it 'returns value' do
27
+ is_expected.to eq('value')
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#each' do
33
+ subject do
34
+ proc do |block|
35
+ expect(right.each(&block)).to eq(right)
36
+ end
37
+ end
38
+
39
+ it 'calls the block with value' do
40
+ is_expected.to yield_with_args('value')
41
+ end
42
+ end
43
+
44
+ describe '#map' do
45
+ subject { right.map(&:length) }
46
+
47
+ it 'perform transformation' do
48
+ is_expected.to eq(described_class.new(5))
49
+ end
50
+ end
51
+
52
+ describe '#flat_map' do
53
+ context 'block returns neither left, nor right' do
54
+ subject { proc { right.flat_map { 42 } } }
55
+
56
+ it 'fails with TypeError' do
57
+ is_expected.to raise_error(TypeError)
58
+ end
59
+ end
60
+
61
+ context 'block returns RightBiased' do
62
+ subject { right.flat_map { |e| described_class.new("Result: #{e}") } }
63
+
64
+ it 'maps to block result' do
65
+ is_expected.to eq(described_class.new('Result: value'))
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#to_a' do
71
+ subject { right.to_a }
72
+ it { is_expected.to eq(['value']) }
73
+ end
74
+
75
+ describe '#to_option' do
76
+ subject { right.to_option }
77
+ it { is_expected.to eq(Fear::Some.new('value')) }
78
+ end
79
+
80
+ describe '#any?' do
81
+ subject { right.any?(&predicate) }
82
+
83
+ context 'matches predicate' do
84
+ let(:predicate) { ->(v) { v == 'value' } }
85
+ it { is_expected.to eq(true) }
86
+ end
87
+
88
+ context 'does not match predicate' do
89
+ let(:predicate) { ->(v) { v != 'value' } }
90
+ it { is_expected.to eq(false) }
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,79 @@
1
+ RSpec.describe Fear::Right do
2
+ it_behaves_like Fear::RightBiased::Right do
3
+ let(:right) { described_class.new('value') }
4
+ end
5
+
6
+ let(:right) { described_class.new('value') }
7
+
8
+ describe '#detect' do
9
+ subject { right.detect(default, &predicate) }
10
+
11
+ context 'predicate evaluates to true' do
12
+ let(:predicate) { ->(v) { v == 'value' } }
13
+ let(:default) { -1 }
14
+ it { is_expected.to eq(right) }
15
+ end
16
+
17
+ context 'predicate evaluates to false and default is a proc' do
18
+ let(:predicate) { ->(v) { v != 'value' } }
19
+ let(:default) { -> { -1 } }
20
+ it { is_expected.to eq(Fear::Left.new(-1)) }
21
+ end
22
+
23
+ context 'predicate evaluates to false and default is not a proc' do
24
+ let(:predicate) { ->(v) { v != 'value' } }
25
+ let(:default) { -1 }
26
+ it { is_expected.to eq(Fear::Left.new(-1)) }
27
+ end
28
+ end
29
+
30
+ describe '#swap' do
31
+ subject { described_class.new('value').swap }
32
+ it { is_expected.to eq(Fear::Left.new('value')) }
33
+ end
34
+
35
+ describe '#reduce' do
36
+ subject do
37
+ described_class.new('value').reduce(
38
+ ->(left) { "Left: #{left}" },
39
+ ->(right) { "Right: #{right}" },
40
+ )
41
+ end
42
+
43
+ it { is_expected.to eq('Right: value') }
44
+ end
45
+
46
+ describe '#join_right' do
47
+ context 'value is Either' do
48
+ subject { described_class.new(value).join_right }
49
+ let(:value) { Fear::Left.new('error') }
50
+
51
+ it 'returns value' do
52
+ is_expected.to eq(value)
53
+ end
54
+ end
55
+
56
+ context 'value is not Either' do
57
+ subject { proc { described_class.new('35').join_right } }
58
+
59
+ it 'fails with type error' do
60
+ is_expected.to raise_error(TypeError)
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#join_left' do
66
+ context 'value is Either' do
67
+ subject { either.join_left }
68
+ let(:either) { described_class.new(Fear::Left.new('error')) }
69
+
70
+ it { is_expected.to eq(either) }
71
+ end
72
+
73
+ context 'value is not Either' do
74
+ subject { either.join_left }
75
+ let(:either) { described_class.new('result') }
76
+ it { is_expected.to eq(either) }
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,48 @@
1
+ RSpec.describe Fear::Some do
2
+ include Fear::Option::Mixin
3
+
4
+ it_behaves_like Fear::RightBiased::Right do
5
+ let(:right) { described_class.new('value') }
6
+ end
7
+
8
+ subject(:some) { Some(value) }
9
+ let(:value) { 42 }
10
+
11
+ describe '#detect' do
12
+ subject { some.detect(&predicate) }
13
+
14
+ context 'predicate evaluates to true' do
15
+ let(:predicate) { ->(v) { v > 40 } }
16
+ it { is_expected.to eq(some) }
17
+ end
18
+
19
+ context 'predicate evaluates to false' do
20
+ let(:predicate) { ->(v) { v < 40 } }
21
+ it { is_expected.to eq(None()) }
22
+ end
23
+ end
24
+
25
+ describe '#reject' do
26
+ subject { some.reject(&predicate) }
27
+
28
+ context 'predicate evaluates to true' do
29
+ let(:predicate) { ->(v) { v > 40 } }
30
+ it { is_expected.to eq(None()) }
31
+ end
32
+
33
+ context 'predicate evaluates to false' do
34
+ let(:predicate) { ->(v) { v < 40 } }
35
+ it { is_expected.to eq(some) }
36
+ end
37
+ end
38
+
39
+ specify '#get returns value' do
40
+ expect(some.get).to eq value
41
+ end
42
+
43
+ specify '#or_nil returns value' do
44
+ result = some.or_nil
45
+
46
+ expect(result).to eq value
47
+ end
48
+ end
@@ -0,0 +1,83 @@
1
+ RSpec.describe Fear::Success do
2
+ let(:success) { described_class.new('value') }
3
+
4
+ it_behaves_like Fear::RightBiased::Right do
5
+ let(:right) { success }
6
+
7
+ describe '#map', 'block fails' do
8
+ subject(:map) { right.map { fail 'unexpected error' } }
9
+
10
+ it { is_expected.to be_kind_of(Fear::Failure) }
11
+ it { expect { map.get }.to raise_error(RuntimeError, 'unexpected error') }
12
+ end
13
+
14
+ describe '#flat_map', 'block fails' do
15
+ subject(:flat_map) { right.flat_map { fail 'unexpected error' } }
16
+
17
+ it { is_expected.to be_kind_of(Fear::Failure) }
18
+ it { expect { flat_map.get }.to raise_error(RuntimeError, 'unexpected error') }
19
+ end
20
+ end
21
+
22
+ describe '#get' do
23
+ subject { success.get }
24
+ it { is_expected.to eq('value') }
25
+ end
26
+
27
+ describe '#success?' do
28
+ subject { success }
29
+ it { is_expected.to be_success }
30
+ end
31
+
32
+ describe '#or_else' do
33
+ subject { success.or_else { described_class.new('another value') } }
34
+ it { is_expected.to eq(success) }
35
+ end
36
+
37
+ describe '#flatten' do
38
+ subject { described_class.new(value).flatten }
39
+
40
+ context 'value is a Success' do
41
+ let(:value) { described_class.new(42) }
42
+ it { is_expected.to eq(described_class.new(42)) }
43
+ end
44
+
45
+ context 'value is a Success of Success' do
46
+ let(:value) { described_class.new(described_class.new(42)) }
47
+ it { is_expected.to eq(described_class.new(42)) }
48
+ end
49
+
50
+ context 'value is a Success of Failure' do
51
+ let(:failure) { Fear::Failure.new(RuntimeError.new) }
52
+ let(:value) { described_class.new(failure) }
53
+ it { is_expected.to eq(failure) }
54
+ end
55
+ end
56
+
57
+ describe '#detect' do
58
+ context 'predicate holds for value' do
59
+ subject { success.detect { |v| v == 'value' } }
60
+ it { is_expected.to eq(success) }
61
+ end
62
+
63
+ context 'predicate does not hold for value' do
64
+ subject { proc { success.detect { |v| v != 'value' }.get } }
65
+ it { is_expected.to raise_error(Fear::NoSuchElementError, 'Predicate does not hold for `value`') }
66
+ end
67
+
68
+ context 'predicate fails with error' do
69
+ subject { proc { success.detect { fail 'foo' }.get } }
70
+ it { is_expected.to raise_error(RuntimeError, 'foo') }
71
+ end
72
+ end
73
+
74
+ describe '#recover_with' do
75
+ subject { success.recover_with { |v| Success(v * 2) } }
76
+ it { is_expected.to eq(success) }
77
+ end
78
+
79
+ describe '#recover' do
80
+ subject { success.recover { |v| v * 2 } }
81
+ it { is_expected.to eq(success) }
82
+ end
83
+ end
@@ -0,0 +1,60 @@
1
+ RSpec.describe Fear::Utils do
2
+ describe '.assert_arg_or_block!' do
3
+ def assert_arg_or_block!(*args, &block)
4
+ described_class.assert_arg_or_block!(:the_method, *args, &block)
5
+ end
6
+
7
+ context 'block given, argument does not given' do
8
+ subject { proc { assert_arg_or_block! {} } }
9
+
10
+ it { is_expected.not_to raise_error }
11
+ end
12
+
13
+ context 'argument given, block does not given' do
14
+ subject { proc { assert_arg_or_block!(42) } }
15
+
16
+ it { is_expected.not_to raise_error }
17
+ end
18
+
19
+ context 'argument and block given at the same time' do
20
+ subject { proc { assert_arg_or_block!(42) {} } }
21
+
22
+ it 'fails with argument error' do
23
+ is_expected.to raise_error(
24
+ ArgumentError,
25
+ '#the_method accepts either one argument or block',
26
+ )
27
+ end
28
+ end
29
+
30
+ context 'no argument and no block given' do
31
+ subject { proc { assert_arg_or_block! } }
32
+
33
+ it 'fails with argument error' do
34
+ is_expected.to raise_error(
35
+ ArgumentError,
36
+ '#the_method accepts either one argument or block',
37
+ )
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'assert_type!' do
43
+ context 'value is of the given type' do
44
+ subject { proc { described_class.assert_type!(24, Integer) } }
45
+
46
+ it { is_expected.not_to raise_error }
47
+ end
48
+
49
+ context 'value is not of the given type' do
50
+ subject { proc { described_class.assert_type!(24, String) } }
51
+
52
+ it 'raises TypeError' do
53
+ is_expected.to raise_error(
54
+ TypeError,
55
+ 'expected `24` to be of String class',
56
+ )
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,77 @@
1
+ # require 'codeclimate-test-reporter'
2
+ # CodeClimate::TestReporter.start
3
+
4
+ require 'fear'
5
+ require File.expand_path('spec/fear/right_biased/right')
6
+ require File.expand_path('spec/fear/right_biased/left')
7
+
8
+ RSpec.configure do |config|
9
+ # rspec-expectations config goes here. You can use an alternate
10
+ # assertion/expectation library such as wrong or the stdlib/minitest
11
+ # assertions if you prefer.
12
+ config.expect_with :rspec do |expectations|
13
+ # This option will default to `true` in RSpec 4. It makes the `description`
14
+ # and `failure_message` of custom matchers include text for helper methods
15
+ # defined using `chain`, e.g.:
16
+ # be_bigger_than(2).and_smaller_than(4).description
17
+ # # => "be bigger than 2 and smaller than 4"
18
+ # ...rather than:
19
+ # # => "be bigger than 2"
20
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
21
+ end
22
+
23
+ # rspec-mocks config goes here. You can use an alternate test double
24
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
25
+ config.mock_with :rspec do |mocks|
26
+ # Prevents you from mocking or stubbing a method that does not exist on
27
+ # a real object. This is generally recommended, and will default to
28
+ # `true` in RSpec 4.
29
+ mocks.verify_partial_doubles = true
30
+ end
31
+
32
+ # These two settings work together to allow you to limit a spec run
33
+ # to individual examples or groups you care about by tagging them with
34
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
35
+ # get run.
36
+ config.filter_run :focus
37
+ config.run_all_when_everything_filtered = true
38
+
39
+ # Limits the available syntax to the non-monkey patched syntax that is
40
+ # recommended.
41
+ # For more details, see:
42
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
43
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
44
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
45
+ config.disable_monkey_patching!
46
+
47
+ # This setting enables warnings. It's recommended, but in some cases may
48
+ # be too noisy due to issues in dependencies.
49
+ config.warnings = true
50
+
51
+ # Many RSpec users commonly either run the entire suite or an individual
52
+ # file, and it's useful to allow more verbose output when running an
53
+ # individual spec file.
54
+ if config.files_to_run.one?
55
+ # Use the documentation formatter for detailed output,
56
+ # unless a formatter has already been configured
57
+ # (e.g. via a command-line flag).
58
+ config.default_formatter = 'doc'
59
+ end
60
+
61
+ # Print the 10 slowest examples and example groups at the
62
+ # end of the spec run, to help surface which specs are running
63
+ # particularly slow.
64
+ config.profile_examples = 3
65
+
66
+ # Run specs in random order to surface order dependencies. If you find an
67
+ # order dependency and want to debug it, you can fix the order by providing
68
+ # the seed, which is printed after each run.
69
+ # --seed 1234
70
+ config.order = :random
71
+
72
+ # Seed global randomization in this process using the `--seed` CLI option.
73
+ # Setting this allows you to use `--seed` to deterministically reproduce
74
+ # test failures related to randomization by passing the same `--seed` value
75
+ # as the one that triggered the failure.
76
+ Kernel.srand config.seed
77
+ end