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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a475b65e0b28577bf21459d1267f9a80b32636b2ea9ad614a07ca02e2969e4e8
4
- data.tar.gz: ce7f241ba21d1e0380e0027665f1b33464864b61f1fdf76b50b3e99644f1a9ad
3
+ metadata.gz: 133a9c4b0a84e4325394ededc6826cb7408a9505d1c45bdfdd06674a10fac5ff
4
+ data.tar.gz: 1345444593420700a2b84938c64f58343e6f33c8a6399fd955fb09cd717c74c0
5
5
  SHA512:
6
- metadata.gz: 8011289c31bad632ebefe20fc42edf4454cffb9ffbde0cd96e576e6ab1bf91f83ac8c707b3e4769af505f5d1bef10a1d428e38a526641b75af1a3cd08ae04988
7
- data.tar.gz: 91bbdf8c82fe716f4d727f8b4a2212d906ec34cf9f9034ddd710a72e382d2336ec8f818fb2c27af0e043b10c7ed69448ada7023d8d0081fbcca27a0e92325467
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
- def tighten(fn)
5
- name, redefiner = parse(fn)
6
- rebuild(fn, :tighten)
4
+ extend self
7
5
 
8
- # remount
6
+ def call(fn, *args, **kwargs, &block)
7
+ wrap(fn).call(*args, **kwargs, &block)
9
8
  end
10
9
 
11
- private
12
-
13
- def parse fn
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
- if mode == :tighten
49
- # remove unreferenced params
50
- args.slice! params.count unless rest
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
@@ -1,3 +1,3 @@
1
- class Amenable
2
- VERSION = '0.0.1'
1
+ module Amenable
2
+ VERSION = '0.0.2'
3
3
  end
@@ -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.1
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-04-08 00:00:00.000000000 Z
11
+ date: 2021-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug