typerb 0.1.8 → 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: 9ee985e57292c037f842de48682659f4fb90e6f18d26811e065c4b32983a5bbb
4
- data.tar.gz: f4960c88faa5d885690405c70a514cbcea191e12964f7e83b50d925bb0848911
3
+ metadata.gz: 540b60be5aed7792e525d276c23d892343db1ea43db239d5c4b6df3664011d65
4
+ data.tar.gz: 9176075161a22f47297e406854b58f7420832630a8792c70b8dd0c49a0049860
5
5
  SHA512:
6
- metadata.gz: c816163ee5396ecfcd09234b9e2590b8a75bc06ef6ea839897da6bc2722c44bbe9bdbc3c1aef75858be28ae6df118ad834e6548b68449a140381d3188b3d9684
7
- data.tar.gz: 84a1286086584e24305f1816f93cf573bef0a257f7fb541e223986e260697c780ea14d6c22fe9cc59857df95e99f1be4f4a438a9b48265072b055d3823dc5819
6
+ metadata.gz: 68ab68e33e41b5f07790814d387bd74f6924445ee44b5faf78d4a80077466ffd8c323fdff4850e746cb2ed8a08bfc3b11c576fdd6ad29014a7f116d0b758bf2e
7
+ data.tar.gz: 4bc5f3c347f2a61006e3097af2a96684a80fcc8b3471957be016466844667083092b050a2bebe564ded578365ec901ef5f11a9a1d14dfb86e21a331a2cb97c6a
@@ -0,0 +1,24 @@
1
+ name: CI RSpec & Rubocop
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+
9
+ strategy:
10
+ matrix:
11
+ ruby-version: [2.5.3, 2.6.0, 2.7.4, 3.0.1, 3.1.0]
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby ${{ matrix.ruby-version }}
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby-version }}
19
+ - name: Install dependencies
20
+ run: bundle install
21
+ - name: Run Rubocop
22
+ run: bundle exec rubocop -DP
23
+ - name: Run tests
24
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -11,3 +11,5 @@
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
14
+
15
+ .ruby-version
data/.rubocop.yml CHANGED
@@ -1,5 +1,7 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.4
2
+ TargetRubyVersion: 3.1
3
+ NewCops: enable
4
+ SuggestExtensions: false
3
5
  Exclude:
4
6
  - 'bin/**/*'
5
7
  - 'Guardfile'
@@ -17,5 +19,17 @@ Style/Documentation:
17
19
  Style/Semicolon:
18
20
  Enabled: false
19
21
 
20
- Metrics/LineLength:
22
+ Style/StringConcatenation:
23
+ Enabled: false
24
+
25
+ Layout/SpaceAroundMethodCallOperator:
26
+ Enabled: false
27
+
28
+ Gemspec/RequiredRubyVersion:
29
+ Enabled: false
30
+
31
+ Layout/LineLength:
21
32
  Max: 170
33
+
34
+ Gemspec/RequireMFA:
35
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,24 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- typerb (0.1.7)
4
+ typerb (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- ast (2.4.0)
10
- awesome_print (1.8.0)
11
- coderay (1.1.2)
12
- diff-lcs (1.3)
13
- ffi (1.9.25)
14
- formatador (0.2.5)
15
- guard (2.15.0)
9
+ ast (2.4.2)
10
+ awesome_print (1.9.2)
11
+ coderay (1.1.3)
12
+ diff-lcs (1.5.0)
13
+ ffi (1.15.5)
14
+ formatador (0.3.0)
15
+ guard (2.18.0)
16
16
  formatador (>= 0.2.4)
17
17
  listen (>= 2.7, < 4.0)
18
18
  lumberjack (>= 1.0.12, < 2.0)
19
19
  nenv (~> 0.1)
20
20
  notiffany (~> 0.0)
21
- pry (>= 0.9.12)
21
+ pry (>= 0.13.0)
22
22
  shellany (~> 0.0)
23
23
  thor (>= 0.18.1)
24
24
  guard-compat (1.2.1)
@@ -26,57 +26,58 @@ GEM
26
26
  guard (~> 2.1)
27
27
  guard-compat (~> 1.1)
28
28
  rspec (>= 2.99.0, < 4.0)
29
- jaro_winkler (1.5.1)
30
- listen (3.1.5)
31
- rb-fsevent (~> 0.9, >= 0.9.4)
32
- rb-inotify (~> 0.9, >= 0.9.7)
33
- ruby_dep (~> 1.2)
34
- lumberjack (1.0.13)
35
- method_source (0.9.2)
29
+ listen (3.7.1)
30
+ rb-fsevent (~> 0.10, >= 0.10.3)
31
+ rb-inotify (~> 0.9, >= 0.9.10)
32
+ lumberjack (1.2.8)
33
+ method_source (1.0.0)
36
34
  nenv (0.3.0)
37
- notiffany (0.1.1)
35
+ notiffany (0.1.3)
38
36
  nenv (~> 0.1)
39
37
  shellany (~> 0.0)
40
- parallel (1.12.1)
41
- parser (2.5.3.0)
42
- ast (~> 2.4.0)
43
- powerpack (0.1.2)
44
- pry (0.12.2)
45
- coderay (~> 1.1.0)
46
- method_source (~> 0.9.0)
47
- rainbow (3.0.0)
48
- rake (12.3.2)
49
- rb-fsevent (0.10.3)
50
- rb-inotify (0.9.10)
51
- ffi (>= 0.5.0, < 2)
52
- rspec (3.8.0)
53
- rspec-core (~> 3.8.0)
54
- rspec-expectations (~> 3.8.0)
55
- rspec-mocks (~> 3.8.0)
56
- rspec-core (3.8.0)
57
- rspec-support (~> 3.8.0)
58
- rspec-expectations (3.8.2)
38
+ parallel (1.21.0)
39
+ parser (3.1.0.0)
40
+ ast (~> 2.4.1)
41
+ pry (0.14.1)
42
+ coderay (~> 1.1)
43
+ method_source (~> 1.0)
44
+ rainbow (3.1.1)
45
+ rake (13.0.6)
46
+ rb-fsevent (0.11.0)
47
+ rb-inotify (0.10.1)
48
+ ffi (~> 1.0)
49
+ regexp_parser (2.2.0)
50
+ rexml (3.2.5)
51
+ rspec (3.10.0)
52
+ rspec-core (~> 3.10.0)
53
+ rspec-expectations (~> 3.10.0)
54
+ rspec-mocks (~> 3.10.0)
55
+ rspec-core (3.10.1)
56
+ rspec-support (~> 3.10.0)
57
+ rspec-expectations (3.10.2)
59
58
  diff-lcs (>= 1.2.0, < 2.0)
60
- rspec-support (~> 3.8.0)
61
- rspec-mocks (3.8.0)
59
+ rspec-support (~> 3.10.0)
60
+ rspec-mocks (3.10.2)
62
61
  diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.8.0)
64
- rspec-support (3.8.0)
65
- rubocop (0.61.1)
66
- jaro_winkler (~> 1.5.1)
62
+ rspec-support (~> 3.10.0)
63
+ rspec-support (3.10.3)
64
+ rubocop (1.24.1)
67
65
  parallel (~> 1.10)
68
- parser (>= 2.5, != 2.5.1.1)
69
- powerpack (~> 0.1)
66
+ parser (>= 3.0.0.0)
70
67
  rainbow (>= 2.2.2, < 4.0)
68
+ regexp_parser (>= 1.8, < 3.0)
69
+ rexml
70
+ rubocop-ast (>= 1.15.1, < 2.0)
71
71
  ruby-progressbar (~> 1.7)
72
- unicode-display_width (~> 1.4.0)
73
- ruby-progressbar (1.10.0)
74
- ruby_dep (1.5.0)
72
+ unicode-display_width (>= 1.4.0, < 3.0)
73
+ rubocop-ast (1.15.1)
74
+ parser (>= 3.0.1.1)
75
+ ruby-progressbar (1.11.0)
75
76
  shellany (0.0.1)
76
77
  super_awesome_print (0.2.5)
77
78
  awesome_print
78
- thor (0.20.3)
79
- unicode-display_width (1.4.0)
79
+ thor (1.2.1)
80
+ unicode-display_width (2.1.0)
80
81
 
81
82
  PLATFORMS
82
83
  ruby
@@ -93,4 +94,4 @@ DEPENDENCIES
93
94
  typerb!
94
95
 
95
96
  BUNDLED WITH
96
- 1.17.2
97
+ 2.3.5
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/typerb.svg)](https://badge.fury.io/rb/typerb)
2
- [![Build Status](https://travis-ci.org/olegantonyan/typerb.svg?branch=master)](https://travis-ci.org/olegantonyan/typerb)
2
+ [![CI RSpec & Rubocop](https://github.com/olegantonyan/typerb/actions/workflows/tests.yml/badge.svg)](https://github.com/olegantonyan/typerb/actions/workflows/tests.yml)
3
3
 
4
4
  # Typerb
5
5
 
@@ -17,10 +17,19 @@ class A
17
17
  some_arg.respond_to!(:strip)
18
18
  end
19
19
 
20
+ def call_with_enum(arg)
21
+ arg.enum!(:one, :two)
22
+ end
23
+
24
+ def call_with_subset(arg)
25
+ arg.subset_of!([:one, :two])
26
+ end
20
27
  end
21
28
 
22
29
  A.new.call(1) #=> TypeError: `some_arg` should be String or Symbol, not Integer
23
30
  A.new.call_with_respond_checks(1) #=> TypeError: 'Integer should respond to all methods: strip'
31
+ A.new.call_with_enum(:three) #=> TypeError: 'Symbol (`arg`) should be one of: [one, two], not three'
32
+ A.new.call_with_subset([:one, :three]) #=> TypeError: 'Array (`arg`) should be subset of: [:one, :two], not [:one, :three]'
24
33
  ```
25
34
 
26
35
  This is equivalent to:
@@ -52,6 +61,11 @@ end
52
61
  A.new.call(nil) #=> TypeError: expected not nil, but got nil
53
62
  ```
54
63
 
64
+ ## Why?
65
+
66
+ 1. Catch error as early as possible (especially nils);
67
+ 2. Additional documentation: you're telling other people more about interfaces.
68
+
55
69
  ## Installation
56
70
 
57
71
  Add this line to your application's Gemfile:
@@ -100,7 +114,7 @@ end
100
114
 
101
115
  If you're unfamiliar with `using` keyword - this is refinement - a relatively new feature in Ruby (since 2.0). It's kind of monkey-patch, but with strict scope. Learn more about [refinements](https://ruby-doc.org/core-2.5.3/doc/syntax/refinements_rdoc.html).
102
116
 
103
- This refinement adds `type!()` and `not_nil!` methods to `Object` class so you can call it on almost much any object (except those inherited from `BasicObject`, but these are rare).
117
+ This refinement adds `type!()` and `not_nil!` methods to `BasicObject` class so you can call it on any object.
104
118
 
105
119
  The method will raise an exception if `self` is not an instance of one of the classes passed as arguments. The tricky part, however, is to get the variable name on which it's called. You need this to get a nice error message telling you exactly which variable has wrong type, not just an abstract `TypeError`. That's why we need Ruby 2.6 with its new `RubyVM::AST` (https://ruby-doc.org/core-2.6.0.preview3/RubyVM/AST.html).
106
120
 
@@ -10,6 +10,14 @@ module Typerb
10
10
  def methods_text(methods)
11
11
  methods.join(', ')
12
12
  end
13
+
14
+ def elements_text(elements)
15
+ '[' + elements.join(', ') + ']'
16
+ end
17
+
18
+ def superset_text(enumerable)
19
+ enumerable.to_s
20
+ end
13
21
  end
14
22
 
15
23
  def raise_with(backtrace, exception_text)
@@ -10,7 +10,7 @@ module Typerb
10
10
  end
11
11
 
12
12
  def get
13
- return if RUBY_VERSION < '2.6.0'
13
+ return unless defined?(RubyVM::AbstractSyntaxTree)
14
14
  return unless File.exist?(file)
15
15
 
16
16
  caller_method = caller_locations(1, 1)[0].label.to_sym
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Typerb
4
- VERSION = '0.1.8'
4
+ VERSION = '0.4.0'
5
5
  end
data/lib/typerb.rb CHANGED
@@ -5,7 +5,7 @@ require 'typerb/variable_name'
5
5
  require 'typerb/exceptional'
6
6
 
7
7
  module Typerb
8
- refine Object do
8
+ refine BasicObject do
9
9
  def type!(*klasses)
10
10
  raise ArgumentError, 'provide at least one class' if klasses.empty?
11
11
  return self if klasses.any? { |kls| is_a?(kls) }
@@ -45,5 +45,34 @@ module Typerb
45
45
 
46
46
  Typerb::Exceptional.new.raise_with(caller, exception_text)
47
47
  end
48
+
49
+ def enum!(*elements)
50
+ raise ArgumentError, 'provide at least one enum element' if elements.empty?
51
+ return self if elements.include?(self)
52
+
53
+ elements_text = Typerb::Exceptional.elements_text(elements)
54
+ exception_text = if (var_name = Typerb::VariableName.new(caller_locations(1, 1)).get)
55
+ "#{self.class} (`#{var_name}`) should be one of: #{elements_text}, not #{self}"
56
+ else
57
+ "#{self.class} expected one of: #{elements_text}, got #{self}"
58
+ end
59
+
60
+ Typerb::Exceptional.new.raise_with(caller, exception_text)
61
+ end
62
+
63
+ def subset_of!(superset)
64
+ raise ArgumentError, 'superset must be Enumerable' unless superset.is_a?(Enumerable)
65
+ raise ArgumentError, 'provide at least one superset element' if superset.empty?
66
+ return self if (self - superset).empty?
67
+
68
+ superset_text = Typerb::Exceptional.superset_text(superset)
69
+ exception_text = if (var_name = Typerb::VariableName.new(caller_locations(1, 1)).get)
70
+ "#{self.class} (`#{var_name}`) should be subset of: #{superset_text}, not #{self}"
71
+ else
72
+ "#{self.class} expected subset of: #{superset_text}, got #{self}"
73
+ end
74
+
75
+ Typerb::Exceptional.new.raise_with(caller, exception_text)
76
+ end
48
77
  end
49
78
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typerb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Antonyan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-12 00:00:00.000000000 Z
11
+ date: 2022-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -129,11 +129,10 @@ executables: []
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
+ - ".github/workflows/tests.yml"
132
133
  - ".gitignore"
133
134
  - ".rspec"
134
135
  - ".rubocop.yml"
135
- - ".ruby-version"
136
- - ".travis.yml"
137
136
  - CODE_OF_CONDUCT.md
138
137
  - Gemfile
139
138
  - Gemfile.lock
@@ -152,7 +151,7 @@ homepage: https://github.com/olegantonyan/typerb
152
151
  licenses:
153
152
  - MIT
154
153
  metadata: {}
155
- post_install_message:
154
+ post_install_message:
156
155
  rdoc_options: []
157
156
  require_paths:
158
157
  - lib
@@ -167,9 +166,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
166
  - !ruby/object:Gem::Version
168
167
  version: '0'
169
168
  requirements: []
170
- rubyforge_project:
171
- rubygems_version: 3.0.0.beta3
172
- signing_key:
169
+ rubygems_version: 3.3.3
170
+ signing_key:
173
171
  specification_version: 4
174
172
  summary: Typecheck sugar for Ruby.
175
173
  test_files: []
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.6.0-rc1
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- before_install: gem install bundler
6
-
7
- rvm:
8
- - 2.4.0
9
- - 2.5.3
10
- - 2.6.0-rc1
11
-
12
- script:
13
- - bundle exec rubocop -DP
14
- - bundle exec rspec