delivered 0.2.0 → 0.4.0

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: 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