explicit 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +389 -0
- data/Rakefile +8 -0
- data/app/controllers/explicit/application_controller.rb +6 -0
- data/app/helpers/explicit/application_helper.rb +6 -0
- data/app/views/explicit/application/_documentation.html.erb +10 -0
- data/config/locales/en.yml +23 -0
- data/config/routes.rb +2 -0
- data/lib/explicit/documentation.rb +40 -0
- data/lib/explicit/engine.rb +9 -0
- data/lib/explicit/request/invalid_params.rb +23 -0
- data/lib/explicit/request/invalid_response_error.rb +17 -0
- data/lib/explicit/request.rb +73 -0
- data/lib/explicit/spec/agreement.rb +28 -0
- data/lib/explicit/spec/array.rb +28 -0
- data/lib/explicit/spec/boolean.rb +31 -0
- data/lib/explicit/spec/date_time_iso8601.rb +17 -0
- data/lib/explicit/spec/date_time_posix.rb +21 -0
- data/lib/explicit/spec/default.rb +20 -0
- data/lib/explicit/spec/error.rb +60 -0
- data/lib/explicit/spec/hash.rb +30 -0
- data/lib/explicit/spec/inclusion.rb +15 -0
- data/lib/explicit/spec/integer.rb +53 -0
- data/lib/explicit/spec/literal.rb +15 -0
- data/lib/explicit/spec/nilable.rb +15 -0
- data/lib/explicit/spec/one_of.rb +22 -0
- data/lib/explicit/spec/record.rb +31 -0
- data/lib/explicit/spec/string.rb +50 -0
- data/lib/explicit/spec.rb +64 -0
- data/lib/explicit/test_helper.rb +45 -0
- data/lib/explicit/version.rb +5 -0
- data/lib/explicit.rb +28 -0
- data/lib/tasks/schema/api_tasks.rake +4 -0
- metadata +94 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Array
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(itemspec, options)
|
7
|
+
itemspec_validator = Explicit::Spec.build(itemspec)
|
8
|
+
|
9
|
+
lambda do |values|
|
10
|
+
return [:error, :array] if !values.is_a?(::Array)
|
11
|
+
|
12
|
+
if options[:empty] == false && values.empty?
|
13
|
+
return [:error, :empty]
|
14
|
+
end
|
15
|
+
|
16
|
+
validated = []
|
17
|
+
|
18
|
+
values.each.with_index do |value, index|
|
19
|
+
case itemspec_validator.call(value)
|
20
|
+
in [:ok, value] then validated << value
|
21
|
+
in [:error, err] then return [:error, [:array, index, err]]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
[:ok, validated]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Boolean
|
4
|
+
extend self
|
5
|
+
|
6
|
+
VALUES = {
|
7
|
+
"true" => true,
|
8
|
+
"on" => true,
|
9
|
+
"1" => true,
|
10
|
+
"false" => false,
|
11
|
+
"off" => false,
|
12
|
+
"0" => false
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
def build(options)
|
16
|
+
lambda do |value|
|
17
|
+
value =
|
18
|
+
if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
19
|
+
value
|
20
|
+
elsif value.is_a?(::String)
|
21
|
+
VALUES[value]
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
return [:error, :boolean] if value.nil?
|
27
|
+
|
28
|
+
[:ok, value]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
module Explicit::Spec::DateTimeISO8601
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def call(value)
|
9
|
+
return [:error, :date_time_iso8601] if !value.is_a?(::String)
|
10
|
+
|
11
|
+
timeval = Time.iso8601(value)
|
12
|
+
|
13
|
+
[:ok, timeval]
|
14
|
+
rescue ArgumentError
|
15
|
+
[:error, :date_time_iso8601]
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
module Explicit::Spec::DateTimePosix
|
6
|
+
extend self
|
7
|
+
|
8
|
+
ERROR_INVALID = [:error, :date_time_posix].freeze
|
9
|
+
|
10
|
+
def call(value)
|
11
|
+
if !value.is_a?(::Integer) && !value.is_a?(::String)
|
12
|
+
return ERROR_INVALID
|
13
|
+
end
|
14
|
+
|
15
|
+
datetimeval = DateTime.strptime(value.to_s, "%s")
|
16
|
+
|
17
|
+
[:ok, datetimeval]
|
18
|
+
rescue Date::Error
|
19
|
+
ERROR_INVALID
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Default
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(defaultval, subspec)
|
7
|
+
subspec_validator = Explicit::Spec::build(subspec)
|
8
|
+
|
9
|
+
lambda do |value|
|
10
|
+
value =
|
11
|
+
if value.nil?
|
12
|
+
defaultval.respond_to?(:call) ? defaultval.call : defaultval
|
13
|
+
else
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
subspec_validator.call(value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Error
|
4
|
+
extend self
|
5
|
+
|
6
|
+
RailsI18n = ->(error, **context) do
|
7
|
+
key = "explicit.errors.#{error}"
|
8
|
+
|
9
|
+
::I18n.t(key, **context)
|
10
|
+
end
|
11
|
+
|
12
|
+
def translate(error, translator = RailsI18n)
|
13
|
+
case error
|
14
|
+
in :agreement
|
15
|
+
translator.call(:agreement)
|
16
|
+
in [:array, index, suberr]
|
17
|
+
translator.call(:array, index:, error: translate(suberr, translator))
|
18
|
+
in :boolean
|
19
|
+
translator.call(:boolean)
|
20
|
+
in :date_time_iso8601
|
21
|
+
translator.call(:date_time_iso8601)
|
22
|
+
in :date_time_posix
|
23
|
+
translator.call(:date_time_posix)
|
24
|
+
in :hash
|
25
|
+
translator.call(:hash)
|
26
|
+
in [:hash_key, key, suberr]
|
27
|
+
translator.call(:hash_key, key:, error: translate(suberr, translator))
|
28
|
+
in [:hash_value, key, suberr]
|
29
|
+
translator.call(:hash_value, key:, error: translate(suberr, translator))
|
30
|
+
in [:inclusion, values]
|
31
|
+
translator.call(:inclusion, values: values.inspect)
|
32
|
+
in :integer
|
33
|
+
translator.call(:integer)
|
34
|
+
in [:min, min]
|
35
|
+
translator.call(:min, min:)
|
36
|
+
in [:max, max]
|
37
|
+
translator.call(:max, max:)
|
38
|
+
in :negative
|
39
|
+
translator.call(:negative)
|
40
|
+
in :positive
|
41
|
+
translator.call(:positive)
|
42
|
+
in [:literal, value]
|
43
|
+
translator.call(:literal, value: value.inspect)
|
44
|
+
in [:one_of, *errors]
|
45
|
+
errors.map { translate(_1, translator) }.join(" OR ")
|
46
|
+
in :string
|
47
|
+
translator.call(:string)
|
48
|
+
in :empty
|
49
|
+
translator.call(:empty)
|
50
|
+
in [:minlength, minlength]
|
51
|
+
translator.call(:minlength, minlength:)
|
52
|
+
in [:maxlength, maxlength]
|
53
|
+
translator.call(:maxlength, maxlength:)
|
54
|
+
in [:format, regex]
|
55
|
+
translator.call(:format, regex: regex.inspect)
|
56
|
+
in Hash
|
57
|
+
error.to_h { |attr_name, err| [attr_name, translate(err, translator)] }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Hash
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(keyspec, valuespec, options)
|
7
|
+
keyspec_validator = Explicit::Spec.build(keyspec)
|
8
|
+
valuespec_validator = Explicit::Spec.build(valuespec)
|
9
|
+
|
10
|
+
lambda do |value|
|
11
|
+
return [:error, :hash] if !value.is_a?(::Hash)
|
12
|
+
return [:error, :empty] if value.empty? && !options[:empty]
|
13
|
+
|
14
|
+
validated_hash = {}
|
15
|
+
|
16
|
+
value.each do |key, value|
|
17
|
+
case [keyspec_validator.call(key), valuespec_validator.call(value)]
|
18
|
+
in [[:ok, validated_key], [:ok, validated_value]]
|
19
|
+
validated_hash[validated_key] = validated_value
|
20
|
+
in [[:error, err], _]
|
21
|
+
return [:error, [:hash_key, key, err]]
|
22
|
+
in [_, [:error, err]]
|
23
|
+
return [:error, [:hash_value, key, err]]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
[:ok, validated_hash]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Integer
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(options)
|
7
|
+
lambda do |value|
|
8
|
+
value =
|
9
|
+
if value.is_a?(::Integer)
|
10
|
+
value
|
11
|
+
elsif value.is_a?(::String) && options[:parse]
|
12
|
+
parse_from_string(value)
|
13
|
+
else
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
return [:error, :integer] if value.nil?
|
18
|
+
|
19
|
+
if (min = options[:min]) && !validate_min(value, min)
|
20
|
+
return [:error, [:min, min]]
|
21
|
+
end
|
22
|
+
|
23
|
+
if (max = options[:max]) && !validate_max(value, max)
|
24
|
+
return [:error, [:max, max]]
|
25
|
+
end
|
26
|
+
|
27
|
+
if options[:negative] == false && value < 0
|
28
|
+
return [:error, :negative]
|
29
|
+
end
|
30
|
+
|
31
|
+
if options[:positive] == false && value > 0
|
32
|
+
return [:error, :positive]
|
33
|
+
end
|
34
|
+
|
35
|
+
[:ok, value]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def parse_from_string(value)
|
41
|
+
Integer(value)
|
42
|
+
rescue ::ArgumentError
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_min(value, min)
|
47
|
+
value >= min
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_max(value, max)
|
51
|
+
value <= max
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Nilable
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(subspec)
|
7
|
+
subspec_validator = Explicit::Spec.build(subspec)
|
8
|
+
|
9
|
+
lambda do |value|
|
10
|
+
return [:ok, nil] if value.nil?
|
11
|
+
|
12
|
+
subspec_validator.call(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::OneOf
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(subspecs)
|
7
|
+
subspec_validators = subspecs.map { Explicit::Spec.build(_1) }
|
8
|
+
|
9
|
+
errors = []
|
10
|
+
|
11
|
+
lambda do |value|
|
12
|
+
subspec_validators.each do |subspec_validator|
|
13
|
+
case subspec_validator.call(value)
|
14
|
+
in [:ok, validated_value] then return [:ok, validated_value]
|
15
|
+
in [:error, err] then errors << err
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
[:error, [:one_of, *errors]]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::Record
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(attributes)
|
7
|
+
attributes_validators = attributes.map do |attribute_name, attribute_spec|
|
8
|
+
[attribute_name, Explicit::Spec.build(attribute_spec)]
|
9
|
+
end
|
10
|
+
|
11
|
+
lambda do |data|
|
12
|
+
validated_data = {}
|
13
|
+
errors = {}
|
14
|
+
|
15
|
+
attributes_validators.each do |attribute_name, attribute_validator|
|
16
|
+
value = data[attribute_name]
|
17
|
+
|
18
|
+
case attribute_validator.call(value)
|
19
|
+
in [:ok, validated_value]
|
20
|
+
validated_data[attribute_name] = validated_value
|
21
|
+
in [:error, err]
|
22
|
+
errors[attribute_name] = err
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return [:error, errors] if errors.any?
|
27
|
+
|
28
|
+
[:ok, validated_data]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec::String
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(options)
|
7
|
+
lambda do |value|
|
8
|
+
return [:error, :string] if !value.is_a?(::String)
|
9
|
+
|
10
|
+
value = value.strip if options[:strip]
|
11
|
+
|
12
|
+
if options.key?(:empty) && !validate_empty(value, options[:empty])
|
13
|
+
return [:error, :empty]
|
14
|
+
end
|
15
|
+
|
16
|
+
if (minlength = options[:minlength]) && !validate_minlength(value, minlength)
|
17
|
+
return [:error, [:minlength, minlength:]]
|
18
|
+
end
|
19
|
+
|
20
|
+
if (maxlength = options[:maxlength]) && !validate_maxlength(value, maxlength)
|
21
|
+
return [:error, [:maxlength, maxlength:]]
|
22
|
+
end
|
23
|
+
|
24
|
+
if (format = options[:format]) && !validate_format(value, format)
|
25
|
+
return [:error, [:format, format]]
|
26
|
+
end
|
27
|
+
|
28
|
+
[:ok, value]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def validate_empty(value, allow_empty)
|
34
|
+
return true if allow_empty
|
35
|
+
|
36
|
+
!value.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate_minlength(value, minlength)
|
40
|
+
value.length >= minlength
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate_maxlength(value, maxlength)
|
44
|
+
value.length <= maxlength
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_format(value, format)
|
48
|
+
format.match?(value)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::Spec
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def build(spec)
|
7
|
+
case spec
|
8
|
+
in :agreement
|
9
|
+
Explicit::Spec::Agreement.build({})
|
10
|
+
in [:agreement, options]
|
11
|
+
Explicit::Spec::Agreement.build(options)
|
12
|
+
|
13
|
+
in [:array, itemspec]
|
14
|
+
Explicit::Spec::Array.build(itemspec, {})
|
15
|
+
in [:array, itemspec, options]
|
16
|
+
Explicit::Spec::Array.build(itemspec, options)
|
17
|
+
|
18
|
+
in :boolean
|
19
|
+
Explicit::Spec::Boolean.build({})
|
20
|
+
in [:boolean, options]
|
21
|
+
Explicit::Spec::Boolean.build(options)
|
22
|
+
|
23
|
+
in :date_time_iso8601
|
24
|
+
Explicit::Spec::DateTimeISO8601
|
25
|
+
in :date_time_posix
|
26
|
+
Explicit::Spec::DateTimePosix
|
27
|
+
|
28
|
+
in [:default, defaultval, subspec]
|
29
|
+
Explicit::Spec::Default.build(defaultval, subspec)
|
30
|
+
|
31
|
+
in [:hash, keyspec, valuespec]
|
32
|
+
Explicit::Spec::Hash.build(keyspec, valuespec, {})
|
33
|
+
in [:hash, keyspec, valuespec, options]
|
34
|
+
Explicit::Spec::Hash.build(keyspec, valuespec, options)
|
35
|
+
|
36
|
+
in [:inclusion, options]
|
37
|
+
Explicit::Spec::Inclusion.build(options)
|
38
|
+
|
39
|
+
in :integer
|
40
|
+
Explicit::Spec::Integer.build({})
|
41
|
+
in [:integer, options]
|
42
|
+
Explicit::Spec::Integer.build(options)
|
43
|
+
|
44
|
+
in [:literal, value]
|
45
|
+
Explicit::Spec::Literal.build(value)
|
46
|
+
in ::String
|
47
|
+
Explicit::Spec::Literal.build(spec)
|
48
|
+
|
49
|
+
in [:nilable, options]
|
50
|
+
Explicit::Spec::Nilable.build(options)
|
51
|
+
|
52
|
+
in [:one_of, *subspecs]
|
53
|
+
Explicit::Spec::OneOf.build(subspecs)
|
54
|
+
|
55
|
+
in :string
|
56
|
+
Explicit::Spec::String.build({})
|
57
|
+
in [:string, options]
|
58
|
+
Explicit::Spec::String.build(options)
|
59
|
+
|
60
|
+
in ::Hash
|
61
|
+
Explicit::Spec::Record.build(spec)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Explicit::TestHelper
|
4
|
+
Response = ::Data.define(:status, :data) do
|
5
|
+
def dig(...) = data.dig(...)
|
6
|
+
end
|
7
|
+
|
8
|
+
def fetch(request, params:, headers: nil)
|
9
|
+
route = request.send(:routes).first
|
10
|
+
|
11
|
+
if route.nil?
|
12
|
+
raise <<-DESC
|
13
|
+
The request #{request} must define at least one route. For example:
|
14
|
+
|
15
|
+
get "/customers/:customer_id"
|
16
|
+
post "/article/:article_id/comments"
|
17
|
+
put "/user/preferences"
|
18
|
+
|
19
|
+
Important: adding a route to the request does not substitute the entry
|
20
|
+
on `routes.rb`.
|
21
|
+
DESC
|
22
|
+
end
|
23
|
+
|
24
|
+
process(route.method, route.path, params:, headers:)
|
25
|
+
|
26
|
+
response = Response.new(
|
27
|
+
status: @response.status,
|
28
|
+
data: @response.parsed_body.deep_symbolize_keys
|
29
|
+
)
|
30
|
+
|
31
|
+
ensure_response_matches_spec!(request, response)
|
32
|
+
|
33
|
+
response
|
34
|
+
end
|
35
|
+
|
36
|
+
def ensure_response_matches_spec!(request, response)
|
37
|
+
allowed_responses = request.send(:responses)
|
38
|
+
response_validator = Explicit::Spec.build([:one_of, *allowed_responses])
|
39
|
+
|
40
|
+
case response_validator.call({ status: response.status, data: response.data.with_indifferent_access })
|
41
|
+
in [:ok, _] then :all_good
|
42
|
+
in [:error, err] then raise Explicit::Request::InvalidResponseError.new(response, err)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/explicit.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "explicit/documentation"
|
2
|
+
require "explicit/engine"
|
3
|
+
require "explicit/test_helper"
|
4
|
+
require "explicit/version"
|
5
|
+
|
6
|
+
require "explicit/request"
|
7
|
+
require "explicit/request/invalid_params"
|
8
|
+
require "explicit/request/invalid_response_error"
|
9
|
+
|
10
|
+
require "explicit/spec"
|
11
|
+
require "explicit/spec/agreement"
|
12
|
+
require "explicit/spec/array"
|
13
|
+
require "explicit/spec/boolean"
|
14
|
+
require "explicit/spec/date_time_iso8601"
|
15
|
+
require "explicit/spec/date_time_posix"
|
16
|
+
require "explicit/spec/default"
|
17
|
+
require "explicit/spec/error"
|
18
|
+
require "explicit/spec/hash"
|
19
|
+
require "explicit/spec/inclusion"
|
20
|
+
require "explicit/spec/integer"
|
21
|
+
require "explicit/spec/literal"
|
22
|
+
require "explicit/spec/nilable"
|
23
|
+
require "explicit/spec/one_of"
|
24
|
+
require "explicit/spec/record"
|
25
|
+
require "explicit/spec/string"
|
26
|
+
|
27
|
+
module Explicit
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: explicit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Luiz Vasconcellos
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 7.2.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 7.2.1
|
27
|
+
description: explicit allows you to document, test and specify requests and responses
|
28
|
+
schemas
|
29
|
+
email:
|
30
|
+
- luizpvasc@gmail.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- MIT-LICENSE
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- app/controllers/explicit/application_controller.rb
|
39
|
+
- app/helpers/explicit/application_helper.rb
|
40
|
+
- app/views/explicit/application/_documentation.html.erb
|
41
|
+
- config/locales/en.yml
|
42
|
+
- config/routes.rb
|
43
|
+
- lib/explicit.rb
|
44
|
+
- lib/explicit/documentation.rb
|
45
|
+
- lib/explicit/engine.rb
|
46
|
+
- lib/explicit/request.rb
|
47
|
+
- lib/explicit/request/invalid_params.rb
|
48
|
+
- lib/explicit/request/invalid_response_error.rb
|
49
|
+
- lib/explicit/spec.rb
|
50
|
+
- lib/explicit/spec/agreement.rb
|
51
|
+
- lib/explicit/spec/array.rb
|
52
|
+
- lib/explicit/spec/boolean.rb
|
53
|
+
- lib/explicit/spec/date_time_iso8601.rb
|
54
|
+
- lib/explicit/spec/date_time_posix.rb
|
55
|
+
- lib/explicit/spec/default.rb
|
56
|
+
- lib/explicit/spec/error.rb
|
57
|
+
- lib/explicit/spec/hash.rb
|
58
|
+
- lib/explicit/spec/inclusion.rb
|
59
|
+
- lib/explicit/spec/integer.rb
|
60
|
+
- lib/explicit/spec/literal.rb
|
61
|
+
- lib/explicit/spec/nilable.rb
|
62
|
+
- lib/explicit/spec/one_of.rb
|
63
|
+
- lib/explicit/spec/record.rb
|
64
|
+
- lib/explicit/spec/string.rb
|
65
|
+
- lib/explicit/test_helper.rb
|
66
|
+
- lib/explicit/version.rb
|
67
|
+
- lib/tasks/schema/api_tasks.rake
|
68
|
+
homepage: https://github.com/luizpvas/explicit
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata:
|
72
|
+
homepage_uri: https://github.com/luizpvas/explicit
|
73
|
+
source_code_uri: https://github.com/luizpvas/explicit
|
74
|
+
changelog_uri: https://github.com/luizpvas/explicit
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubygems_version: 3.4.22
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: explicit is a documentation and validation library for JSON APIs
|
94
|
+
test_files: []
|