amenable 0.0.1 → 0.0.2
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/lib/amenable.rb +9 -29
- data/lib/amenable/version.rb +2 -2
- data/spec/amenable_spec.rb +116 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 133a9c4b0a84e4325394ededc6826cb7408a9505d1c45bdfdd06674a10fac5ff
|
4
|
+
data.tar.gz: 1345444593420700a2b84938c64f58343e6f33c8a6399fd955fb09cd717c74c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fcb746e4541e5360d25b5281d0b407be1b851ba97196d5bae01fec41eae898227bc87aa09dba59d91e22b5045aa14dd93d63856323805cc4944641b79df71b6
|
7
|
+
data.tar.gz: 9072334b6a123882a656f07db3797064cf726fdaf7900ecddc90e808b27ca6503246c0417e1f953e4941fc9c69e2ddce1a5a04be69e245aada6a3b6cf64bccf1
|
data/lib/amenable.rb
CHANGED
@@ -1,30 +1,17 @@
|
|
1
1
|
require 'amenable/version'
|
2
2
|
|
3
3
|
module Amenable
|
4
|
-
|
5
|
-
name, redefiner = parse(fn)
|
6
|
-
rebuild(fn, :tighten)
|
4
|
+
extend self
|
7
5
|
|
8
|
-
|
6
|
+
def call(fn, *args, **kwargs, &block)
|
7
|
+
wrap(fn).call(*args, **kwargs, &block)
|
9
8
|
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
case fn
|
15
|
-
when Symbol
|
16
|
-
name = fn
|
17
|
-
fn = method(fn)
|
18
|
-
redefiner = method(:define_method)
|
19
|
-
when Method
|
20
|
-
name = fn.name
|
21
|
-
redefiner = method(:define_method)
|
10
|
+
def wrap(fn)
|
11
|
+
unless fn.respond_to?(:call)
|
12
|
+
raise ArgumentError, "fn must be callable: #{fn}"
|
22
13
|
end
|
23
14
|
|
24
|
-
[ name, redefiner ]
|
25
|
-
end
|
26
|
-
|
27
|
-
def rebuild(fn, mode:)
|
28
15
|
rest = keyrest = false
|
29
16
|
params = []
|
30
17
|
keys = []
|
@@ -39,21 +26,14 @@ module Amenable
|
|
39
26
|
rest = true
|
40
27
|
when :keyrest
|
41
28
|
keyrest = true
|
42
|
-
else
|
43
|
-
raise RuntimeError, "unexpected parameter type: #{type}"
|
44
29
|
end
|
45
30
|
end
|
46
31
|
|
47
32
|
proc do |*args, **kwargs, &block|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
kwargs = kwargs.slice(*keys) unless keyrest
|
52
|
-
else
|
53
|
-
# loosen
|
54
|
-
end
|
33
|
+
# remove unreferenced params
|
34
|
+
args.slice! params.count unless rest
|
35
|
+
kwargs = kwargs.slice(*keys) unless keyrest
|
55
36
|
|
56
|
-
puts "call(#{args}, #{kwargs})"
|
57
37
|
fn.call(*args, **kwargs, &block)
|
58
38
|
end
|
59
39
|
end
|
data/lib/amenable/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = '0.0.
|
1
|
+
module Amenable
|
2
|
+
VERSION = '0.0.2'
|
3
3
|
end
|
data/spec/amenable_spec.rb
CHANGED
@@ -1,3 +1,119 @@
|
|
1
1
|
describe Amenable do
|
2
|
+
describe '.wrap' do
|
3
|
+
let(:fn) { proc {} }
|
2
4
|
|
5
|
+
it 'requires a function-like input' do
|
6
|
+
expect { Amenable.wrap(nil) }.to raise_error(ArgumentError)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'wraps a function with a function' do
|
10
|
+
res = Amenable.wrap(fn)
|
11
|
+
expect(res).to be_a Proc
|
12
|
+
expect(res).not_to be fn
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns a function that takes any input' do
|
16
|
+
params = Amenable.wrap(fn).parameters.map &:first
|
17
|
+
expect(params).to eq [ :rest, :keyrest, :block ]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.call' do
|
22
|
+
let(:fn) { proc {|x, y = :y, a:, b: 2| [ [ x, y ], { a: a, b: b } ] } }
|
23
|
+
|
24
|
+
it 'calls .wrap under the hood' do
|
25
|
+
fn = proc {}
|
26
|
+
expect(Amenable).to receive(:wrap).with(fn).and_call_original
|
27
|
+
Amenable.call(fn)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'takes args and kwargs as expected' do
|
31
|
+
expect(fn).to receive(:call).with(:x, :y, a: 1, b: 2)
|
32
|
+
Amenable.call(fn, :x, :y, a: 1, b: 2)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'removes excessive parameters' do
|
36
|
+
expect(fn).to receive(:call).with(:x, :y, a: 1, b: 2)
|
37
|
+
Amenable.call(fn, :x, :y, :z, a: 1, b: 2, c: 3)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'works with splat operator' do
|
41
|
+
args = [ :x, :y, :z ]
|
42
|
+
kwargs = { a: 1, b: 2, c: 3 }
|
43
|
+
|
44
|
+
expect(fn).to receive(:call).with(:x, :y, a: 1, b: 2)
|
45
|
+
Amenable.call(fn, *args, **kwargs)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'works with default args' do
|
49
|
+
expect(fn).to receive(:call).with(:x, a: 1).and_call_original
|
50
|
+
|
51
|
+
expect(Amenable.call(fn, :x, a: 1)).to eq([
|
52
|
+
[ :x, :y ],
|
53
|
+
{ a: 1, b: 2 },
|
54
|
+
])
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises if required arguments are not passed' do
|
58
|
+
expect {
|
59
|
+
Amenable.call(fn, :x)
|
60
|
+
}.to raise_error(ArgumentError)
|
61
|
+
|
62
|
+
expect {
|
63
|
+
Amenable.call(fn, :x, :y)
|
64
|
+
}.to raise_error(ArgumentError)
|
65
|
+
|
66
|
+
expect {
|
67
|
+
Amenable.call(fn, :x, :y, b: 2)
|
68
|
+
}.to raise_error(ArgumentError)
|
69
|
+
|
70
|
+
expect {
|
71
|
+
Amenable.call(fn, a: 1, b: 2)
|
72
|
+
}.to raise_error(ArgumentError)
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with var args' do
|
76
|
+
let(:fn) { proc {|x, *z, a:, **c| [ x, z, a, c ] } }
|
77
|
+
|
78
|
+
it 'works with just enough args' do
|
79
|
+
expect(fn).to receive(:call).with(:x, a: 1).and_call_original
|
80
|
+
|
81
|
+
expect(Amenable.call(fn, :x, a: 1)).to eq([
|
82
|
+
:x, [], 1, {},
|
83
|
+
])
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'fails without enough args' do
|
87
|
+
expect {
|
88
|
+
Amenable.call(fn, :x)
|
89
|
+
}.to raise_error(ArgumentError)
|
90
|
+
|
91
|
+
expect {
|
92
|
+
Amenable.call(fn, a: 1)
|
93
|
+
}.to raise_error(ArgumentError)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'passes through all args' do
|
97
|
+
expect(Amenable.call(fn, :x, :y, :z, a: 1, b: 2, c: 3)).to eq([
|
98
|
+
:x, [ :y, :z ], 1, { b: 2, c: 3 },
|
99
|
+
])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'with a method' do
|
104
|
+
before do
|
105
|
+
def test_fn(x, a:, &block)
|
106
|
+
[ x, a, block ]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'works all the same' do
|
111
|
+
test_block = proc {}
|
112
|
+
|
113
|
+
expect(Amenable.call(method(:test_fn), :x, a: 1, &test_block)).to eq([
|
114
|
+
:x, 1, test_block
|
115
|
+
])
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
3
119
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amenable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Pepper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|