speculation 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +0 -3
- data/README.md +14 -27
- data/bin/console +2 -2
- data/examples/sinatra-web-app/Gemfile +7 -0
- data/examples/sinatra-web-app/Gemfile.lock +46 -0
- data/examples/sinatra-web-app/app.rb +153 -0
- data/examples/sinatra-web-app/test +16 -0
- data/lib/speculation.rb +21 -26
- data/lib/speculation/{spec_impl.rb → spec.rb} +11 -11
- data/lib/speculation/{spec_impl → spec}/and_spec.rb +2 -2
- data/lib/speculation/{spec_impl → spec}/every_spec.rb +4 -4
- data/lib/speculation/{spec_impl → spec}/f_spec.rb +3 -3
- data/lib/speculation/{spec_impl → spec}/hash_spec.rb +20 -34
- data/lib/speculation/{spec_impl → spec}/merge_spec.rb +2 -2
- data/lib/speculation/{spec_impl → spec}/nilable_spec.rb +1 -1
- data/lib/speculation/{spec_impl → spec}/or_spec.rb +2 -2
- data/lib/speculation/{spec_impl/spec.rb → spec/predicate_spec.rb} +2 -2
- data/lib/speculation/{spec_impl → spec}/regex_spec.rb +2 -2
- data/lib/speculation/{spec_impl → spec}/tuple_spec.rb +3 -3
- data/lib/speculation/test.rb +5 -5
- data/lib/speculation/version.rb +1 -1
- metadata +17 -28
- data/bin/bundler +0 -17
- data/bin/byebug +0 -17
- data/bin/coderay +0 -17
- data/bin/cucumber-queue +0 -17
- data/bin/minitest-queue +0 -17
- data/bin/pry +0 -17
- data/bin/rake +0 -17
- data/bin/rspec-queue +0 -17
- data/bin/rubocop +0 -17
- data/bin/ruby-parse +0 -17
- data/bin/ruby-rewrite +0 -17
- data/bin/testunit-queue +0 -17
- data/bin/yard +0 -17
- data/bin/yardoc +0 -17
- data/bin/yri +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11bb7e3c5871a34e1419aa9b02bfce56bdc334a2
|
4
|
+
data.tar.gz: b4d3470f9bb704a94b61f333a632f193a8baa21d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1db14032f7e8755385fcd56346c8d04e712b3faf496caa9ecd77784f2ae7442edd0addea2d757d19e418970cbf7a408e82cef6291436f20dc18420312c893092
|
7
|
+
data.tar.gz: '096a7f073629269c834a691a2ad370b9e8722ffdc97fd8885a60b2ec299c29cfb3ce90be6d43b8414a5669afe31468cd6f3a8b3fa2f588a2991a7272cbc7fe22'
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,34 +2,19 @@
|
|
2
2
|
|
3
3
|
A Ruby port of Clojure's `clojure.spec`. See [clojure.spec - Rationale and Overview](https://clojure.org/about/spec). All advantages/disadvantages for clojure.spec should apply to Speculation too. This library is largely a copy-and-paste from clojure.spec so all credit goes to the clojure.spec authors.
|
4
4
|
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
Add this line to your application's Gemfile:
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
gem 'speculation'
|
11
|
-
```
|
12
|
-
|
13
|
-
And then execute:
|
14
|
-
|
15
|
-
$ bundle
|
16
|
-
|
17
|
-
Or install it yourself as:
|
18
|
-
|
19
|
-
$ gem install speculation
|
20
|
-
|
21
5
|
## Project Goals
|
22
6
|
|
23
|
-
The goal of this project is to match clojure.spec as closely as possible, from design to features to API. This decision comes with the trade-off that the library may not necessarily be idiomatic Ruby, however there's nothing stopping other libraries from being built
|
7
|
+
The goal of this project is to match clojure.spec as closely as possible, from design to features to API. This decision comes with the trade-off that the library may not necessarily be idiomatic Ruby, however there's nothing stopping other libraries from being built on top of Speculation to bring a more Ruby-like feel. This library won't introduce features that do not exist in clojure.spec.
|
24
8
|
|
25
9
|
## Examples
|
26
10
|
|
11
|
+
- [sinatra-web-app](examples/sinatra-web-app): A small sinatra web application demonstrating model validation and API error message generation.
|
27
12
|
- [spec_guide.rb](examples/spec_guide.rb): Speculation port of Clojure's [spec guide](https://clojure.org/guides/spec)
|
28
13
|
- [codebreaker.rb](examples/codebreaker.rb): Speculation port of the 'codebreaker' game described in [Interactive development with clojure.spec](http://blog.cognitect.com/blog/2016/10/5/interactive-development-with-clojurespec)
|
29
14
|
|
30
15
|
## Usage
|
31
16
|
|
32
|
-
The API is more-or-less the same as `clojure.spec`. If you're already familiar with then you should
|
17
|
+
The API is more-or-less the same as `clojure.spec`. If you're already familiar clojure.spec with then you should feel at home with Speculation. Clojure and Ruby and quite different languages, so naturally there are some differences:
|
33
18
|
|
34
19
|
### Built in predicates
|
35
20
|
|
@@ -46,18 +31,20 @@ S.valid?(Set[:foo, :bar, :baz], :foo)
|
|
46
31
|
|
47
32
|
### Namespaced keywords/symbols
|
48
33
|
|
49
|
-
Namespaced keywords are at the core of `clojure.spec`. Since spec utilises a global spec registry, namespaced keywords allow libraries to register specs with the same names but under different namespaces, thus removing accidental collisions. Ruby's equivalent to Clojure's keywords are Symbols. Ruby Symbol's don't have namespaces.
|
34
|
+
Namespaced keywords are at the core of `clojure.spec`. Since clojure.spec utilises a global spec registry, namespaced keywords allow libraries to register specs with the same names but under different namespaces, thus removing accidental collisions. Ruby's equivalent to Clojure's keywords are Symbols. Ruby Symbol's don't have namespaces.
|
50
35
|
|
51
|
-
In order keep the global spec registry architecture in Speculation, we utilise a helper method `ns` achieve similar behaviour:
|
36
|
+
In order keep the global spec registry architecture in Speculation, we utilise a helper method `ns` to achieve similar behaviour:
|
52
37
|
|
53
38
|
```rb
|
54
|
-
|
39
|
+
module MyModule
|
40
|
+
extend Speculation::NamespacedSymbols
|
55
41
|
|
56
|
-
p ns(:foo)
|
57
|
-
# => :"MyModule/foo"
|
42
|
+
p ns(:foo)
|
43
|
+
# => :"MyModule/foo"
|
58
44
|
|
59
|
-
p ns(AnotherModule, :foo)
|
60
|
-
# => :"AnotherModule/foo"
|
45
|
+
p ns(AnotherModule, :foo)
|
46
|
+
# => :"AnotherModule/foo"
|
47
|
+
end
|
61
48
|
```
|
62
49
|
|
63
50
|
### FSpecs
|
@@ -90,9 +77,9 @@ S.fdef(method(:hello), :args => S.cat(:name => String),
|
|
90
77
|
|
91
78
|
#### Generators and quick check
|
92
79
|
|
93
|
-
Speculation uses [`Rantly`](https://github.com/abargnesi/rantly) for random data generation. Generator functions in Speculation are Procs that take one argument (Rantly instance) and return random value. While clojure's test.check generators generate values that start small and continue to grow and get more complex as a property holds true, Rantly always generates random values.
|
80
|
+
Speculation uses [`Rantly`](https://github.com/abargnesi/rantly) for random data generation. Generator functions in Speculation are Procs that take one argument (Rantly instance) and return a random value. While clojure's test.check generators generate values that start small and continue to grow and get more complex as a property holds true, Rantly always generates random values.
|
94
81
|
|
95
|
-
Rantly gives Speculation the ability to shrink a failing test case down to
|
82
|
+
Rantly gives Speculation the ability to shrink a failing test case down to its smallest failing case, however in Speculation we limit this to Integers and Strings. This is an area where Speculation may currently be significantly weaker than clojure.spec.
|
96
83
|
|
97
84
|
## Development
|
98
85
|
|
data/bin/console
CHANGED
@@ -23,9 +23,9 @@ def reload!
|
|
23
23
|
load "./lib/speculation/utils.rb"
|
24
24
|
load "./lib/speculation/error.rb"
|
25
25
|
|
26
|
-
load "./lib/speculation/
|
26
|
+
load "./lib/speculation/spec.rb"
|
27
27
|
|
28
|
-
Dir["lib/speculation/
|
28
|
+
Dir["lib/speculation/spec/*.rb"].each do |f|
|
29
29
|
load f
|
30
30
|
end
|
31
31
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/english/speculation.git
|
3
|
+
revision: ae3ee095765816a8d5bfa5b29c808439f04633b0
|
4
|
+
ref: ae3ee09
|
5
|
+
specs:
|
6
|
+
speculation (0.2.0)
|
7
|
+
concurrent-ruby (~> 1.0)
|
8
|
+
rantly (~> 1.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
bcrypt (3.1.11)
|
14
|
+
coderay (1.1.1)
|
15
|
+
concurrent-ruby (1.0.5)
|
16
|
+
method_source (0.8.2)
|
17
|
+
pry (0.10.4)
|
18
|
+
coderay (~> 1.1.0)
|
19
|
+
method_source (~> 0.8.1)
|
20
|
+
slop (~> 3.4)
|
21
|
+
rack (1.6.5)
|
22
|
+
rack-protection (1.5.3)
|
23
|
+
rack
|
24
|
+
rantly (1.0.0)
|
25
|
+
sequel (4.44.0)
|
26
|
+
sinatra (1.4.8)
|
27
|
+
rack (~> 1.5)
|
28
|
+
rack-protection (~> 1.4)
|
29
|
+
tilt (>= 1.3, < 3)
|
30
|
+
slop (3.6.0)
|
31
|
+
sqlite3 (1.3.13)
|
32
|
+
tilt (2.0.6)
|
33
|
+
|
34
|
+
PLATFORMS
|
35
|
+
ruby
|
36
|
+
|
37
|
+
DEPENDENCIES
|
38
|
+
bcrypt
|
39
|
+
pry
|
40
|
+
sequel
|
41
|
+
sinatra
|
42
|
+
speculation!
|
43
|
+
sqlite3
|
44
|
+
|
45
|
+
BUNDLED WITH
|
46
|
+
1.14.6
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'sequel'
|
4
|
+
require 'bcrypt'
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'speculation'
|
7
|
+
require 'speculation/gen'
|
8
|
+
require 'json'
|
9
|
+
|
10
|
+
S = Speculation
|
11
|
+
Gen = S::Gen
|
12
|
+
DB = Sequel.sqlite
|
13
|
+
|
14
|
+
DB.create_table :users do
|
15
|
+
primary_key :id
|
16
|
+
String :username
|
17
|
+
String :email
|
18
|
+
String :hashed_password
|
19
|
+
end
|
20
|
+
|
21
|
+
post '/users' do
|
22
|
+
user_attrs = symbolize_keys(params["user"])
|
23
|
+
|
24
|
+
if User.valid?(user_attrs)
|
25
|
+
User.create!(DB, user_attrs)
|
26
|
+
else
|
27
|
+
User.serialize_validation_errors(user_attrs).to_json
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
get '/users' do
|
32
|
+
users = User.all(DB)
|
33
|
+
users.to_json
|
34
|
+
end
|
35
|
+
|
36
|
+
get '/fake-user' do
|
37
|
+
User.fake
|
38
|
+
end
|
39
|
+
|
40
|
+
def symbolize_keys(hash)
|
41
|
+
hash.map { |k, v| [k.to_sym, v] }.to_h
|
42
|
+
end
|
43
|
+
|
44
|
+
module User
|
45
|
+
extend Speculation::NamespacedSymbols
|
46
|
+
|
47
|
+
def self.valid?(user)
|
48
|
+
S.valid?(ns(:user), user)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.create!(db, user)
|
52
|
+
hashed_password = BCrypt::Password.create(user[:password])
|
53
|
+
|
54
|
+
db[:users].insert(:email => user[:email],
|
55
|
+
:username => user[:username],
|
56
|
+
:hashed_password => hashed_password)
|
57
|
+
|
58
|
+
"success!"
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.all(db)
|
62
|
+
db[:users].all
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.serialize_validation_errors(user)
|
66
|
+
data = S.explain_data(ns(:user), user)
|
67
|
+
data[ns(S, :problems)].map { |problem| Validation.serialize_problem(problem) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.fake
|
71
|
+
Gen.generate(S.gen(ns(User, :user))).to_json
|
72
|
+
end
|
73
|
+
|
74
|
+
module Generators
|
75
|
+
def self.email(rantly)
|
76
|
+
local_part = rantly.sized(rantly.range(1, 64)) { string(:alnum) }
|
77
|
+
subdomain = rantly.sized(rantly.range(1, 10)) { string(:alnum) }
|
78
|
+
tld = rantly.sized(3) { string(:alpha).downcase }
|
79
|
+
|
80
|
+
"#{local_part}@#{subdomain}.#{tld}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.username(rantly)
|
84
|
+
rantly.sized(rantly.range(5, 20)) { rantly.string }
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.password(rantly)
|
88
|
+
[
|
89
|
+
rantly.sized(rantly.range(2, 5)) { rantly.string(:upper) },
|
90
|
+
rantly.sized(rantly.range(2, 5)) { rantly.string(:lower) },
|
91
|
+
rantly.sized(rantly.range(2, 5)) { rantly.string(:digit) },
|
92
|
+
rantly.sized(rantly.range(2, 5)) { rantly.string(:punct) }
|
93
|
+
].join.split("").shuffle.join
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
module Validation
|
98
|
+
def self.serialize_problem(problem)
|
99
|
+
path = problem[:path]
|
100
|
+
predicate, args = problem[:pred]
|
101
|
+
|
102
|
+
message = USER_ERROR_MESSAGE_MAP.fetch(path).fetch(predicate)
|
103
|
+
message = message.call(args) if message.respond_to?(:call)
|
104
|
+
|
105
|
+
{ :error => message }
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.validate_username_length(username)
|
109
|
+
username.length.between?(5, 20)
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.validate_password_length(password)
|
113
|
+
password.length.between?(8, 50)
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.validate_password_complexity(password)
|
117
|
+
[/[A-Z]/, /[a-z]/, /\d/, /\W/].all? { |re| password.match(re) }
|
118
|
+
end
|
119
|
+
|
120
|
+
EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/
|
121
|
+
|
122
|
+
USER_ERROR_MESSAGE_MAP = {
|
123
|
+
[] => {
|
124
|
+
S::Utils.method(:key?) => ->(args) {
|
125
|
+
key = args.first
|
126
|
+
if key == S.or_keys(:email, :username)
|
127
|
+
"email or username is required"
|
128
|
+
else
|
129
|
+
"#{key} is required"
|
130
|
+
end
|
131
|
+
}
|
132
|
+
},
|
133
|
+
[:username] => {
|
134
|
+
String => "username must be a string",
|
135
|
+
method(:validate_username_length) => "username must be between 5 and 20 characters",
|
136
|
+
},
|
137
|
+
[:email] => {
|
138
|
+
String => "email must be a string",
|
139
|
+
EMAIL_REGEX => "email must be a valid email address"
|
140
|
+
},
|
141
|
+
[:password] => {
|
142
|
+
String => "password must be a string",
|
143
|
+
method(:validate_password_length) => "password must be between 8 and 50 characters",
|
144
|
+
method(:validate_password_complexity) => "password must contain at least one of each: upper case, lower case, numeric and special characters"
|
145
|
+
}
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
S.def ns(:email), S.with_gen(S.and(String, Validation::EMAIL_REGEX), Generators.method(:email))
|
150
|
+
S.def ns(:username), S.with_gen(S.and(String, Validation.method(:validate_username_length)), Generators.method(:username))
|
151
|
+
S.def ns(:password), S.with_gen(S.and(String, Validation.method(:validate_password_length), Validation.method(:validate_password_complexity)), Generators.method(:password))
|
152
|
+
S.def ns(:user), S.keys(:req_un => [S.or_keys(ns(:email), ns(:username)), ns(:password)])
|
153
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
set -o xtrace
|
2
|
+
|
3
|
+
curl -s -X POST -d 'user[email]=someone@example.com&user[psasword]=abc123!@ASD' http://localhost:4567/users | jq -c .
|
4
|
+
# => [{"error":"password is required"}]
|
5
|
+
|
6
|
+
curl -s -X POST -d 'user[email]=someone@example.com&user[password]=abc123' http://localhost:4567/users | jq -c .
|
7
|
+
# => [{"error":"password must be between 8 and 50 characters"}]
|
8
|
+
|
9
|
+
curl -s -X POST -d 'user[username]=anonymous&user[password]=test123456' http://localhost:4567/users | jq -c .
|
10
|
+
# => [{"error":"password must contain at least one of each: upper case, lower case, numeric and special characters"}]
|
11
|
+
|
12
|
+
curl -s -X POST -d 'user[username]=anonymous&user[password]=abc123!_ASD' http://localhost:4567/users
|
13
|
+
# => success!
|
14
|
+
|
15
|
+
curl -s http://localhost:4567/users | jq -c .
|
16
|
+
# => [{"id":1,"username":"anonymous","email":null,"hashed_password":"$2a$10$TMLSJNNj4K4YtpMmx.4hTOxh0lg0WsIQbFkY6v8ssuMBtMoJ2oCG6"}]
|
data/lib/speculation.rb
CHANGED
@@ -7,7 +7,7 @@ require "speculation/version"
|
|
7
7
|
require "speculation/namespaced_symbols"
|
8
8
|
require "speculation/identifier"
|
9
9
|
require "speculation/utils"
|
10
|
-
require "speculation/
|
10
|
+
require "speculation/spec"
|
11
11
|
require "speculation/error"
|
12
12
|
|
13
13
|
module Speculation
|
@@ -42,6 +42,8 @@ module Speculation
|
|
42
42
|
|
43
43
|
@registry_ref = Concurrent::Atom.new({})
|
44
44
|
|
45
|
+
INVALID = ns(:invalid)
|
46
|
+
|
45
47
|
# Can be enabled or disabled at runtime:
|
46
48
|
# - enabled/disabled by setting `check_asserts`.
|
47
49
|
# - enabled by setting environment variable SPECULATION_CHECK_ASSERTS to the
|
@@ -108,7 +110,7 @@ module Speculation
|
|
108
110
|
# @param x [Spec, Object]
|
109
111
|
# @return [Spec, false] x if x is a spec, else false
|
110
112
|
def self.spec?(x)
|
111
|
-
x if x.is_a?(
|
113
|
+
x if x.is_a?(Spec)
|
112
114
|
end
|
113
115
|
|
114
116
|
# @param x [Hash, Object]
|
@@ -120,7 +122,7 @@ module Speculation
|
|
120
122
|
# @param value return value of a `conform` call
|
121
123
|
# @return [Boolean] true if value is the result of an unsuccessful conform
|
122
124
|
def self.invalid?(value)
|
123
|
-
value.equal?(
|
125
|
+
value.equal?(INVALID)
|
124
126
|
end
|
125
127
|
|
126
128
|
# @param spec [Spec]
|
@@ -661,11 +663,11 @@ module Speculation
|
|
661
663
|
if spec
|
662
664
|
conform(spec, x)
|
663
665
|
elsif pred.is_a?(Module) || pred.is_a?(::Regexp)
|
664
|
-
pred === x ? x :
|
666
|
+
pred === x ? x : INVALID
|
665
667
|
elsif pred.is_a?(Set)
|
666
|
-
pred.include?(x) ? x :
|
668
|
+
pred.include?(x) ? x : INVALID
|
667
669
|
elsif pred.respond_to?(:call)
|
668
|
-
pred.call(x) ? x :
|
670
|
+
pred.call(x) ? x : INVALID
|
669
671
|
else
|
670
672
|
raise "#{pred} is not a class, proc, set or regexp"
|
671
673
|
end
|
@@ -700,7 +702,7 @@ module Speculation
|
|
700
702
|
elsif Utils.ident?(pred)
|
701
703
|
the_spec(pred)
|
702
704
|
else
|
703
|
-
|
705
|
+
PredicateSpec.new(pred, should_conform)
|
704
706
|
end
|
705
707
|
end
|
706
708
|
|
@@ -810,7 +812,7 @@ module Speculation
|
|
810
812
|
x, *xs = data
|
811
813
|
|
812
814
|
if data.empty?
|
813
|
-
return
|
815
|
+
return INVALID unless accept_nil?(regex)
|
814
816
|
|
815
817
|
return_value = preturn(regex)
|
816
818
|
|
@@ -825,7 +827,7 @@ module Speculation
|
|
825
827
|
if dp
|
826
828
|
re_conform(dp, xs)
|
827
829
|
else
|
828
|
-
|
830
|
+
INVALID
|
829
831
|
end
|
830
832
|
end
|
831
833
|
end
|
@@ -953,7 +955,7 @@ module Speculation
|
|
953
955
|
x = dt(pred, x)
|
954
956
|
|
955
957
|
if invalid?(x)
|
956
|
-
|
958
|
+
INVALID
|
957
959
|
elsif preds.empty?
|
958
960
|
x
|
959
961
|
else
|
@@ -1286,22 +1288,15 @@ module Speculation
|
|
1286
1288
|
raise "Unexpected #{ns(:op)} #{p[ns(:op)]}"
|
1287
1289
|
end
|
1288
1290
|
end
|
1289
|
-
|
1290
|
-
# Resets the spec registry to only builtin specs
|
1291
|
-
def reset_registry!
|
1292
|
-
builtins = {
|
1293
|
-
ns(:any) => with_gen(Utils.constantly(true), ->(r) { r.branch(*Gen::GEN_BUILTINS.values) }),
|
1294
|
-
ns(:boolean) => Set[true, false],
|
1295
|
-
ns(:positive_integer) => with_gen(self.and(Integer, ->(x) { x > 0 }), ->(r) { r.range(1) }),
|
1296
|
-
# Rantly#positive_integer is actually a natural integer
|
1297
|
-
ns(:natural_integer) => with_gen(self.and(Integer, ->(x) { x >= 0 }), :positive_integer.to_proc),
|
1298
|
-
ns(:negative_integer) => with_gen(self.and(Integer, ->(x) { x < 0 }), ->(r) { r.range(nil, -1) }),
|
1299
|
-
ns(:empty) => with_gen(Utils.method(:empty?), Utils.constantly([]))
|
1300
|
-
}.freeze
|
1301
|
-
|
1302
|
-
@registry_ref.reset(builtins)
|
1303
|
-
end
|
1304
1291
|
end
|
1305
1292
|
|
1306
|
-
|
1293
|
+
@registry_ref.reset(
|
1294
|
+
ns(:any) => with_gen(Utils.constantly(true), ->(r) { r.branch(*Gen::GEN_BUILTINS.values) }),
|
1295
|
+
ns(:boolean) => Set[true, false],
|
1296
|
+
ns(:positive_integer) => with_gen(self.and(Integer, ->(x) { x > 0 }), ->(r) { r.range(1) }),
|
1297
|
+
# Rantly#positive_integer is actually a natural integer
|
1298
|
+
ns(:natural_integer) => with_gen(self.and(Integer, ->(x) { x >= 0 }), :positive_integer.to_proc),
|
1299
|
+
ns(:negative_integer) => with_gen(self.and(Integer, ->(x) { x < 0 }), ->(r) { r.range(nil, -1) }),
|
1300
|
+
ns(:empty) => with_gen(Utils.method(:empty?), Utils.constantly([]))
|
1301
|
+
)
|
1307
1302
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Speculation
|
4
4
|
# @private
|
5
|
-
class
|
5
|
+
class Spec
|
6
6
|
attr_accessor :name, :gen
|
7
7
|
attr_reader :id
|
8
8
|
|
@@ -24,13 +24,13 @@ module Speculation
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
require_relative "
|
28
|
-
require_relative "
|
29
|
-
require_relative "
|
30
|
-
require_relative "
|
31
|
-
require_relative "
|
32
|
-
require_relative "
|
33
|
-
require_relative "
|
34
|
-
require_relative "
|
35
|
-
require_relative "
|
36
|
-
require_relative "
|
27
|
+
require_relative "spec/hash_spec"
|
28
|
+
require_relative "spec/predicate_spec"
|
29
|
+
require_relative "spec/tuple_spec"
|
30
|
+
require_relative "spec/or_spec"
|
31
|
+
require_relative "spec/and_spec"
|
32
|
+
require_relative "spec/merge_spec"
|
33
|
+
require_relative "spec/every_spec"
|
34
|
+
require_relative "spec/regex_spec"
|
35
|
+
require_relative "spec/f_spec"
|
36
|
+
require_relative "spec/nilable_spec"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Speculation
|
4
4
|
# @private
|
5
|
-
class AndSpec <
|
5
|
+
class AndSpec < Spec
|
6
6
|
include NamespacedSymbols
|
7
7
|
S = Speculation
|
8
8
|
|
@@ -17,7 +17,7 @@ module Speculation
|
|
17
17
|
@specs.value!.each do |spec|
|
18
18
|
value = spec.conform(value)
|
19
19
|
|
20
|
-
return
|
20
|
+
return S::INVALID if S.invalid?(value)
|
21
21
|
end
|
22
22
|
|
23
23
|
value
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class EverySpec <
|
4
|
+
class EverySpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -55,7 +55,7 @@ module Speculation
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def conform(value)
|
58
|
-
return
|
58
|
+
return S::INVALID unless @collection_predicate.call(value)
|
59
59
|
|
60
60
|
spec = @delayed_spec.value!
|
61
61
|
|
@@ -68,7 +68,7 @@ module Speculation
|
|
68
68
|
conformed_value = spec.conform(val)
|
69
69
|
|
70
70
|
if S.invalid?(conformed_value)
|
71
|
-
return
|
71
|
+
return S::INVALID
|
72
72
|
else
|
73
73
|
return_value = add.call(return_value, index, val, conformed_value)
|
74
74
|
end
|
@@ -81,7 +81,7 @@ module Speculation
|
|
81
81
|
|
82
82
|
value.each_with_index do |item, index|
|
83
83
|
return value if index == limit
|
84
|
-
return
|
84
|
+
return S::INVALID unless S.valid?(spec, item)
|
85
85
|
end
|
86
86
|
|
87
87
|
value
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Speculation
|
4
4
|
# @private
|
5
|
-
class FSpec <
|
5
|
+
class FSpec < Spec
|
6
6
|
include NamespacedSymbols
|
7
7
|
S = Speculation
|
8
8
|
|
@@ -18,14 +18,14 @@ module Speculation
|
|
18
18
|
def conform(f)
|
19
19
|
raise "Can't conform fspec without args spec: #{inspect}" unless @args
|
20
20
|
|
21
|
-
return
|
21
|
+
return S::INVALID unless f.is_a?(Proc) || f.is_a?(Method)
|
22
22
|
|
23
23
|
specs = { :args => @args, :ret => @ret, :fn => @fn, :block => @block }
|
24
24
|
|
25
25
|
if f.equal?(FSpec.validate_fn(f, specs, S.fspec_iterations))
|
26
26
|
f
|
27
27
|
else
|
28
|
-
|
28
|
+
S::INVALID
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class HashSpec <
|
4
|
+
class HashSpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -34,11 +34,11 @@ module Speculation
|
|
34
34
|
@opt_keys = opt + opt_un.map(&method(:unqualify_key))
|
35
35
|
@opt_specs = opt + opt_un
|
36
36
|
@keys_pred = ->(v) { pred_exprs.all? { |p| p.call(v) } }
|
37
|
-
@key_to_spec_map = Hash[
|
37
|
+
@key_to_spec_map = Hash[Utils.conj(req_keys, @opt_keys).zip(Utils.conj(req_specs, @opt_specs))]
|
38
38
|
end
|
39
39
|
|
40
40
|
def conform(value)
|
41
|
-
return
|
41
|
+
return S::INVALID unless @keys_pred.call(value)
|
42
42
|
|
43
43
|
reg = S.registry
|
44
44
|
ret = value
|
@@ -52,7 +52,7 @@ module Speculation
|
|
52
52
|
conformed_value = S.conform(spec, v)
|
53
53
|
|
54
54
|
if S.invalid?(conformed_value)
|
55
|
-
return
|
55
|
+
return S::INVALID
|
56
56
|
else
|
57
57
|
unless conformed_value.equal?(v)
|
58
58
|
ret = ret.merge(key => conformed_value)
|
@@ -74,8 +74,7 @@ module Speculation
|
|
74
74
|
failures = parse_req(@req, value, Utils.method(:itself))
|
75
75
|
|
76
76
|
failures.each do |failure_sexp|
|
77
|
-
|
78
|
-
pred = [Utils.method(:key?), [sexp_to_rb(failure_sexp)]]
|
77
|
+
pred = [Utils.method(:key?), [failure_sexp]]
|
79
78
|
problems << { :path => path, :pred => pred, :val => value, :via => via, :in => inn }
|
80
79
|
end
|
81
80
|
end
|
@@ -84,7 +83,7 @@ module Speculation
|
|
84
83
|
failures = parse_req(@req_un, value, method(:unqualify_key))
|
85
84
|
|
86
85
|
failures.each do |failure_sexp|
|
87
|
-
pred = [Utils.method(:key?), [
|
86
|
+
pred = [Utils.method(:key?), [failure_sexp]]
|
88
87
|
problems << { :path => path, :pred => pred, :val => value, :via => via, :in => inn }
|
89
88
|
end
|
90
89
|
end
|
@@ -135,29 +134,6 @@ module Speculation
|
|
135
134
|
|
136
135
|
private
|
137
136
|
|
138
|
-
def sexp_to_rb(sexp, level = 0)
|
139
|
-
if sexp.is_a?(Array)
|
140
|
-
op, *keys = sexp
|
141
|
-
rb_string = String.new
|
142
|
-
|
143
|
-
rb_string << "(" unless level.zero?
|
144
|
-
|
145
|
-
keys.each_with_index do |key, i|
|
146
|
-
unless i.zero?
|
147
|
-
rb_string << " #{NamespacedSymbols.name(op)} "
|
148
|
-
end
|
149
|
-
|
150
|
-
rb_string << sexp_to_rb(key, level + 1).to_s
|
151
|
-
end
|
152
|
-
|
153
|
-
rb_string << ")" unless level.zero?
|
154
|
-
|
155
|
-
rb_string
|
156
|
-
else
|
157
|
-
sexp
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
137
|
def extract_keys(symbol_or_arr)
|
162
138
|
if symbol_or_arr.is_a?(Array)
|
163
139
|
symbol_or_arr[1..-1].flat_map(&method(:extract_keys))
|
@@ -177,16 +153,16 @@ module Speculation
|
|
177
153
|
op, *kks = key
|
178
154
|
case op
|
179
155
|
when ns(S, :or)
|
180
|
-
if kks.
|
156
|
+
if kks.any? { |k| parse_req([k], v, f).empty? }
|
181
157
|
[]
|
182
158
|
else
|
183
|
-
[key]
|
159
|
+
transform_keys([key], f)
|
184
160
|
end
|
185
161
|
when ns(S, :and)
|
186
162
|
if kks.all? { |k| parse_req([k], v, f).empty? }
|
187
163
|
[]
|
188
164
|
else
|
189
|
-
[key]
|
165
|
+
transform_keys([key], f)
|
190
166
|
end
|
191
167
|
else
|
192
168
|
raise "Expected or, and, got #{op}"
|
@@ -194,7 +170,7 @@ module Speculation
|
|
194
170
|
elsif v.key?(f.call(key))
|
195
171
|
[]
|
196
172
|
else
|
197
|
-
[key]
|
173
|
+
[f.call(key)]
|
198
174
|
end
|
199
175
|
|
200
176
|
if ks.any?
|
@@ -203,5 +179,15 @@ module Speculation
|
|
203
179
|
ret
|
204
180
|
end
|
205
181
|
end
|
182
|
+
|
183
|
+
def transform_keys(keys, f)
|
184
|
+
keys.map { |key|
|
185
|
+
case key
|
186
|
+
when Array then transform_keys(key, f)
|
187
|
+
when ns(S, :and), ns(S, :or) then key
|
188
|
+
else f.call(key)
|
189
|
+
end
|
190
|
+
}
|
191
|
+
end
|
206
192
|
end
|
207
193
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class MergeSpec <
|
4
|
+
class MergeSpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -13,7 +13,7 @@ module Speculation
|
|
13
13
|
ms = @preds.map { |pred| S.dt(pred, x) }
|
14
14
|
|
15
15
|
if ms.any?(&S.method(:invalid?))
|
16
|
-
|
16
|
+
S::INVALID
|
17
17
|
else
|
18
18
|
ms.reduce(&:merge)
|
19
19
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class OrSpec <
|
4
|
+
class OrSpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -27,7 +27,7 @@ module Speculation
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
S::INVALID
|
31
31
|
end
|
32
32
|
|
33
33
|
def explain(path, via, inn, value)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class
|
4
|
+
class PredicateSpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -20,7 +20,7 @@ module Speculation
|
|
20
20
|
if @should_conform
|
21
21
|
ret
|
22
22
|
else
|
23
|
-
ret ? value :
|
23
|
+
ret ? value : S::INVALID
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class RegexSpec <
|
4
|
+
class RegexSpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -13,7 +13,7 @@ module Speculation
|
|
13
13
|
if value.nil? || Utils.collection?(value)
|
14
14
|
S.re_conform(@regex, value)
|
15
15
|
else
|
16
|
-
|
16
|
+
S::INVALID
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Speculation
|
3
3
|
# @private
|
4
|
-
class TupleSpec <
|
4
|
+
class TupleSpec < Spec
|
5
5
|
include NamespacedSymbols
|
6
6
|
S = Speculation
|
7
7
|
|
@@ -17,7 +17,7 @@ module Speculation
|
|
17
17
|
specs = @delayed_specs.value!
|
18
18
|
|
19
19
|
unless Utils.array?(collection) && collection.count == specs.count
|
20
|
-
return
|
20
|
+
return S::INVALID
|
21
21
|
end
|
22
22
|
|
23
23
|
return_value = collection.class.new
|
@@ -26,7 +26,7 @@ module Speculation
|
|
26
26
|
conformed_value = spec.conform(value)
|
27
27
|
|
28
28
|
if S.invalid?(conformed_value)
|
29
|
-
return
|
29
|
+
return S::INVALID
|
30
30
|
else
|
31
31
|
return_value += [conformed_value]
|
32
32
|
end
|
data/lib/speculation/test.rb
CHANGED
@@ -218,7 +218,7 @@ module Speculation
|
|
218
218
|
conformed_args = S.conform(fspec.args, args)
|
219
219
|
conformed_block = S.conform(fspec.block, block) if fspec.block
|
220
220
|
|
221
|
-
if conformed_args ==
|
221
|
+
if conformed_args == S::INVALID
|
222
222
|
backtrace = backtrace_relevant_to_instrument(caller)
|
223
223
|
|
224
224
|
ed = S.
|
@@ -230,7 +230,7 @@ module Speculation
|
|
230
230
|
msg = io.string
|
231
231
|
|
232
232
|
raise Speculation::Error.new("Call to '#{ident}' did not conform to spec:\n #{msg}", ed)
|
233
|
-
elsif conformed_block ==
|
233
|
+
elsif conformed_block == S::INVALID
|
234
234
|
backtrace = backtrace_relevant_to_instrument(caller)
|
235
235
|
|
236
236
|
ed = S.
|
@@ -354,13 +354,13 @@ module Speculation
|
|
354
354
|
def check_call(method, spec, args, block)
|
355
355
|
conformed_args = S.conform(spec.args, args) if spec.args
|
356
356
|
|
357
|
-
if conformed_args ==
|
357
|
+
if conformed_args == S::INVALID
|
358
358
|
return explain_check(args, spec.args, args, :args)
|
359
359
|
end
|
360
360
|
|
361
361
|
conformed_block = S.conform(spec.block, block) if spec.block
|
362
362
|
|
363
|
-
if conformed_block ==
|
363
|
+
if conformed_block == S::INVALID
|
364
364
|
return explain_check(block, spec.block, block, :block)
|
365
365
|
end
|
366
366
|
|
@@ -368,7 +368,7 @@ module Speculation
|
|
368
368
|
|
369
369
|
conformed_ret = S.conform(spec.ret, ret) if spec.ret
|
370
370
|
|
371
|
-
if conformed_ret ==
|
371
|
+
if conformed_ret == S::INVALID
|
372
372
|
return explain_check(args, spec.ret, ret, :ret)
|
373
373
|
end
|
374
374
|
|
data/lib/speculation/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: speculation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie English
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -165,24 +165,13 @@ files:
|
|
165
165
|
- LICENSE.txt
|
166
166
|
- README.md
|
167
167
|
- Rakefile
|
168
|
-
- bin/bundler
|
169
|
-
- bin/byebug
|
170
|
-
- bin/coderay
|
171
168
|
- bin/console
|
172
|
-
- bin/cucumber-queue
|
173
|
-
- bin/minitest-queue
|
174
|
-
- bin/pry
|
175
|
-
- bin/rake
|
176
|
-
- bin/rspec-queue
|
177
|
-
- bin/rubocop
|
178
|
-
- bin/ruby-parse
|
179
|
-
- bin/ruby-rewrite
|
180
169
|
- bin/setup
|
181
|
-
- bin/testunit-queue
|
182
|
-
- bin/yard
|
183
|
-
- bin/yardoc
|
184
|
-
- bin/yri
|
185
170
|
- examples/codebreaker.rb
|
171
|
+
- examples/sinatra-web-app/Gemfile
|
172
|
+
- examples/sinatra-web-app/Gemfile.lock
|
173
|
+
- examples/sinatra-web-app/app.rb
|
174
|
+
- examples/sinatra-web-app/test
|
186
175
|
- examples/spec_guide.rb
|
187
176
|
- lib/speculation.rb
|
188
177
|
- lib/speculation/error.rb
|
@@ -190,17 +179,17 @@ files:
|
|
190
179
|
- lib/speculation/identifier.rb
|
191
180
|
- lib/speculation/namespaced_symbols.rb
|
192
181
|
- lib/speculation/pmap.rb
|
193
|
-
- lib/speculation/
|
194
|
-
- lib/speculation/
|
195
|
-
- lib/speculation/
|
196
|
-
- lib/speculation/
|
197
|
-
- lib/speculation/
|
198
|
-
- lib/speculation/
|
199
|
-
- lib/speculation/
|
200
|
-
- lib/speculation/
|
201
|
-
- lib/speculation/
|
202
|
-
- lib/speculation/
|
203
|
-
- lib/speculation/
|
182
|
+
- lib/speculation/spec.rb
|
183
|
+
- lib/speculation/spec/and_spec.rb
|
184
|
+
- lib/speculation/spec/every_spec.rb
|
185
|
+
- lib/speculation/spec/f_spec.rb
|
186
|
+
- lib/speculation/spec/hash_spec.rb
|
187
|
+
- lib/speculation/spec/merge_spec.rb
|
188
|
+
- lib/speculation/spec/nilable_spec.rb
|
189
|
+
- lib/speculation/spec/or_spec.rb
|
190
|
+
- lib/speculation/spec/predicate_spec.rb
|
191
|
+
- lib/speculation/spec/regex_spec.rb
|
192
|
+
- lib/speculation/spec/tuple_spec.rb
|
204
193
|
- lib/speculation/test.rb
|
205
194
|
- lib/speculation/utils.rb
|
206
195
|
- lib/speculation/version.rb
|
data/bin/bundler
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'bundler' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("bundler", "bundler")
|
data/bin/byebug
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'byebug' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("byebug", "byebug")
|
data/bin/coderay
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'coderay' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("coderay", "coderay")
|
data/bin/cucumber-queue
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'cucumber-queue' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("test-queue", "cucumber-queue")
|
data/bin/minitest-queue
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'minitest-queue' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("test-queue", "minitest-queue")
|
data/bin/pry
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'pry' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("pry", "pry")
|
data/bin/rake
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'rake' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("rake", "rake")
|
data/bin/rspec-queue
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'rspec-queue' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("test-queue", "rspec-queue")
|
data/bin/rubocop
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'rubocop' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("rubocop", "rubocop")
|
data/bin/ruby-parse
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'ruby-parse' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("parser", "ruby-parse")
|
data/bin/ruby-rewrite
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'ruby-rewrite' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("parser", "ruby-rewrite")
|
data/bin/testunit-queue
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'testunit-queue' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("test-queue", "testunit-queue")
|
data/bin/yard
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'yard' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("yard", "yard")
|
data/bin/yardoc
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'yardoc' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("yard", "yardoc")
|
data/bin/yri
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'yri' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("yard", "yri")
|