useless-doc 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/useless/doc/core/body.rb +1 -1
- data/lib/useless/doc/core/domain.rb +6 -2
- data/lib/useless/doc/core/request.rb +3 -3
- data/lib/useless/doc/core/resource.rb +1 -1
- data/lib/useless/doc/core/response.rb +1 -1
- data/lib/useless/doc/dsl.rb +8 -0
- data/lib/useless/doc/router.rb +12 -2
- data/lib/useless/doc/serialization/dump.rb +2 -0
- data/lib/useless/doc/serialization/load.rb +14 -0
- data/lib/useless/doc/ui/godel/api.mustache +2 -2
- data/lib/useless/doc/ui/godel/domain.mustache +3 -3
- data/lib/useless/doc/ui/godel/stylesheet.css +13 -4
- data/lib/useless/doc/ui/godel.rb +19 -2
- data/lib/useless/doc/version.rb +1 -1
- data/spec/documents/api.json +1 -0
- data/spec/documents/domain.json +1 -0
- data/spec/useless/doc/dsl_spec.rb +2 -0
- data/spec/useless/doc/router_spec.rb +10 -0
- data/spec/useless/doc/serialization/dump_spec.rb +4 -0
- data/spec/useless/doc/serialization/load_spec.rb +2 -0
- data/spec/useless/doc/ui/godel_spec.rb +34 -4
- data/useless-doc.gemspec +1 -0
- metadata +18 -2
@@ -13,12 +13,15 @@ module Useless
|
|
13
13
|
# @!attribute [r] description
|
14
14
|
# @return [String] a description of the domain.
|
15
15
|
#
|
16
|
+
# @!attribute [r] timestamp
|
17
|
+
# @return [Time] the time that this domain doc was last updated.
|
18
|
+
#
|
16
19
|
# @!attribute [r] apis
|
17
20
|
# @return [Array<API>] the APIs included in this domain.
|
18
21
|
#
|
19
22
|
class Domain
|
20
23
|
|
21
|
-
attr_accessor :name, :url, :description, :apis
|
24
|
+
attr_accessor :name, :url, :description, :timestamp, :apis
|
22
25
|
|
23
26
|
# @param [Hash] attrs corresponds to the class's instance attributes.
|
24
27
|
#
|
@@ -26,7 +29,8 @@ module Useless
|
|
26
29
|
@name = attrs[:name]
|
27
30
|
@url = attrs[:url]
|
28
31
|
@description = attrs[:description]
|
29
|
-
@
|
32
|
+
@timestamp = attrs[:timestamp]
|
33
|
+
@apis = attrs[:apis] || []
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
@@ -54,10 +54,10 @@ module Useless
|
|
54
54
|
@method = attrs[:method]
|
55
55
|
@description = attrs[:description]
|
56
56
|
@authentication_required = attrs[:authentication_required]
|
57
|
-
@parameters = attrs[:parameters]
|
58
|
-
@headers = attrs[:headers]
|
57
|
+
@parameters = attrs[:parameters] || []
|
58
|
+
@headers = attrs[:headers] || []
|
59
59
|
@body = attrs[:body]
|
60
|
-
@responses = attrs[:responses]
|
60
|
+
@responses = attrs[:responses] || []
|
61
61
|
end
|
62
62
|
|
63
63
|
# Documentation for a request parameter for an API action.
|
data/lib/useless/doc/dsl.rb
CHANGED
@@ -84,6 +84,14 @@ module Useless
|
|
84
84
|
@attributes[:description] = description
|
85
85
|
end
|
86
86
|
|
87
|
+
def timestamp(timestamp)
|
88
|
+
if timestamp.is_a?(String)
|
89
|
+
timestamp = Time.parse(timestamp)
|
90
|
+
end
|
91
|
+
|
92
|
+
@attributes[:timestamp] = timestamp
|
93
|
+
end
|
94
|
+
|
87
95
|
def api(name, &block)
|
88
96
|
api = API.build name: name, &block
|
89
97
|
@attributes[:apis] << api
|
data/lib/useless/doc/router.rb
CHANGED
@@ -11,6 +11,16 @@ module Useless
|
|
11
11
|
@default ||= Doc::Router::Default.new
|
12
12
|
end
|
13
13
|
|
14
|
+
def self.uri_for(raw_url)
|
15
|
+
url = raw_url.dup
|
16
|
+
|
17
|
+
unless url =~ /^https?:\/\//
|
18
|
+
url = 'http://' + url
|
19
|
+
end
|
20
|
+
|
21
|
+
URI(url)
|
22
|
+
end
|
23
|
+
|
14
24
|
def doc_for_api(url)
|
15
25
|
end
|
16
26
|
|
@@ -26,7 +36,7 @@ module Useless
|
|
26
36
|
|
27
37
|
def doc_for_api(url)
|
28
38
|
return nil unless supported_url?(url)
|
29
|
-
uri =
|
39
|
+
uri = Router.uri_for(url)
|
30
40
|
host = uri.host
|
31
41
|
new_host = host.
|
32
42
|
split('.').
|
@@ -36,7 +46,7 @@ module Useless
|
|
36
46
|
end
|
37
47
|
|
38
48
|
def api_for_doc(url)
|
39
|
-
uri =
|
49
|
+
uri = Router.uri_for(url)
|
40
50
|
host = uri.host
|
41
51
|
parts = host.split('.')
|
42
52
|
parts.slice!(-3) if parts[-3] == 'doc'
|
@@ -30,6 +30,7 @@ module Useless
|
|
30
30
|
'name' => domain.name,
|
31
31
|
'url' => domain.url,
|
32
32
|
'description' => domain.description,
|
33
|
+
'timestamp' => domain.timestamp ? domain.timestamp.iso8601 : nil,
|
33
34
|
'apis' => domain.apis.map { |api| api(api) }
|
34
35
|
end
|
35
36
|
end
|
@@ -46,6 +47,7 @@ module Useless
|
|
46
47
|
'name' => api.name,
|
47
48
|
'url' => api.url,
|
48
49
|
'description' => api.description,
|
50
|
+
'timestamp' => api.timestamp ? api.timestamp.iso8601 : nil,
|
49
51
|
'resources' => api.resources.map { |resource| resource(resource) }
|
50
52
|
end
|
51
53
|
end
|
@@ -51,9 +51,16 @@ module Useless
|
|
51
51
|
api json
|
52
52
|
end
|
53
53
|
|
54
|
+
timestamp = begin
|
55
|
+
Time.parse(hash['timestamp'])
|
56
|
+
rescue TypeError, ArgumentError
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
54
60
|
Useless::Doc::Core::Domain.new \
|
55
61
|
name: hash['name'],
|
56
62
|
url: hash['url'],
|
63
|
+
timestamp: timestamp,
|
57
64
|
description: hash['description'],
|
58
65
|
apis: apis
|
59
66
|
end
|
@@ -73,9 +80,16 @@ module Useless
|
|
73
80
|
resource json
|
74
81
|
end
|
75
82
|
|
83
|
+
timestamp = begin
|
84
|
+
Time.parse(hash['timestamp'])
|
85
|
+
rescue TypeError, ArgumentError
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
76
89
|
Useless::Doc::Core::API.new \
|
77
90
|
name: hash['name'],
|
78
91
|
url: hash['url'],
|
92
|
+
timestamp: timestamp,
|
79
93
|
description: hash['description'],
|
80
94
|
resources: resources
|
81
95
|
end
|
@@ -13,14 +13,14 @@
|
|
13
13
|
<section class="api header-section">
|
14
14
|
<a class="name header-section-title" href="{{doc_url}}">{{name}}</a>
|
15
15
|
|
16
|
-
|
16
|
+
{{{description}}}
|
17
17
|
</section>
|
18
18
|
{{/apis}}
|
19
19
|
</header>
|
20
20
|
|
21
21
|
<section class="main description">
|
22
|
-
<article>
|
23
|
-
|
22
|
+
<article class="description domain">
|
23
|
+
{{{description}}}
|
24
24
|
</article>
|
25
25
|
</section>
|
26
26
|
</body>
|
@@ -10,6 +10,7 @@ h1, h2, h3, h4 {
|
|
10
10
|
font-family: 'Open Sans Condensed', sans-serif;
|
11
11
|
margin-top: 0;
|
12
12
|
margin-bottom: 0.25em;
|
13
|
+
color: #333;
|
13
14
|
}
|
14
15
|
|
15
16
|
h2 {
|
@@ -35,11 +36,19 @@ h4 span.content-type {
|
|
35
36
|
font-size: 0.75em;
|
36
37
|
}
|
37
38
|
|
38
|
-
|
39
|
-
color: #
|
39
|
+
article.description {
|
40
|
+
color: #555;
|
40
41
|
margin-top: 0;
|
41
42
|
}
|
42
43
|
|
44
|
+
article.description code {
|
45
|
+
font-family: 'Courier New', 'Courier', monospace;
|
46
|
+
}
|
47
|
+
|
48
|
+
article.description h2 {
|
49
|
+
margin-bottom: 0.25em;
|
50
|
+
}
|
51
|
+
|
43
52
|
p.description.request {
|
44
53
|
margin-bottom: 0.5em;
|
45
54
|
}
|
@@ -71,7 +80,7 @@ header section.header-section.api {
|
|
71
80
|
}
|
72
81
|
|
73
82
|
header section.header-section p {
|
74
|
-
margin
|
83
|
+
margin: 0.25em 0 0.75em;
|
75
84
|
}
|
76
85
|
|
77
86
|
header section.header-section a.header-section-title {
|
@@ -85,7 +94,7 @@ header section.header-section td.description {
|
|
85
94
|
|
86
95
|
section.main {
|
87
96
|
position: relative;
|
88
|
-
margin-left:
|
97
|
+
margin-left: 303px;
|
89
98
|
min-width: 520px;
|
90
99
|
}
|
91
100
|
|
data/lib/useless/doc/ui/godel.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'mustache'
|
2
2
|
require 'forwardable'
|
3
3
|
require 'rack/utils'
|
4
|
+
require 'redcarpet'
|
4
5
|
|
5
6
|
require 'useless/doc/core/domain'
|
6
7
|
require 'useless/doc/core/api'
|
@@ -16,6 +17,14 @@ module Useless
|
|
16
17
|
File.dirname(__FILE__) + '/godel'
|
17
18
|
end
|
18
19
|
|
20
|
+
def self.markdown
|
21
|
+
@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML,
|
22
|
+
:no_intra_emphasis => true, :tables => true,
|
23
|
+
:fenced_code_blocks => true,:autolink => true,
|
24
|
+
:space_after_headers => true, :lax_spacing => true,
|
25
|
+
:superscript => true)
|
26
|
+
end
|
27
|
+
|
19
28
|
def initialize(router)
|
20
29
|
@router = router
|
21
30
|
end
|
@@ -39,7 +48,7 @@ module Useless
|
|
39
48
|
class Domain < Mustache
|
40
49
|
extend Forwardable
|
41
50
|
|
42
|
-
def_delegators :@domain, :name
|
51
|
+
def_delegators :@domain, :name
|
43
52
|
|
44
53
|
self.template_file = Godel.asset_path + '/domain.mustache'
|
45
54
|
|
@@ -48,6 +57,10 @@ module Useless
|
|
48
57
|
@router = router
|
49
58
|
end
|
50
59
|
|
60
|
+
def description
|
61
|
+
Godel.markdown.render(@domain.description)
|
62
|
+
end
|
63
|
+
|
51
64
|
def apis
|
52
65
|
@domain.apis.map{ |api| Godel::API.new(api, @router) }
|
53
66
|
end
|
@@ -56,7 +69,7 @@ module Useless
|
|
56
69
|
class API < Mustache
|
57
70
|
extend Forwardable
|
58
71
|
|
59
|
-
def_delegators :@api, :name, :url
|
72
|
+
def_delegators :@api, :name, :url
|
60
73
|
|
61
74
|
self.template_file = Godel.asset_path + '/api.mustache'
|
62
75
|
|
@@ -69,6 +82,10 @@ module Useless
|
|
69
82
|
@router.doc_for_api(@api.url)
|
70
83
|
end
|
71
84
|
|
85
|
+
def description
|
86
|
+
Godel.markdown.render(@api.description)
|
87
|
+
end
|
88
|
+
|
72
89
|
def resources
|
73
90
|
@api.resources.map{ |resource| Godel::Resource.new(resource, @router) }
|
74
91
|
end
|
data/lib/useless/doc/version.rb
CHANGED
data/spec/documents/api.json
CHANGED
data/spec/documents/domain.json
CHANGED
@@ -11,6 +11,7 @@ describe Useless::Doc::DSL::Domain do
|
|
11
11
|
domain = Useless::Doc.domain 'useless.io' do
|
12
12
|
url 'http://useless.io'
|
13
13
|
description 'A collection of useless APIs.'
|
14
|
+
timestamp '2013-03-06 11:13 PM'
|
14
15
|
|
15
16
|
api 'Twonk' do
|
16
17
|
url 'twonk.useless.io'
|
@@ -21,6 +22,7 @@ describe Useless::Doc::DSL::Domain do
|
|
21
22
|
domain.name.should == 'useless.io'
|
22
23
|
domain.url.should == 'http://useless.io'
|
23
24
|
domain.description.should == 'A collection of useless APIs.'
|
25
|
+
domain.timestamp.should == Time.parse('2013-03-06 11:13 PM')
|
24
26
|
|
25
27
|
domain.apis.first.name.should == 'Twonk'
|
26
28
|
domain.apis.first.url.should == 'twonk.useless.io'
|
@@ -18,6 +18,11 @@ describe Useless::Doc::Router::Default do
|
|
18
18
|
it 'should return nil if the specified URL is not part of the domain' do
|
19
19
|
@router.doc_for_api('http://nonexistant.domain.com/some/path').should be_nil
|
20
20
|
end
|
21
|
+
|
22
|
+
it 'should handle URLs that are missing a scheme' do
|
23
|
+
@router.doc_for_api('api.domain.com/some/path').
|
24
|
+
should == 'http://api.doc.domain.com/some/path'
|
25
|
+
end
|
21
26
|
end
|
22
27
|
|
23
28
|
describe '.api_for_doc' do
|
@@ -34,5 +39,10 @@ describe Useless::Doc::Router::Default do
|
|
34
39
|
it 'should return nil if the resulting URL is not part of the domain' do
|
35
40
|
@router.api_for_doc('http://nonexistant.doc.domain.com/some/path').should be_nil
|
36
41
|
end
|
42
|
+
|
43
|
+
it 'should handle URLs that are missing a scheme' do
|
44
|
+
@router.api_for_doc('api.doc.domain.com/some/path').
|
45
|
+
should == 'http://api.domain.com/some/path'
|
46
|
+
end
|
37
47
|
end
|
38
48
|
end
|
@@ -33,6 +33,7 @@ describe Useless::Doc::Serialization::Dump do
|
|
33
33
|
domain = Useless::Doc::Core::Domain.new \
|
34
34
|
name: 'Useless',
|
35
35
|
url: 'http://useless.io',
|
36
|
+
timestamp: Time.parse('2013-03-06 11:13 PM'),
|
36
37
|
description: 'A collection of useless APIs.',
|
37
38
|
apis: [api]
|
38
39
|
|
@@ -40,6 +41,7 @@ describe Useless::Doc::Serialization::Dump do
|
|
40
41
|
hash = Useless::Doc::Serialization::Load.json_to_hash(json)
|
41
42
|
hash['name'].should == 'Useless'
|
42
43
|
hash['url'].should == 'http://useless.io'
|
44
|
+
hash['timestamp'].should == Time.parse('2013-03-06 11:13 PM').iso8601
|
43
45
|
hash['description'].should == 'A collection of useless APIs.'
|
44
46
|
|
45
47
|
api_hash = Useless::Doc::Serialization::Load.json_to_hash(hash['apis'][0])
|
@@ -59,6 +61,7 @@ describe Useless::Doc::Serialization::Dump do
|
|
59
61
|
api = Useless::Doc::Core::API.new \
|
60
62
|
name: 'Twiddles API',
|
61
63
|
url: 'twiddles.useless.io',
|
64
|
+
timestamp: Time.parse('2013-03-06 11:13 PM'),
|
62
65
|
description: 'Pretty much, like, everything you\'re looking for',
|
63
66
|
resources: [resource]
|
64
67
|
|
@@ -66,6 +69,7 @@ describe Useless::Doc::Serialization::Dump do
|
|
66
69
|
hash = Useless::Doc::Serialization::Load.json_to_hash(json)
|
67
70
|
hash['name'].should == 'Twiddles API'
|
68
71
|
hash['url'].should == 'twiddles.useless.io'
|
72
|
+
hash['timestamp'].should == Time.parse('2013-03-06 11:13 PM').iso8601
|
69
73
|
hash['description'].should == 'Pretty much, like, everything you\'re looking for'
|
70
74
|
|
71
75
|
resource_hash = Useless::Doc::Serialization::Load.json_to_hash(hash['resources'][0])
|
@@ -45,6 +45,7 @@ describe Useless::Doc::Serialization::Load do
|
|
45
45
|
domain = Useless::Doc::Serialization::Load.domain document.read
|
46
46
|
domain.name.should == 'Useless'
|
47
47
|
domain.url.should == 'http://useless.io'
|
48
|
+
domain.timestamp.should == Time.parse('2013-03-06T23:13:00-05:00')
|
48
49
|
domain.description.should == 'A collection of useless APIs.'
|
49
50
|
domain.apis.first.name.should == 'The Jah API'
|
50
51
|
domain.apis.first.url.should == 'http://jah.useless.io'
|
@@ -58,6 +59,7 @@ describe Useless::Doc::Serialization::Load do
|
|
58
59
|
api = Useless::Doc::Serialization::Load.api document.read
|
59
60
|
api.name.should == 'Twonk API'
|
60
61
|
api.url.should == 'twonk.useless.io'
|
62
|
+
api.timestamp.should == Time.parse('2013-03-06T23:13:00-05:00')
|
61
63
|
api.description.should == 'Twonk information. Duh.'
|
62
64
|
api.resources.first.path.should == '/twonks/:id'
|
63
65
|
api.resources.first.description.should == 'The most critical aspect.'
|
@@ -2,6 +2,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
|
|
2
2
|
|
3
3
|
require 'nokogiri'
|
4
4
|
require 'useless/doc'
|
5
|
+
require 'useless/doc/core/domain'
|
6
|
+
require 'useless/doc/core/api'
|
5
7
|
require 'useless/doc/router'
|
6
8
|
require 'useless/doc/ui/godel'
|
7
9
|
|
@@ -9,10 +11,10 @@ describe Useless::Doc::UI::Godel do
|
|
9
11
|
describe '.html' do
|
10
12
|
context 'for a Core::Domain instance' do
|
11
13
|
before(:all) do
|
12
|
-
router = Useless::Doc::Router.default
|
14
|
+
@router = Useless::Doc::Router.default
|
13
15
|
json = load_document('domain.json').read
|
14
16
|
domain = Useless::Doc.load.domain(json)
|
15
|
-
result = Useless::Doc::UI::Godel.new(router).html(domain)
|
17
|
+
result = Useless::Doc::UI::Godel.new(@router).html(domain)
|
16
18
|
@doc = Nokogiri::HTML(result)
|
17
19
|
end
|
18
20
|
|
@@ -23,11 +25,25 @@ describe Useless::Doc::UI::Godel do
|
|
23
25
|
end
|
24
26
|
|
25
27
|
it 'should render the domain description in an article p' do
|
26
|
-
description = @doc.css('article
|
28
|
+
description = @doc.css('article.description.domain p')
|
27
29
|
description.length.should == 1
|
28
30
|
description.first.content.should == 'A collection of useless APIs.'
|
29
31
|
end
|
30
32
|
|
33
|
+
it 'should not escape the description text' do
|
34
|
+
domain = Useless::Doc::Core::Domain.new description: '<span>The description</span>'
|
35
|
+
result = Useless::Doc::UI::Godel.new(@router).html(domain)
|
36
|
+
description = Nokogiri::HTML(result).css('article.description.domain p')
|
37
|
+
description.first.inner_html.should == '<span>The description</span>'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should interpret Markdown for the description' do
|
41
|
+
domain = Useless::Doc::Core::Domain.new description: '*The description*'
|
42
|
+
result = Useless::Doc::UI::Godel.new(@router).html(domain)
|
43
|
+
description = Nokogiri::HTML(result).css('article.description.domain p')
|
44
|
+
description.first.inner_html.should == '<em>The description</em>'
|
45
|
+
end
|
46
|
+
|
31
47
|
it 'should render API names as a\'s, with correct doc URLs' do
|
32
48
|
as = @doc.css('a.name')
|
33
49
|
as.length.should == 2
|
@@ -58,11 +74,25 @@ describe Useless::Doc::UI::Godel do
|
|
58
74
|
end
|
59
75
|
|
60
76
|
it 'should render the API description in an article p' do
|
61
|
-
description = @doc.css('article
|
77
|
+
description = @doc.css('article.description.api p')
|
62
78
|
description.length.should == 1
|
63
79
|
description.first.content.should == 'Twonk information. Duh.'
|
64
80
|
end
|
65
81
|
|
82
|
+
it 'should not escape the description text' do
|
83
|
+
domain = Useless::Doc::Core::API.new description: '<span>The description</span>'
|
84
|
+
result = Useless::Doc::UI::Godel.new(@router).html(domain)
|
85
|
+
description = Nokogiri::HTML(result).css('article.description.api p')
|
86
|
+
description.first.inner_html.should == '<span>The description</span>'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should interpret Markdown for the description' do
|
90
|
+
domain = Useless::Doc::Core::API.new description: '*The description*'
|
91
|
+
result = Useless::Doc::UI::Godel.new(@router).html(domain)
|
92
|
+
description = Nokogiri::HTML(result).css('article.description.api p')
|
93
|
+
description.first.inner_html.should == '<em>The description</em>'
|
94
|
+
end
|
95
|
+
|
66
96
|
it 'should render resouce paths as a\'s' do
|
67
97
|
as = @doc.css('a.path')
|
68
98
|
as.length.should == 2
|
data/useless-doc.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_dependency 'low', '~> 0.0.17'
|
21
21
|
gem.add_dependency 'sinatra', '~> 1.3.4'
|
22
22
|
gem.add_dependency 'mustache', '~> 0.99.4'
|
23
|
+
gem.add_dependency 'redcarpet', '~> 2.2.2'
|
23
24
|
|
24
25
|
gem.add_development_dependency 'rspec', '~> 2.12.0'
|
25
26
|
gem.add_development_dependency 'rack-test', '~> 0.6.2'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: useless-doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: oj
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: 0.99.4
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: redcarpet
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.2.2
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 2.2.2
|
110
126
|
- !ruby/object:Gem::Dependency
|
111
127
|
name: rspec
|
112
128
|
requirement: !ruby/object:Gem::Requirement
|