argo 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/COPYING.txt +13 -0
- data/lib/argo/array_property.rb +12 -0
- data/lib/argo/boolean_property.rb +6 -0
- data/lib/argo/constraint_processor.rb +53 -0
- data/lib/argo/deferred_object.rb +23 -0
- data/lib/argo/dereferencer.rb +26 -0
- data/lib/argo/immutable_keyword_struct.rb +32 -0
- data/lib/argo/integer_property.rb +6 -0
- data/lib/argo/number_property.rb +6 -0
- data/lib/argo/object_property.rb +6 -0
- data/lib/argo/parser.rb +20 -0
- data/lib/argo/property.rb +11 -0
- data/lib/argo/property_factory.rb +91 -0
- data/lib/argo/schema.rb +13 -0
- data/lib/argo/schema_factory.rb +71 -0
- data/lib/argo/string_property.rb +6 -0
- data/lib/argo/version.rb +3 -0
- data/spec/integration/array_reference_spec.rb +37 -0
- data/spec/integration/basic_example_spec.rb +61 -0
- data/spec/integration/core_nested_schema_spec.rb +48 -0
- data/spec/integration/core_simple_schema_spec.rb +19 -0
- data/spec/integration/disk_device_spec.rb +51 -0
- data/spec/integration/disk_uuid_spec.rb +53 -0
- data/spec/integration/entry_schema_spec.rb +115 -0
- data/spec/integration/nfs_spec.rb +71 -0
- data/spec/integration/property_reference_spec.rb +27 -0
- data/spec/integration/simple_example_spec.rb +114 -0
- data/spec/integration/tmpfs_spec.rb +51 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/unit/deferred_object_spec.rb +29 -0
- data/spec/unit/immutable_keyword_struct_spec.rb +54 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eec272ff117353e33f1c251074a13a9b80ee0133
|
4
|
+
data.tar.gz: 8849f7c278b5f83c27699d5e10a39bc3e32e68fa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d936009d4cb7595e92127e2b0ed8d47ec391a53b780fd66f59f68e12144ed00e72eb79beb648112167b84c634767fc24fe7283975b510f06b6b7164afd2fd2e6
|
7
|
+
data.tar.gz: adf136d679c8b065c63cc6ad9f388f907db1905468c44dbb9112d39dd8bdd1de1e8d88f20e154c8a4193334aa0e034a780a0a750d39074303df828fa55c94154
|
data/COPYING.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2015 Paul Battley
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
9
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
10
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
11
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
12
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
13
|
+
PERFORMANCE OF THIS SOFTWARE.
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Argo
|
4
|
+
class ConstraintProcessor
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
NON_CONSTRAINT_PROPERTIES = %w[
|
8
|
+
description
|
9
|
+
items
|
10
|
+
type
|
11
|
+
]
|
12
|
+
|
13
|
+
def initialize(dereferencer)
|
14
|
+
@dereferencer = dereferencer
|
15
|
+
end
|
16
|
+
|
17
|
+
def process(hash)
|
18
|
+
process_hash(
|
19
|
+
hash.reject { |k, _| NON_CONSTRAINT_PROPERTIES.include?(k) }
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def_delegators :@dereferencer, :dereference, :reference?
|
26
|
+
|
27
|
+
def symbolize_key(k)
|
28
|
+
k.gsub(/[A-Z]/) { |m| "_#{m.downcase}" }.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_object(obj)
|
32
|
+
case obj
|
33
|
+
when Hash
|
34
|
+
process_hash(obj)
|
35
|
+
when Array
|
36
|
+
obj.map { |v| process_object(v) }.freeze
|
37
|
+
else
|
38
|
+
obj.freeze
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_hash(hash)
|
43
|
+
if reference?(hash)
|
44
|
+
dereference(hash)
|
45
|
+
else
|
46
|
+
hash.
|
47
|
+
map { |k, v| [symbolize_key(k), process_object(v)] }.
|
48
|
+
to_h.
|
49
|
+
freeze
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Argo
|
4
|
+
class DeferredObject < Delegator
|
5
|
+
instance_methods.each do |m|
|
6
|
+
unless m =~ /^__|^(respond_to\?|method_missing|object_id)$/
|
7
|
+
undef_method m
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(&block)
|
12
|
+
@__delegator_block__ = block
|
13
|
+
@__mutex__ = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def __getobj__
|
17
|
+
@__mutex__.synchronize do
|
18
|
+
@__getobj__ ||= @__delegator_block__.call
|
19
|
+
end
|
20
|
+
@__getobj__
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'argo/deferred_object'
|
2
|
+
|
3
|
+
module Argo
|
4
|
+
class Dereferencer
|
5
|
+
def initialize(&block)
|
6
|
+
@block = block
|
7
|
+
end
|
8
|
+
|
9
|
+
def dereference(hash)
|
10
|
+
path = hash.fetch('$ref')
|
11
|
+
fragments = path.split(/\//)
|
12
|
+
unless fragments[0] == '#'
|
13
|
+
raise "Can't dereference non-root-anchored path '#{path}'"
|
14
|
+
end
|
15
|
+
DeferredObject.new {
|
16
|
+
fragments.drop(1).inject(@block.call) { |schema, fragment|
|
17
|
+
schema.schemas.fetch(fragment)
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def reference?(hash)
|
23
|
+
hash.key?('$ref')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Argo
|
2
|
+
class ImmutableKeywordStruct
|
3
|
+
# Disable these metrics here as gnarly metaprogramming is inherently ugly
|
4
|
+
# and splitting it up won't help much.
|
5
|
+
#
|
6
|
+
# rubocop:disable Metrics/AbcSize
|
7
|
+
# rubocop:disable Metrics/MethodLength
|
8
|
+
def self.new(default_parameters, &block)
|
9
|
+
Class.new do
|
10
|
+
define_method :initialize do |**kwargs|
|
11
|
+
unknown_keys = kwargs.keys - __defaults__.keys
|
12
|
+
if unknown_keys.any?
|
13
|
+
raise ArgumentError, "unknown keyword: #{unknown_keys.first}"
|
14
|
+
end
|
15
|
+
__defaults__.each do |key, default|
|
16
|
+
instance_variable_set("@#{key}", kwargs.fetch(key, default).freeze)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader(*default_parameters.keys)
|
21
|
+
|
22
|
+
class_eval(&block) if block
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
define_method :__defaults__ do
|
27
|
+
default_parameters
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/argo/parser.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'argo/dereferencer'
|
2
|
+
require 'argo/schema_factory'
|
3
|
+
|
4
|
+
module Argo
|
5
|
+
class Parser
|
6
|
+
def initialize(source)
|
7
|
+
@source = source
|
8
|
+
end
|
9
|
+
|
10
|
+
def root
|
11
|
+
@root ||= SchemaFactory.new(dereferencer).build(@source)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def dereferencer
|
17
|
+
@dereferencer ||= Dereferencer.new { root }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'argo/array_property'
|
4
|
+
require 'argo/boolean_property'
|
5
|
+
require 'argo/integer_property'
|
6
|
+
require 'argo/number_property'
|
7
|
+
require 'argo/object_property'
|
8
|
+
require 'argo/string_property'
|
9
|
+
|
10
|
+
require 'argo/constraint_processor'
|
11
|
+
|
12
|
+
module Argo
|
13
|
+
class PropertyFactory
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
TYPE_MAP = {
|
17
|
+
'array' => ArrayProperty,
|
18
|
+
'boolean' => BooleanProperty,
|
19
|
+
'integer' => IntegerProperty,
|
20
|
+
'number' => NumberProperty,
|
21
|
+
'object' => ObjectProperty,
|
22
|
+
'string' => StringProperty
|
23
|
+
}
|
24
|
+
|
25
|
+
def initialize(dereferencer, required_fields = [])
|
26
|
+
@dereferencer = dereferencer
|
27
|
+
@required_fields = required_fields
|
28
|
+
end
|
29
|
+
|
30
|
+
def_delegators :@dereferencer, :dereference, :reference?
|
31
|
+
|
32
|
+
def build(body, name: nil)
|
33
|
+
class_for_type(body).new(
|
34
|
+
constraints: constraints(body),
|
35
|
+
description: body['description'],
|
36
|
+
required: required?(name),
|
37
|
+
**additional_properties(body)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def class_for_type(body)
|
44
|
+
klass = explicit_class(body) || implicit_class(body)
|
45
|
+
raise "No type found in #{body.inspect}" unless klass
|
46
|
+
klass
|
47
|
+
end
|
48
|
+
|
49
|
+
def explicit_class(body)
|
50
|
+
return nil unless body.key?('type')
|
51
|
+
type = body.fetch('type')
|
52
|
+
raise "Unknown property type '#{type}'" unless TYPE_MAP.key?(type)
|
53
|
+
TYPE_MAP.fetch(type)
|
54
|
+
end
|
55
|
+
|
56
|
+
def implicit_class(body)
|
57
|
+
if body.key?('enum')
|
58
|
+
StringProperty
|
59
|
+
elsif (body.keys & %w[ oneOf anyOf ]).any?
|
60
|
+
ObjectProperty
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def additional_properties(body)
|
65
|
+
if class_for_type(body) == ArrayProperty
|
66
|
+
additional_properties_for_array(body)
|
67
|
+
else
|
68
|
+
{}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def additional_properties_for_array(body)
|
73
|
+
items = [body.fetch('items')].flatten.first
|
74
|
+
if reference?(items)
|
75
|
+
value = dereference(items)
|
76
|
+
else
|
77
|
+
factory = PropertyFactory.new(@dereferencer)
|
78
|
+
value = factory.build(items)
|
79
|
+
end
|
80
|
+
{ items: value }
|
81
|
+
end
|
82
|
+
|
83
|
+
def required?(name)
|
84
|
+
@required_fields.include?(name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def constraints(hash)
|
88
|
+
ConstraintProcessor.new(@dereferencer).process(hash)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/argo/schema.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'argo/schema'
|
3
|
+
require 'argo/property_factory'
|
4
|
+
|
5
|
+
module Argo
|
6
|
+
class SchemaFactory
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def initialize(dereferencer)
|
10
|
+
@dereferencer = dereferencer
|
11
|
+
end
|
12
|
+
|
13
|
+
def_delegators :@dereferencer, :dereference, :reference?
|
14
|
+
|
15
|
+
def build(subgraph, route = [])
|
16
|
+
Schema.new(
|
17
|
+
description: extract_one(subgraph, :description),
|
18
|
+
title: extract_one(subgraph, :title),
|
19
|
+
schemas: subschemas(subgraph, route),
|
20
|
+
type: type(subgraph),
|
21
|
+
properties: properties(subgraph),
|
22
|
+
spec: extract_one(subgraph, :$schema),
|
23
|
+
route: route
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
NON_SUBSCHEMA_PROPERTIES = %w[
|
28
|
+
$schema
|
29
|
+
additionalItems
|
30
|
+
additionalProperties
|
31
|
+
description
|
32
|
+
id
|
33
|
+
properties
|
34
|
+
required
|
35
|
+
title
|
36
|
+
type
|
37
|
+
]
|
38
|
+
|
39
|
+
def element_kind(key)
|
40
|
+
NON_SUBSCHEMA_PROPERTIES.include?(key) ? key.to_sym : :subschema
|
41
|
+
end
|
42
|
+
|
43
|
+
def extract(subgraph, kind)
|
44
|
+
subgraph.select { |k, _| element_kind(k) == kind }
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_one(subgraph, kind, default: nil)
|
48
|
+
_, v = subgraph.find { |k, _| element_kind(k) == kind }
|
49
|
+
v || default
|
50
|
+
end
|
51
|
+
|
52
|
+
def subschemas(subgraph, route)
|
53
|
+
extract(subgraph, :subschema).
|
54
|
+
inject({}) { |h, (k, v)| h.merge(k => build(v, route + [k])) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def type(subgraph)
|
58
|
+
extract_one(subgraph, :type, default: :object).to_sym
|
59
|
+
end
|
60
|
+
|
61
|
+
def properties(subgraph)
|
62
|
+
required_fields = extract_one(subgraph, :required, default: [])
|
63
|
+
factory = PropertyFactory.new(@dereferencer, required_fields)
|
64
|
+
extract_one(subgraph, :properties, default: {}).
|
65
|
+
map { |k, v|
|
66
|
+
[k, reference?(v) ? dereference(v) : factory.build(v, name: k)]
|
67
|
+
}.
|
68
|
+
to_h
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/argo/version.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'array reference' do
|
5
|
+
subject {
|
6
|
+
json = read_fixture('array_reference.json')
|
7
|
+
Argo::Parser.new(JSON.parse(json)).root
|
8
|
+
}
|
9
|
+
|
10
|
+
describe 'property with reference' do
|
11
|
+
subject { super().properties.fetch('a') }
|
12
|
+
|
13
|
+
it { is_expected.to be_kind_of(Argo::ArrayProperty) }
|
14
|
+
|
15
|
+
describe 'items' do
|
16
|
+
subject { super().items }
|
17
|
+
|
18
|
+
it 'has one property' do
|
19
|
+
expect(subject.properties.keys).to eq(%w[ thing_id ])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'property with array containing one reference' do
|
25
|
+
subject { super().properties.fetch('b') }
|
26
|
+
|
27
|
+
it { is_expected.to be_kind_of(Argo::ArrayProperty) }
|
28
|
+
|
29
|
+
describe 'items' do
|
30
|
+
subject { super().items }
|
31
|
+
|
32
|
+
it 'has one property' do
|
33
|
+
expect(subject.properties.keys).to eq(%w[ thing_id ])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'Example schemata' do
|
5
|
+
# See http://json-schema.org/examples.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('basic_example.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has a title' do
|
13
|
+
expect(subject.title).
|
14
|
+
to eq('Example Schema')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is an object' do
|
18
|
+
expect(subject.type).
|
19
|
+
to eq(:object)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'properties' do
|
23
|
+
subject { super().properties }
|
24
|
+
|
25
|
+
it 'has three items' do
|
26
|
+
expect(subject.length).to eq(3)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'firstName' do
|
30
|
+
subject { super().fetch('firstName') }
|
31
|
+
|
32
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
33
|
+
|
34
|
+
it 'has no description' do
|
35
|
+
expect(subject.description).to be_nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'is required' do
|
39
|
+
expect(subject).to be_required
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'age' do
|
44
|
+
subject { super().fetch('age') }
|
45
|
+
|
46
|
+
it { is_expected.to be_kind_of(Argo::IntegerProperty) }
|
47
|
+
|
48
|
+
it 'has a description' do
|
49
|
+
expect(subject.description).to eq('Age in years')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'is not required' do
|
53
|
+
expect(subject).not_to be_required
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'has constraints' do
|
57
|
+
expect(subject.constraints).to eq(minimum: 0)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'Core spec section 3.4 nested schema' do
|
5
|
+
# See http://json-schema.org/latest/json-schema-core.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('core_nested_schema.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has the title "root"' do
|
13
|
+
expect(subject.title).to eq('root')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has an empty route' do
|
17
|
+
expect(subject.route).to eq([])
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'nested schema' do
|
21
|
+
subject { super().schemas.fetch('otherSchema') }
|
22
|
+
|
23
|
+
it 'has the title "nested"' do
|
24
|
+
expect(subject.title).to eq('nested')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has a one-element route' do
|
28
|
+
expect(subject.route).to eq(%w[ otherSchema ])
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'doubly nested schema' do
|
32
|
+
subject { super().schemas.fetch('anotherSchema') }
|
33
|
+
|
34
|
+
it 'has the title "alsoNested"' do
|
35
|
+
expect(subject.title).to eq('alsoNested')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'has a two-element route' do
|
39
|
+
expect(subject.route).to eq(%w[ otherSchema anotherSchema ])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'is an object' do
|
45
|
+
expect(subject.type).
|
46
|
+
to eq(:object)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'Core spec section 3.4 simple schema' do
|
5
|
+
# See http://json-schema.org/latest/json-schema-core.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('core_simple_schema.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has a title' do
|
13
|
+
expect(subject.title).to eq('root')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'is an object' do
|
17
|
+
expect(subject.type).to eq(:object)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'diskDevice' do
|
5
|
+
# See http://json-schema.org/example2.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('diskDevice.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has no title' do
|
13
|
+
expect(subject.title).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'properties' do
|
17
|
+
subject { super().properties }
|
18
|
+
|
19
|
+
it 'has two items' do
|
20
|
+
expect(subject.length).to eq(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'type' do
|
24
|
+
subject { super().fetch('type') }
|
25
|
+
|
26
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
27
|
+
|
28
|
+
it 'is required' do
|
29
|
+
expect(subject).to be_required
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has an enum constraint' do
|
33
|
+
expect(subject.constraints).to eq(enum: %w[ disk ])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'device' do
|
38
|
+
subject { super().fetch('device') }
|
39
|
+
|
40
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
41
|
+
|
42
|
+
it 'is required' do
|
43
|
+
expect(subject).to be_required
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has a pattern constraint' do
|
47
|
+
expect(subject.constraints).to eq(pattern: '^/dev/[^/]+(/[^/]+)*$')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'diskUUID' do
|
5
|
+
# See http://json-schema.org/example2.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('diskUUID.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has no title' do
|
13
|
+
expect(subject.title).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'properties' do
|
17
|
+
subject { super().properties }
|
18
|
+
|
19
|
+
it 'has two items' do
|
20
|
+
expect(subject.length).to eq(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'type' do
|
24
|
+
subject { super().fetch('type') }
|
25
|
+
|
26
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
27
|
+
|
28
|
+
it 'is required' do
|
29
|
+
expect(subject).to be_required
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has an enum constraint' do
|
33
|
+
expect(subject.constraints).to eq(enum: %w[ disk ])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'label' do
|
38
|
+
subject { super().fetch('label') }
|
39
|
+
|
40
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
41
|
+
|
42
|
+
it 'is required' do
|
43
|
+
expect(subject).to be_required
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has a pattern constraint' do
|
47
|
+
expect(subject.constraints).to eq(
|
48
|
+
pattern: '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$'
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'entry-schema' do
|
5
|
+
# See http://json-schema.org/example2.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('entry-schema.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has a description' do
|
13
|
+
expect(subject.description).
|
14
|
+
to eq('schema for an fstab entry')
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'properties' do
|
18
|
+
subject { super().properties }
|
19
|
+
|
20
|
+
it 'has four items' do
|
21
|
+
expect(subject.length).to eq(4)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'storage' do
|
25
|
+
subject { super().fetch('storage') }
|
26
|
+
|
27
|
+
it { is_expected.to be_kind_of(Argo::ObjectProperty) }
|
28
|
+
|
29
|
+
it 'is required' do
|
30
|
+
expect(subject).to be_required
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'one_of constraint' do
|
34
|
+
subject { super().constraints.fetch(:one_of) }
|
35
|
+
|
36
|
+
it 'has four entries' do
|
37
|
+
expect(subject.length).to eq(4)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'first' do
|
41
|
+
subject { super().fetch(0) }
|
42
|
+
|
43
|
+
it { is_expected.to be_kind_of(Argo::Schema) }
|
44
|
+
|
45
|
+
describe 'properties' do
|
46
|
+
subject { super().properties }
|
47
|
+
|
48
|
+
it 'has two items' do
|
49
|
+
expect(subject.length).to eq(2)
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'type' do
|
53
|
+
subject { super().fetch('type') }
|
54
|
+
|
55
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'device' do
|
59
|
+
subject { super().fetch('device') }
|
60
|
+
|
61
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'fstype' do
|
69
|
+
subject { super().fetch('fstype') }
|
70
|
+
|
71
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
72
|
+
|
73
|
+
it 'is not required' do
|
74
|
+
expect(subject).not_to be_required
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'has an enum constraint' do
|
78
|
+
expect(subject.constraints).to eq(enum: %w[ ext3 ext4 btrfs ])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'options' do
|
83
|
+
subject { super().fetch('options') }
|
84
|
+
|
85
|
+
it { is_expected.to be_kind_of(Argo::ArrayProperty) }
|
86
|
+
|
87
|
+
describe 'items' do
|
88
|
+
subject { super().items }
|
89
|
+
|
90
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'is not required' do
|
94
|
+
expect(subject).not_to be_required
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'has minimum items and uniqueness constraints' do
|
98
|
+
expect(subject.constraints).to eq(
|
99
|
+
min_items: 1,
|
100
|
+
unique_items: true
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'readonly' do
|
106
|
+
subject { super().fetch('readonly') }
|
107
|
+
|
108
|
+
it { is_expected.to be_kind_of(Argo::BooleanProperty) }
|
109
|
+
|
110
|
+
it 'is not required' do
|
111
|
+
expect(subject).not_to be_required
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'nfs' do
|
5
|
+
# See http://json-schema.org/example2.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('nfs.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has no title' do
|
13
|
+
expect(subject.title).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'properties' do
|
17
|
+
subject { super().properties }
|
18
|
+
|
19
|
+
it 'has three items' do
|
20
|
+
expect(subject.length).to eq(3)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'type' do
|
24
|
+
subject { super().fetch('type') }
|
25
|
+
|
26
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
27
|
+
|
28
|
+
it 'is required' do
|
29
|
+
expect(subject).to be_required
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has an enum constraint' do
|
33
|
+
expect(subject.constraints).to eq(enum: %w[ nfs ])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'remotePath' do
|
38
|
+
subject { super().fetch('remotePath') }
|
39
|
+
|
40
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
41
|
+
|
42
|
+
it 'is required' do
|
43
|
+
expect(subject).to be_required
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has a pattern constraint' do
|
47
|
+
expect(subject.constraints).to eq(pattern: '^(/[^/]+)+$')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'server' do
|
52
|
+
subject { super().fetch('server') }
|
53
|
+
|
54
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
55
|
+
|
56
|
+
it 'is required' do
|
57
|
+
expect(subject).to be_required
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'has a one-of constraint' do
|
61
|
+
expect(subject.constraints).to eq(
|
62
|
+
one_of: [
|
63
|
+
{ format: 'host-name' },
|
64
|
+
{ format: 'ipv4' },
|
65
|
+
{ format: 'ipv6' }
|
66
|
+
]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'property reference' do
|
5
|
+
subject {
|
6
|
+
json = read_fixture('property_reference.json')
|
7
|
+
Argo::Parser.new(JSON.parse(json)).root
|
8
|
+
}
|
9
|
+
|
10
|
+
describe 'a' do
|
11
|
+
subject { super().properties.fetch('a') }
|
12
|
+
|
13
|
+
it { is_expected.to be_kind_of(Argo::Schema) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'b' do
|
17
|
+
subject { super().properties.fetch('b') }
|
18
|
+
|
19
|
+
it { is_expected.to be_kind_of(Argo::ArrayProperty) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'c' do
|
23
|
+
subject { super().properties.fetch('c') }
|
24
|
+
|
25
|
+
it { is_expected.to be_kind_of(Argo::ArrayProperty) }
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'Example schemata' do
|
5
|
+
subject {
|
6
|
+
json = read_fixture('simple_example.json')
|
7
|
+
Argo::Parser.new(JSON.parse(json)).root
|
8
|
+
}
|
9
|
+
|
10
|
+
it 'has a title' do
|
11
|
+
expect(subject.title).to eq('Product')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'is an object' do
|
15
|
+
expect(subject.type).to eq(:object)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'refers to the draft specification v4' do
|
19
|
+
expect(subject.spec).to eq('http://json-schema.org/draft-04/schema#')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'has a description' do
|
23
|
+
expect(subject.description).to eq("A product from Acme's catalog")
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'properties' do
|
27
|
+
subject { super().properties }
|
28
|
+
|
29
|
+
it 'has four items' do
|
30
|
+
expect(subject.length).to eq(4)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'id' do
|
34
|
+
subject { super().fetch('id') }
|
35
|
+
|
36
|
+
it { is_expected.to be_kind_of(Argo::IntegerProperty) }
|
37
|
+
|
38
|
+
it 'has a description' do
|
39
|
+
expect(subject.description).
|
40
|
+
to eq('The unique identifier for a product')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'is required' do
|
44
|
+
expect(subject).to be_required
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'has no constraints' do
|
48
|
+
expect(subject.constraints).to be_empty
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'name' do
|
53
|
+
subject { super().fetch('name') }
|
54
|
+
|
55
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
56
|
+
|
57
|
+
it 'has a description' do
|
58
|
+
expect(subject.description).to eq('Name of the product')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'is required' do
|
62
|
+
expect(subject).to be_required
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'has no constraints' do
|
66
|
+
expect(subject.constraints).to be_empty
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'price' do
|
71
|
+
subject { super().fetch('price') }
|
72
|
+
|
73
|
+
it { is_expected.to be_kind_of(Argo::NumberProperty) }
|
74
|
+
|
75
|
+
it 'has no description' do
|
76
|
+
expect(subject.description).to be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'is required' do
|
80
|
+
expect(subject).to be_required
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'has constraints' do
|
84
|
+
expect(subject.constraints).
|
85
|
+
to eq(minimum: 0, exclusive_minimum: true)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'tags' do
|
90
|
+
subject { super().fetch('tags') }
|
91
|
+
|
92
|
+
it { is_expected.to be_kind_of(Argo::ArrayProperty) }
|
93
|
+
|
94
|
+
it 'has no description' do
|
95
|
+
expect(subject.description).to be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'is not required' do
|
99
|
+
expect(subject).not_to be_required
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'has constraints' do
|
103
|
+
expect(subject.constraints).
|
104
|
+
to eq(min_items: 1, unique_items: true)
|
105
|
+
end
|
106
|
+
|
107
|
+
describe 'items' do
|
108
|
+
subject { super().items }
|
109
|
+
|
110
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'argo/parser'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
RSpec.describe 'tmpfs' do
|
5
|
+
# See http://json-schema.org/example2.html
|
6
|
+
|
7
|
+
subject {
|
8
|
+
json = read_fixture('tmpfs.json')
|
9
|
+
Argo::Parser.new(JSON.parse(json)).root
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'has no title' do
|
13
|
+
expect(subject.title).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'properties' do
|
17
|
+
subject { super().properties }
|
18
|
+
|
19
|
+
it 'has two items' do
|
20
|
+
expect(subject.length).to eq(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'type' do
|
24
|
+
subject { super().fetch('type') }
|
25
|
+
|
26
|
+
it { is_expected.to be_kind_of(Argo::StringProperty) }
|
27
|
+
|
28
|
+
it 'is required' do
|
29
|
+
expect(subject).to be_required
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has constraints' do
|
33
|
+
expect(subject.constraints).to eq(enum: %w[ tmpfs ])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'sizeInMB' do
|
38
|
+
subject { super().fetch('sizeInMB') }
|
39
|
+
|
40
|
+
it { is_expected.to be_kind_of(Argo::IntegerProperty) }
|
41
|
+
|
42
|
+
it 'is required' do
|
43
|
+
expect(subject).to be_required
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'has constraints' do
|
47
|
+
expect(subject.constraints).to eq(minimum: 16, maximum: 512)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.filter_run :focus
|
3
|
+
config.run_all_when_everything_filtered = true
|
4
|
+
|
5
|
+
if config.files_to_run.one?
|
6
|
+
config.default_formatter = 'doc'
|
7
|
+
end
|
8
|
+
|
9
|
+
config.order = :random
|
10
|
+
|
11
|
+
Kernel.srand config.seed
|
12
|
+
|
13
|
+
config.expect_with :rspec do |expectations|
|
14
|
+
expectations.syntax = :expect
|
15
|
+
end
|
16
|
+
|
17
|
+
config.mock_with :rspec do |mocks|
|
18
|
+
mocks.syntax = :expect
|
19
|
+
mocks.verify_partial_doubles = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def read_fixture(name)
|
23
|
+
File.read(File.expand_path("../fixtures/#{name}", __FILE__))
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'argo/deferred_object'
|
2
|
+
|
3
|
+
RSpec.describe Argo::DeferredObject do
|
4
|
+
subject { described_class.new { receiver.delegee } }
|
5
|
+
let(:receiver) { double(delegee: delegee) }
|
6
|
+
let(:delegee) { double(message: nil) }
|
7
|
+
|
8
|
+
it 'does not call the block at initialization time' do
|
9
|
+
expect(receiver).to receive(:delegee).never
|
10
|
+
subject
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'calls the block when a method is called' do
|
14
|
+
expect(delegee).to receive(:message)
|
15
|
+
subject.message
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'delegates the value to the receiver' do
|
19
|
+
allow(delegee).to receive(:message).and_return('VALUE')
|
20
|
+
expect(subject.message).to eq('VALUE')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'evaluates the block only once' do
|
24
|
+
expect(receiver).to receive(:delegee).once.and_return(delegee)
|
25
|
+
2.times do
|
26
|
+
subject.message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'argo/immutable_keyword_struct'
|
2
|
+
|
3
|
+
RSpec.describe Argo::ImmutableKeywordStruct do
|
4
|
+
let(:klass) {
|
5
|
+
described_class.new(a: nil, b: 'foo') do
|
6
|
+
def hello
|
7
|
+
"hello #{b}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
}
|
11
|
+
|
12
|
+
context 'with defaults' do
|
13
|
+
subject { klass.new }
|
14
|
+
|
15
|
+
it 'assigns properties with defaults' do
|
16
|
+
expect(subject.a).to be_nil
|
17
|
+
expect(subject.b).to eq('foo')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'freezes values' do
|
21
|
+
expect {
|
22
|
+
subject.b << ' oops'
|
23
|
+
}.to raise_exception(RuntimeError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'allows method definition in a block' do
|
27
|
+
expect(subject.hello).to eq('hello foo')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with assigned values' do
|
32
|
+
subject { klass.new(b: 'bar') }
|
33
|
+
|
34
|
+
it 'overrides defaults' do
|
35
|
+
expect(subject.b).to eq('bar')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'freezes values' do
|
39
|
+
expect {
|
40
|
+
subject.b << ' oops'
|
41
|
+
}.to raise_exception(RuntimeError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'allows method definition in a block' do
|
45
|
+
expect(subject.hello).to eq('hello bar')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises an exception with an unrecognised keyword' do
|
50
|
+
expect {
|
51
|
+
klass.new(c: 1)
|
52
|
+
}.to raise_exception(ArgumentError)
|
53
|
+
end
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: argo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Battley
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.32'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.32'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
description: Expand JSON Schema(s) into introspectable Ruby objects
|
70
|
+
email: pbattley@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- COPYING.txt
|
75
|
+
files:
|
76
|
+
- COPYING.txt
|
77
|
+
- lib/argo/array_property.rb
|
78
|
+
- lib/argo/boolean_property.rb
|
79
|
+
- lib/argo/constraint_processor.rb
|
80
|
+
- lib/argo/deferred_object.rb
|
81
|
+
- lib/argo/dereferencer.rb
|
82
|
+
- lib/argo/immutable_keyword_struct.rb
|
83
|
+
- lib/argo/integer_property.rb
|
84
|
+
- lib/argo/number_property.rb
|
85
|
+
- lib/argo/object_property.rb
|
86
|
+
- lib/argo/parser.rb
|
87
|
+
- lib/argo/property.rb
|
88
|
+
- lib/argo/property_factory.rb
|
89
|
+
- lib/argo/schema.rb
|
90
|
+
- lib/argo/schema_factory.rb
|
91
|
+
- lib/argo/string_property.rb
|
92
|
+
- lib/argo/version.rb
|
93
|
+
- spec/integration/array_reference_spec.rb
|
94
|
+
- spec/integration/basic_example_spec.rb
|
95
|
+
- spec/integration/core_nested_schema_spec.rb
|
96
|
+
- spec/integration/core_simple_schema_spec.rb
|
97
|
+
- spec/integration/disk_device_spec.rb
|
98
|
+
- spec/integration/disk_uuid_spec.rb
|
99
|
+
- spec/integration/entry_schema_spec.rb
|
100
|
+
- spec/integration/nfs_spec.rb
|
101
|
+
- spec/integration/property_reference_spec.rb
|
102
|
+
- spec/integration/simple_example_spec.rb
|
103
|
+
- spec/integration/tmpfs_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
- spec/unit/deferred_object_spec.rb
|
106
|
+
- spec/unit/immutable_keyword_struct_spec.rb
|
107
|
+
homepage: https://github.com/threedaymonk/argo
|
108
|
+
licenses:
|
109
|
+
- ISC
|
110
|
+
metadata: {}
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 2.1.0
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 2.4.5
|
128
|
+
signing_key:
|
129
|
+
specification_version: 4
|
130
|
+
summary: JSON Schema expander
|
131
|
+
test_files: []
|