opushon 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -2
- data/VERSION.semver +1 -1
- data/lib/opushon/error/min_is_greater_than_max_error.rb +8 -0
- data/lib/opushon/error/minlen_is_longer_than_maxlen_error.rb +8 -0
- data/lib/opushon/instance.rb +4 -13
- data/lib/opushon/option_object.rb +19 -39
- data/lib/opushon/parameter/base.rb +47 -0
- data/lib/opushon/parameter/input.rb +34 -0
- data/lib/opushon/parameter/output.rb +10 -0
- data/lib/opushon/parameter.rb +9 -0
- data/lib/opushon/restricted_value.rb +35 -0
- data/lib/opushon/type/array.rb +10 -0
- data/lib/opushon/type/base.rb +12 -5
- data/lib/opushon/type/boolean.rb +0 -3
- data/lib/opushon/type/hash.rb +10 -0
- data/lib/opushon/type/number.rb +15 -13
- data/lib/opushon/type/string.rb +18 -13
- data/lib/opushon/verb.rb +0 -2
- data/lib/opushon/version.rb +2 -0
- data/opushon.gemspec +0 -1
- data/spec/opushon/parameter/input_spec.rb +161 -0
- data/spec/opushon/parameter/output_spec.rb +108 -0
- data/spec/opushon/parameter/spec_helper.rb +1 -0
- data/spec/opushon/restricted_value_spec.rb +42 -0
- data/spec/opushon_spec.rb +313 -323
- data/spec/support/immutable.rb +13 -13
- metadata +19 -18
- data/lib/opushon/attribute.rb +0 -29
- data/lib/opushon/option.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a3cb8fd9120b42f1f8c2158cc41c7e740bb659c
|
4
|
+
data.tar.gz: d6363f7c674d0efbfd668a8e10164e9623f2ab82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5889b5b0437163ec429e62377c13e30efd404b6fa1816d203b13655a9e658d4f6ea3efdb161feadebf6982403f2f6f2b94b04f2b40775c74e730c013e0283fd6
|
7
|
+
data.tar.gz: c475f71d712b5a3bb4c10ebf73ef5eaa912857a8049bbfa3e3b6d1d29883fabe884064ce1fc55a95eb4883e99345ce7c6357d9ce2d688838106f1d4bad6d9bfa
|
data/Rakefile
CHANGED
data/VERSION.semver
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/opushon/instance.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require_relative 'option'
|
2
1
|
require_relative 'option_object'
|
3
2
|
require_relative 'verb'
|
4
3
|
require 'json'
|
@@ -8,19 +7,20 @@ module Opushon
|
|
8
7
|
# Parse a Opushon string in opushon.
|
9
8
|
class Instance
|
10
9
|
def initialize(opushon)
|
11
|
-
o = JSON.
|
10
|
+
o = JSON.parse(opushon, symbolize_names: true)
|
12
11
|
|
13
12
|
unless o.is_a?(Hash)
|
14
13
|
fail SyntaxError
|
15
14
|
end
|
16
15
|
|
17
|
-
unless o.keys.
|
16
|
+
unless o.keys.to_set.subset? VERBS
|
18
17
|
fail VerbError
|
19
18
|
end
|
20
19
|
|
21
20
|
@options = {}
|
22
21
|
o.each do |verb, option_object|
|
23
|
-
|
22
|
+
option_object_sym = JSON.parse(option_object.to_json, symbolize_names: true)
|
23
|
+
@options.update verb => OptionObject.new(option_object_sym)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -30,14 +30,5 @@ module Opushon
|
|
30
30
|
def to_h
|
31
31
|
Hash[@options.each { |k,v| @options[k] = v.to_h }]
|
32
32
|
end
|
33
|
-
|
34
|
-
# Runs all the validations within the current context.
|
35
|
-
#
|
36
|
-
# @return [Boolean] Returns true if no errors are found, false otherwise.
|
37
|
-
#
|
38
|
-
# @api public
|
39
|
-
def valid?(verb, example)
|
40
|
-
@options.fetch(verb.to_s).valid? example
|
41
|
-
end
|
42
33
|
end
|
43
34
|
end
|
@@ -1,56 +1,36 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative 'verb'
|
1
|
+
require_relative 'parameter'
|
3
2
|
|
4
3
|
# Namespace for the Opushon library.
|
5
4
|
module Opushon
|
6
5
|
# Parse a Opushon string in opushon.
|
7
6
|
class OptionObject
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def initialize( title: '',
|
8
|
+
description: '',
|
9
|
+
parameters: {},
|
10
|
+
examples: {} )
|
12
11
|
|
13
|
-
@
|
14
|
-
|
15
|
-
query_string.each do |key, properties|
|
16
|
-
@query_string.update key => Attribute.new(properties)
|
17
|
-
end
|
12
|
+
@title = title.to_s
|
13
|
+
@description = description.to_s
|
18
14
|
|
19
|
-
@
|
20
|
-
|
21
|
-
parameters.each do |key, properties|
|
22
|
-
@parameters.update key => Attribute.new(properties)
|
23
|
-
end
|
15
|
+
@input_params = Parameter::Input.load parameters.fetch(:input) { nil }
|
16
|
+
@output_params = Parameter::Output.load parameters.fetch(:output) { nil }
|
24
17
|
|
25
|
-
@
|
18
|
+
@input_example = examples.fetch(:input) { nil }
|
19
|
+
@output_example = examples.fetch(:output) { nil }
|
26
20
|
|
27
|
-
|
28
|
-
fail InvalidExample unless valid?(@example)
|
29
|
-
end
|
30
|
-
|
31
|
-
@other_settings = members
|
21
|
+
freeze
|
32
22
|
end
|
33
23
|
|
34
24
|
# Dump option object's members to a hash.
|
35
25
|
def to_h
|
36
26
|
{
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# Runs all the validations within the current context.
|
46
|
-
#
|
47
|
-
# @return [Boolean] Returns true if no errors are found, false otherwise.
|
48
|
-
def valid?(example)
|
49
|
-
unless VERBS.include?(@verb.to_sym)
|
50
|
-
fail VerbError
|
51
|
-
end
|
52
|
-
|
53
|
-
true
|
27
|
+
title: @title,
|
28
|
+
description: @description,
|
29
|
+
parameters: { input: @input_params,
|
30
|
+
output: @output_params },
|
31
|
+
examples: { input: @input_example,
|
32
|
+
output: @output_example }
|
33
|
+
}
|
54
34
|
end
|
55
35
|
end
|
56
36
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative File.join '..', 'type'
|
2
|
+
|
3
|
+
# Namespace for the Opushon library.
|
4
|
+
module Opushon
|
5
|
+
module Parameter
|
6
|
+
# Abstract class.
|
7
|
+
class Base
|
8
|
+
def self.load(input_or_output_params)
|
9
|
+
if input_or_output_params.nil?
|
10
|
+
@input_or_output_params = nil
|
11
|
+
else
|
12
|
+
@input_or_output_params = {}
|
13
|
+
|
14
|
+
input_or_output_params.each do |key, properties|
|
15
|
+
properties_sym = JSON.parse(properties.to_json, symbolize_names: true)
|
16
|
+
@input_or_output_params.update key.to_sym => new(properties_sym).to_h
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@input_or_output_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize( title: '',
|
24
|
+
description: '',
|
25
|
+
nullifiable: true,
|
26
|
+
type: 'string', **type_properties )
|
27
|
+
|
28
|
+
@title = title.to_s
|
29
|
+
@description = description.to_s
|
30
|
+
@nullifiable = nullifiable
|
31
|
+
@type = Type.const_get(type.capitalize).new(type_properties)
|
32
|
+
|
33
|
+
freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
# Dump attribute's properties to a hash.
|
37
|
+
def to_h
|
38
|
+
{
|
39
|
+
title: @title,
|
40
|
+
description: @description,
|
41
|
+
nullifiable: @nullifiable,
|
42
|
+
type: @type.to_sym
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative File.join '..', 'restricted_value'
|
3
|
+
|
4
|
+
# Namespace for the Opushon library.
|
5
|
+
module Opushon
|
6
|
+
module Parameter
|
7
|
+
# Parse a Opushon input.
|
8
|
+
class Input < Base
|
9
|
+
def initialize( query_string: true,
|
10
|
+
restricted_values: nil,
|
11
|
+
title: '',
|
12
|
+
description: '',
|
13
|
+
nullifiable: true,
|
14
|
+
type: 'string', **type_properties )
|
15
|
+
|
16
|
+
@query_string = query_string
|
17
|
+
@restricted_values = RestrictedValue.load_list(restricted_values)
|
18
|
+
|
19
|
+
@title = title.to_s
|
20
|
+
@description = description.to_s
|
21
|
+
@nullifiable = nullifiable
|
22
|
+
@type = Type.const_get(type.capitalize).new(type_properties)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Dump attribute's properties to a hash.
|
26
|
+
def to_h
|
27
|
+
{
|
28
|
+
query_string: @query_string,
|
29
|
+
restricted_values: @restricted_values
|
30
|
+
}.merge(super).merge(@type.constraints)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Namespace for the Opushon library.
|
2
|
+
module Opushon
|
3
|
+
# Parse a Opushon string in opushon.
|
4
|
+
class RestrictedValue
|
5
|
+
attr_reader :value
|
6
|
+
|
7
|
+
def self.load_list(restricted_values)
|
8
|
+
return if restricted_values.nil?
|
9
|
+
|
10
|
+
restricted_values.map do |restricted_value|
|
11
|
+
new(JSON.parse(restricted_value.to_json, symbolize_names: true)).to_h
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize( title: '',
|
16
|
+
description: '',
|
17
|
+
value: )
|
18
|
+
|
19
|
+
@title = title.to_s
|
20
|
+
@description = description.to_s
|
21
|
+
@value = value
|
22
|
+
|
23
|
+
freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
# Dump instance's opushon to a hash.
|
27
|
+
def to_h
|
28
|
+
{
|
29
|
+
title: @title,
|
30
|
+
description: @description,
|
31
|
+
value: @value
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/opushon/type/base.rb
CHANGED
@@ -3,15 +3,22 @@ module Opushon
|
|
3
3
|
module Type
|
4
4
|
# Abstract class.
|
5
5
|
class Base
|
6
|
-
def
|
7
|
-
|
6
|
+
def initialize(*)
|
7
|
+
freeze
|
8
8
|
end
|
9
9
|
|
10
10
|
def to_h
|
11
11
|
{
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
type: to_sym
|
13
|
+
}.merge(constraints)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_sym
|
17
|
+
self.class.name.split('::').last.downcase
|
18
|
+
end
|
19
|
+
|
20
|
+
def constraints
|
21
|
+
{}
|
15
22
|
end
|
16
23
|
end
|
17
24
|
end
|
data/lib/opushon/type/boolean.rb
CHANGED
data/lib/opushon/type/number.rb
CHANGED
@@ -5,22 +5,24 @@ module Opushon
|
|
5
5
|
module Type
|
6
6
|
# The type number.
|
7
7
|
class Number < Base
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def initialize( min: nil,
|
9
|
+
max: nil )
|
10
|
+
|
11
|
+
if !min.nil? && !max.nil?
|
12
|
+
fail MinIsGreaterThanMaxError if min > max
|
13
|
+
end
|
14
|
+
|
15
|
+
@min = min
|
16
|
+
@max = max
|
13
17
|
|
14
|
-
|
15
|
-
0
|
18
|
+
freeze
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
})
|
21
|
+
def constraints
|
22
|
+
{
|
23
|
+
min: @min,
|
24
|
+
max: @max
|
25
|
+
}
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
data/lib/opushon/type/string.rb
CHANGED
@@ -5,22 +5,27 @@ module Opushon
|
|
5
5
|
module Type
|
6
6
|
# The type string.
|
7
7
|
class String < Base
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def initialize( minlen: nil,
|
9
|
+
maxlen: nil,
|
10
|
+
pattern: nil )
|
11
|
+
|
12
|
+
if !minlen.nil? && !maxlen.nil?
|
13
|
+
fail MinlenIsLongerThanMaxlenError if minlen > maxlen
|
14
|
+
end
|
15
|
+
|
16
|
+
@minlen = minlen
|
17
|
+
@maxlen = maxlen
|
18
|
+
@pattern = pattern
|
13
19
|
|
14
|
-
|
15
|
-
''
|
20
|
+
freeze
|
16
21
|
end
|
17
22
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
23
|
+
def constraints
|
24
|
+
{
|
25
|
+
minlen: @minlen,
|
26
|
+
maxlen: @maxlen,
|
27
|
+
pattern: @pattern
|
28
|
+
}
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
data/lib/opushon/verb.rb
CHANGED
data/lib/opushon/version.rb
CHANGED
data/opushon.gemspec
CHANGED
@@ -16,6 +16,5 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
17
17
|
spec.add_development_dependency 'minitest', '~> 5'
|
18
18
|
spec.add_development_dependency 'rake', '~> 10.0'
|
19
|
-
spec.add_development_dependency 'yard', '~> 0.8'
|
20
19
|
spec.add_development_dependency 'coveralls', '~> 0.7'
|
21
20
|
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Opushon::Parameter::Input do
|
4
|
+
subject do
|
5
|
+
Opushon::Parameter::Input
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '.load' do
|
9
|
+
it 'MUST return the hash' do
|
10
|
+
params = {
|
11
|
+
foo: subject.new(title: 'Foo').to_h,
|
12
|
+
bar: subject.new(title: 'Bar').to_h
|
13
|
+
}
|
14
|
+
|
15
|
+
subject.load(params).must_equal({
|
16
|
+
foo: subject.new(title: 'Foo').to_h,
|
17
|
+
bar: subject.new(title: 'Bar').to_h
|
18
|
+
})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.new' do
|
23
|
+
describe '#to_h' do
|
24
|
+
describe 'default params' do
|
25
|
+
describe 'default type' do
|
26
|
+
it 'MUST return the hash' do
|
27
|
+
o = subject.new
|
28
|
+
|
29
|
+
o.to_h.must_equal(title: '',
|
30
|
+
description: '',
|
31
|
+
type: 'string',
|
32
|
+
nullifiable: true,
|
33
|
+
query_string: true,
|
34
|
+
restricted_values: nil,
|
35
|
+
minlen: nil,
|
36
|
+
maxlen: nil,
|
37
|
+
pattern: nil)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'string type' do
|
42
|
+
it 'MUST return the hash' do
|
43
|
+
o = subject.new(type: 'string')
|
44
|
+
|
45
|
+
o.to_h.must_equal(title: '',
|
46
|
+
description: '',
|
47
|
+
type: 'string',
|
48
|
+
nullifiable: true,
|
49
|
+
query_string: true,
|
50
|
+
restricted_values: nil,
|
51
|
+
minlen: nil,
|
52
|
+
maxlen: nil,
|
53
|
+
pattern: nil)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'number type' do
|
58
|
+
it 'MUST return the hash' do
|
59
|
+
o = subject.new(type: 'number')
|
60
|
+
|
61
|
+
o.to_h.must_equal(title: '',
|
62
|
+
description: '',
|
63
|
+
type: 'number',
|
64
|
+
nullifiable: true,
|
65
|
+
query_string: true,
|
66
|
+
restricted_values: nil,
|
67
|
+
min: nil,
|
68
|
+
max: nil)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'boolean type' do
|
73
|
+
it 'MUST return the hash' do
|
74
|
+
o = subject.new(type: 'boolean')
|
75
|
+
|
76
|
+
o.to_h.must_equal(title: '',
|
77
|
+
description: '',
|
78
|
+
type: 'boolean',
|
79
|
+
nullifiable: true,
|
80
|
+
query_string: true,
|
81
|
+
restricted_values: nil)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'array type' do
|
86
|
+
it 'MUST return the hash' do
|
87
|
+
o = subject.new(type: 'array')
|
88
|
+
|
89
|
+
o.to_h.must_equal(title: '',
|
90
|
+
description: '',
|
91
|
+
type: 'array',
|
92
|
+
nullifiable: true,
|
93
|
+
query_string: true,
|
94
|
+
restricted_values: nil)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'hash type' do
|
99
|
+
it 'MUST return the hash' do
|
100
|
+
o = subject.new(type: 'hash')
|
101
|
+
|
102
|
+
o.to_h.must_equal(title: '',
|
103
|
+
description: '',
|
104
|
+
type: 'hash',
|
105
|
+
nullifiable: true,
|
106
|
+
query_string: true,
|
107
|
+
restricted_values: nil)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'random example' do
|
114
|
+
it 'MUST return the hash' do
|
115
|
+
o = subject.new(
|
116
|
+
description: 'State of the issues to return.',
|
117
|
+
type: 'boolean',
|
118
|
+
query_string: false,
|
119
|
+
nullifiable: true,
|
120
|
+
restricted_values: [
|
121
|
+
{
|
122
|
+
value: "open",
|
123
|
+
title: "Open"
|
124
|
+
},
|
125
|
+
{
|
126
|
+
value: "closed",
|
127
|
+
title: "Closed"
|
128
|
+
},
|
129
|
+
{
|
130
|
+
value: "all",
|
131
|
+
title: "All"
|
132
|
+
}
|
133
|
+
]
|
134
|
+
)
|
135
|
+
|
136
|
+
o.to_h.must_equal(title: '',
|
137
|
+
description: 'State of the issues to return.',
|
138
|
+
type: 'boolean',
|
139
|
+
nullifiable: true,
|
140
|
+
query_string: false,
|
141
|
+
restricted_values: [
|
142
|
+
{
|
143
|
+
title: 'Open',
|
144
|
+
description: '',
|
145
|
+
value: 'open'
|
146
|
+
},
|
147
|
+
{
|
148
|
+
title: 'Closed',
|
149
|
+
description: '',
|
150
|
+
value: 'closed'
|
151
|
+
},
|
152
|
+
{
|
153
|
+
title: 'All',
|
154
|
+
description: '',
|
155
|
+
value: 'all'
|
156
|
+
}
|
157
|
+
])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|