transproc 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Transproc::Recursion do
4
+ let(:hashes) { Transproc::HashTransformations }
5
+
4
6
  describe '.recursion' do
5
7
  let(:original) do
6
8
  {
@@ -28,7 +30,7 @@ describe Transproc::Recursion do
28
30
 
29
31
  context 'when function is non-destructive' do
30
32
  let(:map) do
31
- t(:recursion, -> enum {
33
+ described_class.t(:recursion, -> enum {
32
34
  enum.reject { |v| v == 'baz' }
33
35
  })
34
36
  end
@@ -41,7 +43,7 @@ describe Transproc::Recursion do
41
43
 
42
44
  context 'when function is destructive' do
43
45
  let(:map) do
44
- t(:recursion, -> enum {
46
+ described_class.t(:recursion, -> enum {
45
47
  enum.reject! { |v| v == 'baz' }
46
48
  })
47
49
  end
@@ -87,7 +89,7 @@ describe Transproc::Recursion do
87
89
  end
88
90
 
89
91
  context 'when function is non-destructive' do
90
- let(:map) { t(:array_recursion, proc(&:compact)) }
92
+ let(:map) { described_class.t(:array_recursion, proc(&:compact)) }
91
93
 
92
94
  it 'applies funtions to all items recursively' do
93
95
  expect(map[input]).to eql(output)
@@ -96,7 +98,7 @@ describe Transproc::Recursion do
96
98
  end
97
99
 
98
100
  context 'when function is destructive' do
99
- let(:map) { t(:array_recursion, proc(&:compact!)) }
101
+ let(:map) { described_class.t(:array_recursion, proc(&:compact!)) }
100
102
 
101
103
  it 'applies funtions to all items recursively and destructively' do
102
104
  expect(map[input]).to eql(output)
@@ -135,7 +137,9 @@ describe Transproc::Recursion do
135
137
  end
136
138
 
137
139
  context 'when function is non-destructive' do
138
- let(:map) { t(:hash_recursion, t(:symbolize_keys)) }
140
+ let(:map) do
141
+ described_class.t(:hash_recursion, hashes.t(:symbolize_keys))
142
+ end
139
143
 
140
144
  it 'applies funtions to all values recursively' do
141
145
  expect(map[input]).to eql(output)
@@ -144,7 +148,9 @@ describe Transproc::Recursion do
144
148
  end
145
149
 
146
150
  context 'when function is destructive' do
147
- let(:map) { t(:hash_recursion, t(:symbolize_keys!)) }
151
+ let(:map) do
152
+ described_class.t(:hash_recursion, hashes.t(:symbolize_keys!))
153
+ end
148
154
 
149
155
  it 'applies funtions to all values recursively and destructively' do
150
156
  expect(map[input]).to eql(output)
@@ -1,95 +1,105 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Transproc::Registry do
4
- before do
5
- module FooModule
4
+ before { module Transproc::Test; end }
5
+ after { Transproc.send :remove_const, :Test }
6
+
7
+ let(:foo) do
8
+ Transproc::Test::Foo = Module.new do
6
9
  extend Transproc::Registry
7
10
 
8
- def foo(value, prefix)
9
- [prefix, '_', value].join
11
+ def self.prefix(value, prefix)
12
+ "#{prefix}_#{value}"
10
13
  end
11
14
  end
15
+ end
16
+ let(:bar) { Transproc::Test::Bar = Module.new { extend Transproc::Registry } }
17
+ let(:baz) { Transproc::Test::Baz = Module.new { extend Transproc::Registry } }
18
+
19
+ describe '.[]' do
20
+ subject(:transproc) { foo[fn, 'baz'] }
12
21
 
13
- module BarModule
14
- include FooModule
22
+ context 'from a method' do
23
+ let(:fn) { :prefix }
15
24
 
16
- def bar(*args)
17
- foo(*args).upcase
25
+ it 'builds a function from a method' do
26
+ expect(transproc['qux']).to eql 'baz_qux'
18
27
  end
19
28
  end
20
29
 
21
- module BazModule
22
- extend Transproc::Registry
30
+ context 'from a closure' do
31
+ let(:fn) { -> value, prefix { [prefix, '_', value].join } }
32
+
33
+ it 'builds a function from a method' do
34
+ expect(transproc['qux']).to eql 'baz_qux'
35
+ end
23
36
  end
24
37
  end
25
38
 
26
- describe '.[]' do
27
- it 'builds function from the method' do
28
- fn = ::FooModule[:foo, 'baz']
39
+ describe '.t' do
40
+ subject(:transproc) { foo.t(:prefix, 'baz') }
29
41
 
30
- expect(fn['qux']).to eql 'baz_qux'
42
+ it 'is an alias for .[]' do
43
+ expect(transproc['qux']).to eql 'baz_qux'
31
44
  end
45
+ end
32
46
 
33
- it 'builds function from the proc' do
34
- fun = -> value, prefix { [prefix, '_', value].join }
35
- fn = ::FooModule[fun, 'baz']
36
-
37
- expect(fn['qux']).to eql 'baz_qux'
38
- end
47
+ describe '.import' do
48
+ context 'a module' do
49
+ subject(:import) { bar.import foo }
39
50
 
40
- it 'builds function using methods from included modules' do
41
- fn = ::BarModule[:bar, 'baz']
51
+ it 'registers all its methods' do
52
+ import
53
+ expect(bar[:prefix, 'baz']['qux']).to eql 'baz_qux'
54
+ end
42
55
 
43
- expect(fn['qux']).to eql 'BAZ_QUX'
56
+ it 'returns itself' do
57
+ expect(import).to eq bar
58
+ end
44
59
  end
45
60
 
46
- it 'can access methods from included modules directly' do
47
- fn = ::BarModule[:foo, 'baz']
61
+ context 'a method' do
62
+ before { bar.import :prefix, from: foo }
48
63
 
49
- expect(fn['qux']).to eql 'baz_qux'
64
+ it 'registers a transproc' do
65
+ expect(bar[:prefix, 'bar']['baz']).to eql 'bar_baz'
66
+ end
50
67
  end
51
68
 
52
- it 'cannot access undefined methods' do
53
- module ::BarModule
54
- undef_method :foo
69
+ context 'an imported method' do
70
+ before do
71
+ bar.import :prefix, from: foo, as: :affix
72
+ baz.import :affix, from: bar
55
73
  end
56
74
 
57
- expect { ::BarModule[:foo, 'baz'] }.to raise_error(NameError)
75
+ it 'registers a transproc' do
76
+ expect(baz[:affix, 'bar']['baz']).to eql 'bar_baz'
77
+ end
58
78
  end
59
- end
60
79
 
61
- describe '.uses' do
62
- it 'forwards methods to another module directly' do
63
- expect { ::BazModule[:baz, 'baz'] }.to raise_error(NameError)
80
+ context 'a renamed method' do
81
+ before { bar.import :prefix, from: foo, as: :affix }
64
82
 
65
- module BazModule
66
- uses :foo, as: :ffoo, from: FooModule
67
- uses :bar, from: BarModule
83
+ it 'registers a transproc under the new name' do
84
+ expect(bar[:affix, 'bar']['baz']).to eql 'bar_baz'
68
85
  end
69
-
70
- ffoo = ::BazModule[:ffoo, 'baz']
71
- bar = ::BazModule[:bar, 'baz']
72
-
73
- expect(ffoo['qux']).to eql 'baz_qux'
74
- expect(bar['qux']).to eql 'BAZ_QUX'
75
86
  end
76
- end
77
87
 
78
- describe '#t' do
79
- it 'is an alias for .[]' do
80
- module FooModule
81
- def qux(value, *args)
82
- t(:foo, *args)[value]
88
+ context 'an unknown method' do
89
+ it 'fails' do
90
+ expect { bar.import :suffix, from: foo }.to raise_error do |error|
91
+ expect(error).to be_kind_of Transproc::FunctionNotFoundError
92
+ expect(error.message).to include 'Foo[:suffix]'
83
93
  end
84
94
  end
95
+ end
96
+ end
85
97
 
86
- fn = ::FooModule[:foo, 'baz']
98
+ describe '.uses' do
99
+ before { bar.uses foo }
87
100
 
88
- expect(fn['qux']).to eql 'baz_qux'
101
+ it 'is an alias for .import' do
102
+ expect(bar[:prefix, 'baz']['qux']).to eql 'baz_qux'
89
103
  end
90
104
  end
91
-
92
- after { Object.send :remove_const, :BazModule }
93
- after { Object.send :remove_const, :BarModule }
94
- after { Object.send :remove_const, :FooModule }
95
105
  end
@@ -0,0 +1,148 @@
1
+ # encoding: utf-8
2
+
3
+ describe Transproc::Store do
4
+ let(:store) { described_class.new methods }
5
+ let(:methods) { { foo: instance_double(Proc) } }
6
+
7
+ describe '.new' do
8
+ it 'is immutable' do
9
+ expect(store).to be_frozen
10
+ end
11
+
12
+ it 'does not freeze the source hash' do
13
+ expect { store }.not_to change { methods.frozen? }
14
+ end
15
+ end # describe .new
16
+
17
+ describe '#methods' do
18
+ it 'returns the hash from the initializer' do
19
+ expect(store.methods).to eql methods
20
+ end
21
+
22
+ it 'returns empty hash by default' do
23
+ expect(described_class.new.methods).to eql({})
24
+ end
25
+
26
+ it 'is immutable' do
27
+ expect(store.methods).to be_frozen
28
+ end
29
+ end # describe #methods
30
+
31
+ describe '#fetch' do
32
+ it 'returns a registered proc' do
33
+ expect(store.fetch(:foo)).to eql methods[:foo]
34
+ end
35
+
36
+ it 'raises KeyError if requested proc is unknown' do
37
+ expect { store.fetch(:bar) }.to raise_error KeyError
38
+ end
39
+ end # describe #fetch
40
+
41
+ describe '#import' do
42
+ before do
43
+ module Bar
44
+ def self.bar
45
+ :bar
46
+ end
47
+ end
48
+
49
+ module Baz
50
+ def self.baz
51
+ :baz
52
+ end
53
+ end
54
+
55
+ module Qux
56
+ extend Transproc::Registry
57
+
58
+ import Bar
59
+ import Baz
60
+
61
+ def self.baz
62
+ :qux_baz
63
+ end
64
+
65
+ def self.qux
66
+ :qux
67
+ end
68
+ end
69
+ end
70
+
71
+ shared_examples :importing_method do
72
+ let(:preserved) { subject.methods[:foo] }
73
+ let(:imported) { subject.methods[key] }
74
+
75
+ it '[preserves old methods]' do
76
+ expect(preserved).to eql(methods[:foo])
77
+ end
78
+
79
+ it '[registers a new method]' do
80
+ expect(imported).to be_kind_of Method
81
+ expect(imported.call).to eql(value)
82
+ end
83
+ end
84
+
85
+ context 'named method' do
86
+ subject { store.import 'qux', from: Qux }
87
+
88
+ it_behaves_like :importing_method do
89
+ let(:key) { :qux }
90
+ let(:value) { :qux }
91
+ end
92
+ end
93
+
94
+ context 'renamed method' do
95
+ subject { store.import 'qux', from: Qux, as: 'quxx' }
96
+
97
+ it_behaves_like :importing_method do
98
+ let(:key) { :quxx }
99
+ let(:value) { :qux }
100
+ end
101
+ end
102
+
103
+ context 'imported proc' do
104
+ subject { store.import 'bar', from: Qux, as: 'barr' }
105
+
106
+ it_behaves_like :importing_method do
107
+ let(:key) { :barr }
108
+ let(:value) { :bar }
109
+ end
110
+ end
111
+
112
+ context 'method that reloads imported proc' do
113
+ subject { store.import 'baz', from: Qux, as: 'bazz' }
114
+
115
+ it_behaves_like :importing_method do
116
+ let(:key) { :bazz }
117
+ let(:value) { :qux_baz }
118
+ end
119
+ end
120
+
121
+ context 'module' do
122
+ subject { store.import Qux }
123
+
124
+ it_behaves_like :importing_method do
125
+ let(:key) { :bar }
126
+ let(:value) { :bar }
127
+ end
128
+
129
+ it_behaves_like :importing_method do
130
+ let(:key) { :baz }
131
+ let(:value) { :qux_baz }
132
+ end
133
+
134
+ it_behaves_like :importing_method do
135
+ let(:key) { :qux }
136
+ let(:value) { :qux }
137
+ end
138
+
139
+ it 'skips Transproc::Registry singleton methods' do
140
+ expect(subject.methods.keys).to contain_exactly(:foo, :bar, :baz, :qux)
141
+ end
142
+ end
143
+
144
+ after do
145
+ %w(Bar Baz Qux).each { |name| Object.send :remove_const, name }
146
+ end
147
+ end # describe #import
148
+ end # describe Transproc::Store
@@ -50,6 +50,14 @@ describe Transproc do
50
50
  end
51
51
  end
52
52
 
53
+ describe 'accessing a function with args' do
54
+ it 'curries the args' do
55
+ fn = Transproc(:map_array, Transproc(:to_string))
56
+
57
+ expect(fn.args).to include(Transproc(:to_string))
58
+ end
59
+ end
60
+
53
61
  describe 'handling malformed input' do
54
62
  it 'raises a Transproc::MalformedInputError' do
55
63
  expect {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transproc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-20 00:00:00.000000000 Z
11
+ date: 2015-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,6 +84,9 @@ files:
84
84
  - lib/transproc/hash.rb
85
85
  - lib/transproc/recursion.rb
86
86
  - lib/transproc/registry.rb
87
+ - lib/transproc/rspec.rb
88
+ - lib/transproc/store.rb
89
+ - lib/transproc/support/deprecations.rb
87
90
  - lib/transproc/version.rb
88
91
  - rakelib/mutant.rake
89
92
  - rakelib/rubocop.rake
@@ -94,10 +97,12 @@ files:
94
97
  - spec/unit/coercions_spec.rb
95
98
  - spec/unit/composer_spec.rb
96
99
  - spec/unit/conditional_spec.rb
100
+ - spec/unit/function_not_found_error_spec.rb
97
101
  - spec/unit/function_spec.rb
98
102
  - spec/unit/hash_transformations_spec.rb
99
103
  - spec/unit/recursion_spec.rb
100
104
  - spec/unit/registry_spec.rb
105
+ - spec/unit/store_spec.rb
101
106
  - spec/unit/transproc_spec.rb
102
107
  - transproc.gemspec
103
108
  homepage: http://solnic.github.io/transproc/
@@ -132,8 +137,10 @@ test_files:
132
137
  - spec/unit/coercions_spec.rb
133
138
  - spec/unit/composer_spec.rb
134
139
  - spec/unit/conditional_spec.rb
140
+ - spec/unit/function_not_found_error_spec.rb
135
141
  - spec/unit/function_spec.rb
136
142
  - spec/unit/hash_transformations_spec.rb
137
143
  - spec/unit/recursion_spec.rb
138
144
  - spec/unit/registry_spec.rb
145
+ - spec/unit/store_spec.rb
139
146
  - spec/unit/transproc_spec.rb