delivered 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23b613f6dd8b19b06d0ca874c1a4f7408708f18b88e05d53b683693b27a20a04
4
- data.tar.gz: 1380e56b87e1fa5b534b5bd6645dc1d965dec1c81021e042c4fc7f031aafdae2
3
+ metadata.gz: bd1eeeeaa704a08c1b4c834b24ba5623409da015b9697df7653cd60502edd8c3
4
+ data.tar.gz: 7fbce031535260897742c0f38100b23b0e62431f85dcd0f40c5b5a062a1f982a
5
5
  SHA512:
6
- metadata.gz: ef984b3f51256ace952efaac631986a500c121408a42f544f6f9c4c296d2d88e2cc909452232bbdb498b4177ead3b910139205105c4137180c56dfcca2297f28
7
- data.tar.gz: 17d2eaeb8cc23bfe69dd3f76b7b33d09d967f0f87d81221209c4b09c6cbd3777ed8ea45d4fd62ad119155a7bd1cd1aba8476677d022a6b24afb23032ff9dd423
6
+ metadata.gz: 3cca910f20d4d8cc948912346ff1f2c20add1e0fb7b7ba3bdaa42e81702195290b84670220579e6e6359a619e2f94f4bf4460fd0a2c9ad7227d39b2f84c42896
7
+ data.tar.gz: 23ad19572356a722b933db7253810b212120f1d9d47242a4fe56b5c6009d51164d6035ede779ee9d37758e9c6d3b235d18c75f553a5b8e09bf80318c59caac64
data/Gemfile.lock CHANGED
@@ -1,37 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- delivered (0.2.0)
4
+ delivered (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  amazing_print (1.6.0)
10
10
  ast (2.4.2)
11
- debug (1.9.1)
11
+ debug (1.9.2)
12
12
  irb (~> 1.10)
13
13
  reline (>= 0.3.8)
14
14
  io-console (0.7.2)
15
- irb (1.12.0)
16
- rdoc
15
+ irb (1.13.1)
16
+ rdoc (>= 4.0.0)
17
17
  reline (>= 0.4.2)
18
- json (2.7.1)
18
+ json (2.7.2)
19
19
  language_server-protocol (3.17.0.3)
20
20
  parallel (1.24.0)
21
- parser (3.3.0.5)
21
+ parser (3.3.1.0)
22
22
  ast (~> 2.4.1)
23
23
  racc
24
24
  psych (5.1.2)
25
25
  stringio
26
- racc (1.7.3)
26
+ racc (1.8.0)
27
27
  rainbow (3.1.1)
28
- rdoc (6.6.3.1)
28
+ rdoc (6.7.0)
29
29
  psych (>= 4.0.0)
30
- regexp_parser (2.9.0)
31
- reline (0.5.0)
30
+ regexp_parser (2.9.2)
31
+ reline (0.5.8)
32
32
  io-console (~> 0.5)
33
- rexml (3.2.6)
34
- rubocop (1.62.1)
33
+ rexml (3.2.8)
34
+ strscan (>= 3.0.9)
35
+ rubocop (1.64.0)
35
36
  json (~> 2.3)
36
37
  language_server-protocol (>= 3.17.0)
37
38
  parallel (~> 1.10)
@@ -42,11 +43,12 @@ GEM
42
43
  rubocop-ast (>= 1.31.1, < 2.0)
43
44
  ruby-progressbar (~> 1.7)
44
45
  unicode-display_width (>= 2.4.0, < 3.0)
45
- rubocop-ast (1.31.2)
46
- parser (>= 3.3.0.4)
46
+ rubocop-ast (1.31.3)
47
+ parser (>= 3.3.1.0)
47
48
  ruby-progressbar (1.13.0)
48
49
  stringio (3.1.0)
49
- sus (0.24.6)
50
+ strscan (3.1.0)
51
+ sus (0.25.0)
50
52
  unicode-display_width (2.5.0)
51
53
 
52
54
  PLATFORMS
data/README.md CHANGED
@@ -26,6 +26,16 @@ end
26
26
  If an invalid argument is given to `User#create`, for example, if `age` is a `String` instead of
27
27
  the required `Integer`, a `Delivered::ArgumentError` exception will be raised.
28
28
 
29
+ ### Single and Double Splat Arguments
30
+
31
+ You can use single and double splats in your method signatures, and Delivered will pass them through
32
+ without checking, while still checking the other named positional and keyword arguments.
33
+
34
+ ```ruby
35
+ sig String
36
+ def create(name, *args, foo:, **kwargs); end
37
+ ```
38
+
29
39
  ### Return Types
30
40
 
31
41
  You can also check the return value of the method by passing a Hash with an Array as the key, and
@@ -73,6 +83,15 @@ sig validate: T.Boolean
73
83
  def create(validate:); end
74
84
  ```
75
85
 
86
+ #### `RespondTo`
87
+
88
+ Value **MUST** be respond to the given method(s).
89
+
90
+ ```ruby
91
+ sig name: T.RespondTo(:to_s)
92
+ def create(name:); end
93
+ ```
94
+
76
95
  #### `Any`
77
96
 
78
97
  Value **MUST** be any of the given list of values, that is, the value must be one of the given list.
@@ -3,8 +3,6 @@
3
3
  module Delivered
4
4
  module Signature
5
5
  def sig(*sig_args, **sig_kwargs, &return_blk)
6
- # ap [sig_args, sig_kwargs, return_blk]
7
-
8
6
  # Block return
9
7
  returns = return_blk&.call
10
8
 
@@ -20,32 +18,32 @@ module Delivered
20
18
  sig_kwargs = sig_args.pop if sig_args.last.is_a?(Hash)
21
19
  end
22
20
 
23
- # ap [sig_args, sig_kwargs, returns]
21
+ # ap(sig_args:, sig_kwargs:)
24
22
 
25
23
  meta = class << self; self; end
26
24
  sig_check = lambda do |klass, class_method, name, *args, **kwargs, &block| # rubocop:disable Metrics/BlockLength
27
- cname = if class_method
28
- "#{klass.name}.#{name}"
29
- else
30
- "#{klass.class.name}##{name}"
31
- end
25
+ # ap(args:, kwargs:, params: klass.method(:"__#{name}").parameters)
26
+
27
+ cname = class_method ? "#{klass.name}.#{name}" : "#{klass.class.name}##{name}"
32
28
 
33
29
  sig_args.each.with_index do |arg, i|
34
30
  args[i] => ^arg
35
31
  rescue NoMatchingPatternError => e
36
32
  raise Delivered::ArgumentError,
37
- "`#{cname}` expected `#{arg}` as positional arg #{i}, but received " \
33
+ "`#{cname}` expected #{arg.inspect} as argument #{i}, but received " \
38
34
  "`#{args[i].inspect}`",
39
35
  caller, cause: e
40
36
  end
41
37
 
42
- kwargs.each do |key, value|
43
- value => ^(sig_kwargs[key])
44
- rescue NoMatchingPatternError => e
45
- raise Delivered::ArgumentError,
46
- "`#{cname}` expected `#{sig_kwargs[key]}` as keyword arg :#{key}, but received " \
47
- "`#{value.inspect}`",
48
- caller, cause: e
38
+ unless sig_kwargs.empty?
39
+ kwargs.each do |key, value|
40
+ value => ^(sig_kwargs[key])
41
+ rescue NoMatchingPatternError => e
42
+ raise Delivered::ArgumentError,
43
+ "`#{cname}` expected #{sig_kwargs[key].inspect} as keyword argument :#{key}, " \
44
+ "but received `#{value.inspect}`",
45
+ caller, cause: e
46
+ end
49
47
  end
50
48
 
51
49
  result = if block
@@ -58,13 +56,15 @@ module Delivered
58
56
  result => ^returns unless returns.nil?
59
57
  rescue NoMatchingPatternError => e
60
58
  raise Delivered::ArgumentError,
61
- "`#{cname}` expected to return `#{returns}`, but returned `#{result.inspect}`",
59
+ "`#{cname}` expected to return #{returns.inspect}, " \
60
+ "but returned `#{result.inspect}`",
62
61
  caller, cause: e
63
62
  end
64
63
 
65
64
  result
66
65
  end
67
66
 
67
+ # Instance method redefinition
68
68
  meta.send :define_method, :method_added do |name|
69
69
  meta.send :remove_method, :method_added
70
70
  meta.send :remove_method, :singleton_method_added
@@ -75,6 +75,7 @@ module Delivered
75
75
  end
76
76
  end
77
77
 
78
+ # Class method redefinition
78
79
  meta.send :define_method, :singleton_method_added do |name|
79
80
  next if name == :singleton_method_added
80
81
 
@@ -6,16 +6,32 @@ module Delivered
6
6
  @types = types
7
7
  end
8
8
 
9
+ def inspect = "Any(#{@types.map(&:inspect).join(', ')})"
10
+
9
11
  def ===(value)
10
12
  @types.empty? ? true : @types.any? { |type| type === value }
11
13
  end
12
14
  end
13
15
 
16
+ class RespondToType
17
+ def initialize(*methods)
18
+ @methods = methods
19
+ end
20
+
21
+ def inspect = "RespondTo(#{@methods.map(&:inspect).join(', ')})"
22
+
23
+ def ===(value)
24
+ @methods.all? { |m| value.respond_to?(m) }
25
+ end
26
+ end
27
+
14
28
  class NilableType
15
29
  def initialize(type = nil)
16
30
  @type = type
17
31
  end
18
32
 
33
+ def inspect = "Nilable(#{@type&.inspect || 'Any'})"
34
+
19
35
  def ===(value)
20
36
  (@type.nil? ? true : nil === value) || @type === value
21
37
  end
@@ -26,6 +42,8 @@ module Delivered
26
42
  freeze
27
43
  end
28
44
 
45
+ def inspect = 'Boolean'
46
+
29
47
  def ===(value)
30
48
  [true, false].include?(value)
31
49
  end
@@ -35,6 +53,7 @@ module Delivered
35
53
  module_function
36
54
 
37
55
  def Nilable(type = nil) = NilableType.new(type)
56
+ def RespondTo(*methods) = RespondToType.new(*methods)
38
57
  def Any(*types) = AnyType.new(*types)
39
58
  def Boolean = BooleanType.new
40
59
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delivered
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delivered
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-04 00:00:00.000000000 Z
11
+ date: 2024-05-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -49,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
49
  - !ruby/object:Gem::Version
50
50
  version: '0'
51
51
  requirements: []
52
- rubygems_version: 3.5.7
52
+ rubygems_version: 3.5.10
53
53
  signing_key:
54
54
  specification_version: 4
55
55
  summary: Simple runtime type checking for Ruby method signatures