diaspora-vines 0.2.0.develop.2 → 0.2.0.develop.3

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.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'test_helper'
3
+ require "test_helper"
4
4
 
5
5
  class RouterWrapper
6
6
  def initialize(stream); @stream = stream; end
@@ -15,47 +15,67 @@ describe Vines::Stream::Server::Outbound::Authoritative do
15
15
  end
16
16
 
17
17
  def test_invalid_stanza
18
- node = node('<message/>')
19
- @stream.expect(:router, @router)
20
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
21
- assert @stream.verify
18
+ EM.run {
19
+ node = node("<message/>")
20
+ @stream.expect(:router, @router)
21
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
22
+ assert @stream.verify
23
+ EM.stop
24
+ }
22
25
  end
23
26
 
24
27
  def test_invalid_token
25
- node = node('<db:verify/>')
26
- router = RouterWrapper.new(nil)
27
- @stream.expect(:router, router)
28
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
29
- assert @stream.verify
28
+ EM.run {
29
+ node = node("<db:verify/>")
30
+ router = RouterWrapper.new(nil)
31
+ @stream.expect(:router, router)
32
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
33
+ assert @stream.verify
34
+ EM.stop
35
+ }
30
36
  end
31
37
 
32
38
  def test_valid_verification
33
- node = node(%Q{<db:verify xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="remote.host" to="local.host" id="1234" type="valid"/>})
34
- result = "<db:result xmlns:db='#{Vines::NAMESPACES[:legacy_dialback]}' from='#{node[:to]}' to='#{node[:from]}' type='#{node[:type]}'/>"
35
- @stream.expect(:router, @router)
36
- # NOTE this tests the 'inbound' stream var
37
- @stream.expect(:write, nil, [result])
38
- @stream.expect(:advance, nil, [Vines::Stream::Server::Ready])
39
- @stream.expect(:notify_connected, nil)
40
- # end
41
- @stream.expect(:nil?, false)
42
- @stream.expect(:close_connection, nil)
43
- @state.node(node)
44
- assert @stream.verify
39
+ EM.run {
40
+ node = node(
41
+ %(<db:verify xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" ) +
42
+ %(from="remote.host" to="local.host" id="1234" type="valid"/>)
43
+ )
44
+ result = %(<db:result xmlns:db='#{Vines::NAMESPACES[:legacy_dialback]}' ) +
45
+ %(from='#{node[:to]}' to='#{node[:from]}' type='#{node[:type]}'/>)
46
+ @stream.expect(:router, @router)
47
+ # NOTE this tests the "inbound" stream var
48
+ @stream.expect(:write, nil, [result])
49
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Ready])
50
+ @stream.expect(:notify_connected, nil)
51
+ # end
52
+ @stream.expect(:nil?, false)
53
+ @stream.expect(:close_connection, nil)
54
+ @state.node(node)
55
+ assert @stream.verify
56
+ EM.stop
57
+ }
45
58
  end
46
59
 
47
60
  def test_invalid_verification
48
- node = node(%Q{<db:verify xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" from="remote.host" to="local.host" id="1234" type="invalid"/>})
49
- result = "<db:result xmlns:db='#{Vines::NAMESPACES[:legacy_dialback]}' from='#{node[:to]}' to='#{node[:from]}' type='#{node[:type]}'/>"
50
- @stream.expect(:router, @router)
51
- # NOTE this tests the 'inbound' stream var
52
- @stream.expect(:close_connection_after_writing, nil)
53
- @stream.expect(:write, nil, [result])
54
- # end
55
- @stream.expect(:nil?, false)
56
- @stream.expect(:close_connection, nil)
57
- @state.node(node)
58
- assert @stream.verify
61
+ EM.run {
62
+ node = node(
63
+ %(<db:verify xmlns:db="#{Vines::NAMESPACES[:legacy_dialback]}" ) +
64
+ %(from="remote.host" to="local.host" id="1234" type="invalid"/>)
65
+ )
66
+ result = %(<db:result xmlns:db='#{Vines::NAMESPACES[:legacy_dialback]}' ) +
67
+ %(from='#{node[:to]}' to='#{node[:from]}' type='#{node[:type]}'/>)
68
+ @stream.expect(:router, @router)
69
+ # NOTE this tests the "inbound" stream var
70
+ @stream.expect(:close_connection_after_writing, nil)
71
+ @stream.expect(:write, nil, [result])
72
+ # end
73
+ @stream.expect(:nil?, false)
74
+ @stream.expect(:close_connection, nil)
75
+ @state.node(node)
76
+ assert @stream.verify
77
+ EM.stop
78
+ }
59
79
  end
60
80
 
61
81
  private
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'test_helper'
3
+ require "test_helper"
4
4
 
5
5
  describe Vines::Stream::Server::Outbound::Start do
6
6
  before do
@@ -9,20 +9,32 @@ describe Vines::Stream::Server::Outbound::Start do
9
9
  end
10
10
 
11
11
  def test_missing_namespace
12
- node = node('<stream:stream/>')
13
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
12
+ EM.run {
13
+ node = node("<stream:stream/>")
14
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
15
+ EM.stop
16
+ }
14
17
  end
15
18
 
16
19
  def test_invalid_namespace
17
- node = node(%Q{<stream:stream xmlns="#{Vines::NAMESPACES[:stream]}"/>})
18
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
20
+ EM.run {
21
+ node = node(%(<stream:stream xmlns="#{Vines::NAMESPACES[:stream]}"/>))
22
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
23
+ EM.stop
24
+ }
19
25
  end
20
26
 
21
27
  def test_valid_stream
22
- node = node(%Q{<stream:stream xmlns='jabber:client' xmlns:stream='#{Vines::NAMESPACES[:stream]}' xml:lang='en' id='1234' from='host.com' version='1.0'>})
23
- @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::Auth])
24
- @state.node(node)
25
- assert @stream.verify
28
+ EM.run {
29
+ node = node(
30
+ %(<stream:stream xmlns="jabber:client" xmlns:stream="#{Vines::NAMESPACES[:stream]}" ) +
31
+ %(xml:lang="en" id="1234" from="host.com" version="1.0">)
32
+ )
33
+ @stream.expect(:advance, nil, [Vines::Stream::Server::Outbound::Auth])
34
+ @state.node(node)
35
+ assert @stream.verify
36
+ EM.stop
37
+ }
26
38
  end
27
39
 
28
40
  private
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'test_helper'
3
+ require "test_helper"
4
4
 
5
5
  describe Vines::Stream::Server::Ready do
6
6
  subject { Vines::Stream::Server::Ready.new(stream, nil) }
@@ -22,72 +22,96 @@ describe Vines::Stream::Server::Ready do
22
22
  SERVER_STANZAS.clear
23
23
  end
24
24
 
25
- it 'processes a valid node' do
26
- config = MiniTest::Mock.new
27
- config.expect(:local_jid?, true, [Vines::JID.new('romeo@verona.lit')])
28
-
29
- stream.expect(:config, config)
30
- stream.expect(:remote_domain, 'wonderland.lit')
31
- stream.expect(:domain, 'verona.lit')
32
- stream.expect(:user=, nil, [Vines::User.new(jid: 'alice@wonderland.lit')])
33
-
34
- node = node(%Q{<message from="alice@wonderland.lit" to="romeo@verona.lit"/>})
35
- subject.node(node)
36
- assert_equal 1, SERVER_STANZAS.size
37
- assert stream.verify
38
- assert config.verify
25
+ it "processes a valid node" do
26
+ EM.run {
27
+ config = MiniTest::Mock.new
28
+ config.expect(:local_jid?, true, [Vines::JID.new("romeo@verona.lit")])
29
+
30
+ stream.expect(:config, config)
31
+ stream.expect(:remote_domain, "wonderland.lit")
32
+ stream.expect(:domain, "verona.lit")
33
+ stream.expect(:user=, nil, [Vines::User.new(jid: "alice@wonderland.lit")])
34
+
35
+ node = node(%(<message from="alice@wonderland.lit" to="romeo@verona.lit"/>))
36
+ subject.node(node)
37
+ assert_equal 1, SERVER_STANZAS.size
38
+ assert stream.verify
39
+ assert config.verify
40
+ EM.stop
41
+ }
39
42
  end
40
43
 
41
- it 'raises unsupported-stanza-type stream error' do
42
- node = node('<bogus/>')
43
- -> { subject.node(node) }.must_raise Vines::StreamErrors::UnsupportedStanzaType
44
- assert SERVER_STANZAS.empty?
45
- assert stream.verify
44
+ it "raises unsupported-stanza-type stream error" do
45
+ EM.run {
46
+ node = node("<bogus/>")
47
+ -> { subject.node(node) }.must_raise Vines::StreamErrors::UnsupportedStanzaType
48
+ assert SERVER_STANZAS.empty?
49
+ assert stream.verify
50
+ EM.stop
51
+ }
46
52
  end
47
53
 
48
- it 'raises improper-addressing stream error when to address is missing' do
49
- node = node(%Q{<message from="alice@wonderland.lit"/>})
50
- -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing
51
- assert SERVER_STANZAS.empty?
52
- assert stream.verify
54
+ it "raises improper-addressing stream error when to address is missing" do
55
+ EM.run {
56
+ node = node(%(<message from="alice@wonderland.lit"/>))
57
+ -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing
58
+ assert SERVER_STANZAS.empty?
59
+ assert stream.verify
60
+ EM.stop
61
+ }
53
62
  end
54
63
 
55
- it 'raises jid-malformed stanza error when to address is invalid' do
56
- node = node(%Q{<message from="alice@wonderland.lit" to=" "/>})
57
- -> { subject.node(node) }.must_raise Vines::StanzaErrors::JidMalformed
58
- assert SERVER_STANZAS.empty?
59
- assert stream.verify
64
+ it "raises jid-malformed stanza error when to address is invalid" do
65
+ EM.run {
66
+ node = node(%(<message from="alice@wonderland.lit" to=" "/>))
67
+ -> { subject.node(node) }.must_raise Vines::StanzaErrors::JidMalformed
68
+ assert SERVER_STANZAS.empty?
69
+ assert stream.verify
70
+ EM.stop
71
+ }
60
72
  end
61
73
 
62
- it 'raises improper-addressing stream error' do
63
- node = node(%Q{<message to="romeo@verona.lit"/>})
64
- -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing
65
- assert SERVER_STANZAS.empty?
66
- assert stream.verify
74
+ it "raises improper-addressing stream error" do
75
+ EM.run {
76
+ node = node(%(<message to="romeo@verona.lit"/>))
77
+ -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing
78
+ assert SERVER_STANZAS.empty?
79
+ assert stream.verify
80
+ EM.stop
81
+ }
67
82
  end
68
83
 
69
- it 'raises jid-malformed stanza error for invalid from address' do
70
- node = node(%Q{<message from=" " to="romeo@verona.lit"/>})
71
- -> { subject.node(node) }.must_raise Vines::StanzaErrors::JidMalformed
72
- assert SERVER_STANZAS.empty?
73
- assert stream.verify
84
+ it "raises jid-malformed stanza error for invalid from address" do
85
+ EM.run {
86
+ node = node(%(<message from=" " to="romeo@verona.lit"/>))
87
+ -> { subject.node(node) }.must_raise Vines::StanzaErrors::JidMalformed
88
+ assert SERVER_STANZAS.empty?
89
+ assert stream.verify
90
+ EM.stop
91
+ }
74
92
  end
75
93
 
76
- it 'raises invalid-from stream error' do
77
- stream.expect(:remote_domain, 'wonderland.lit')
78
- node = node(%Q{<message from="alice@bogus.lit" to="romeo@verona.lit"/>})
79
- -> { subject.node(node) }.must_raise Vines::StreamErrors::InvalidFrom
80
- assert SERVER_STANZAS.empty?
81
- assert stream.verify
94
+ it "raises invalid-from stream error" do
95
+ EM.run {
96
+ stream.expect(:remote_domain, "wonderland.lit")
97
+ node = node(%(<message from="alice@bogus.lit" to="romeo@verona.lit"/>))
98
+ -> { subject.node(node) }.must_raise Vines::StreamErrors::InvalidFrom
99
+ assert SERVER_STANZAS.empty?
100
+ assert stream.verify
101
+ EM.stop
102
+ }
82
103
  end
83
104
 
84
- it 'raises host-unknown stream error' do
85
- stream.expect(:remote_domain, 'wonderland.lit')
86
- stream.expect(:domain, 'verona.lit')
87
- node = node(%Q{<message from="alice@wonderland.lit" to="romeo@bogus.lit"/>})
88
- -> { subject.node(node) }.must_raise Vines::StreamErrors::HostUnknown
89
- assert SERVER_STANZAS.empty?
90
- assert stream.verify
105
+ it "raises host-unknown stream error" do
106
+ EM.run {
107
+ stream.expect(:remote_domain, "wonderland.lit")
108
+ stream.expect(:domain, "verona.lit")
109
+ node = node(%(<message from="alice@wonderland.lit" to="romeo@bogus.lit"/>))
110
+ -> { subject.node(node) }.must_raise Vines::StreamErrors::HostUnknown
111
+ assert SERVER_STANZAS.empty?
112
+ assert stream.verify
113
+ EM.stop
114
+ }
91
115
  end
92
116
 
93
117
  private
@@ -18,48 +18,83 @@ describe Vines::Stream::Server::AuthMethod do
18
18
  end
19
19
 
20
20
  def test_missing_namespace
21
- node = node('<stream:stream/>')
22
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
21
+ EM.run {
22
+ node = node("<stream:stream/>")
23
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
24
+ EM.stop
25
+ }
23
26
  end
24
27
 
25
28
  def test_invalid_namespace
26
- node = node(%Q{<stream:stream xmlns="#{Vines::NAMESPACES[:stream]}"/>})
27
- assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
29
+ EM.run {
30
+ node = node(%(<stream:stream xmlns="#{Vines::NAMESPACES[:stream]}"/>))
31
+ assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) }
32
+ EM.stop
33
+ }
28
34
  end
29
35
 
30
36
  def test_valid_stream_tls_required
31
- node = node(%Q{<stream:stream xmlns="jabber:client" xmlns:stream="#{Vines::NAMESPACES[:stream]}" to="host.com" version="1.0"/>})
32
- features = node(%Q{<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}"><starttls xmlns="#{Vines::NAMESPACES[:tls]}"/><dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>})
33
- @stream.expect(:start, nil, [node])
34
- @stream.expect(:vhost, VhostWrapper.new(false))
35
- @stream.expect(:advance, nil, [Vines::Stream::Server::AuthMethod])
36
- @stream.expect(:dialback_retry?, false)
37
- @stream.expect(:write, nil, [features])
38
- @state.node(node)
39
- assert @stream.verify
37
+ EM.run {
38
+ node = node(
39
+ %(<stream:stream xmlns="jabber:client" ) +
40
+ %(xmlns:stream="#{Vines::NAMESPACES[:stream]}" to="host.com" version="1.0"/>)
41
+ )
42
+ features = node(
43
+ %(<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}">) +
44
+ %(<starttls xmlns="#{Vines::NAMESPACES[:tls]}"/>) +
45
+ %(<dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>)
46
+ )
47
+ @stream.expect(:start, nil, [node])
48
+ @stream.expect(:vhost, VhostWrapper.new(false))
49
+ @stream.expect(:advance, nil, [Vines::Stream::Server::AuthMethod])
50
+ @stream.expect(:dialback_retry?, false)
51
+ @stream.expect(:write, nil, [features])
52
+ @state.node(node)
53
+ assert @stream.verify
54
+ EM.stop
55
+ }
40
56
  end
41
57
 
42
58
  def test_valid_stream_with_dialback_flag
43
- node = node(%Q{<stream:stream xmlns="jabber:client" xmlns:stream="#{Vines::NAMESPACES[:stream]}" to="host.com" version="1.0"/>})
44
- features = node(%Q{<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}"><dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>})
45
- @stream.expect(:start, nil, [node])
46
- @stream.expect(:advance, nil, [Vines::Stream::Server::AuthMethod])
47
- @stream.expect(:dialback_retry?, true)
48
- @stream.expect(:write, nil, [features])
49
- @state.node(node)
50
- assert @stream.verify
59
+ EM.run {
60
+ node = node(
61
+ %(<stream:stream xmlns="jabber:client" ) +
62
+ %(xmlns:stream="#{Vines::NAMESPACES[:stream]}" to="host.com" version="1.0"/>)
63
+ )
64
+ features = node(
65
+ %(<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}">) +
66
+ %(<dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>)
67
+ )
68
+ @stream.expect(:start, nil, [node])
69
+ @stream.expect(:advance, nil, [Vines::Stream::Server::AuthMethod])
70
+ @stream.expect(:dialback_retry?, true)
71
+ @stream.expect(:write, nil, [features])
72
+ @state.node(node)
73
+ assert @stream.verify
74
+ EM.stop
75
+ }
51
76
  end
52
77
 
53
78
  def test_valid_stream
54
- node = node(%Q{<stream:stream xmlns="jabber:client" xmlns:stream="#{Vines::NAMESPACES[:stream]}" to="host.com" version="1.0"/>})
55
- features = node(%Q{<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}"><starttls xmlns="#{Vines::NAMESPACES[:tls]}"><required/></starttls><dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>})
56
- @stream.expect(:start, nil, [node])
57
- @stream.expect(:vhost, VhostWrapper.new(true))
58
- @stream.expect(:advance, nil, [Vines::Stream::Server::AuthMethod])
59
- @stream.expect(:dialback_retry?, false)
60
- @stream.expect(:write, nil, [features])
61
- @state.node(node)
62
- assert @stream.verify
79
+ EM.run {
80
+ node = node(
81
+ %(<stream:stream xmlns="jabber:client" ) +
82
+ %(xmlns:stream="#{Vines::NAMESPACES[:stream]}" to="host.com" version="1.0"/>)
83
+ )
84
+ features = node(
85
+ %(<stream:features xmlns:stream="#{Vines::NAMESPACES[:stream]}">) +
86
+ %(<starttls xmlns="#{Vines::NAMESPACES[:tls]}"><required/></starttls>) +
87
+ %(<dialback xmlns="#{Vines::NAMESPACES[:dialback]}"/></stream:features>)
88
+ )
89
+ @stream.expect(:start, nil, [node])
90
+ @stream.expect(:vhost, VhostWrapper.new(true))
91
+ @stream.expect(:advance, nil, [Vines::Stream::Server::AuthMethod])
92
+ @stream.expect(:dialback_retry?, false)
93
+ @stream.expect(:write, nil, [features])
94
+ @state.node(node)
95
+ assert @stream.verify
96
+ EM.stop
97
+ }
63
98
  end
64
99
 
65
100
  private
data/test/test_helper.rb CHANGED
@@ -6,6 +6,14 @@ require 'ext/nokogiri'
6
6
  require 'minitest/autorun'
7
7
  require 'rails/all'
8
8
 
9
+ # A simple hook allowing you to run a block of code after everything is done running
10
+ # In this case we want to delete the old sqlite database in case we run rake-test twice
11
+ Minitest.after_run {
12
+ db_file = "test.db"
13
+ File.delete(db_file) if File.exist?(db_file)
14
+ puts "After_run hook deleted #{db_file}"
15
+ }
16
+
9
17
  class MiniTest::Spec
10
18
 
11
19
  # Build an <iq> xml node with the given attributes. This is useful as a
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diaspora-vines
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.develop.2
4
+ version: 0.2.0.develop.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Graham
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-23 00:00:00.000000000 Z
12
+ date: 2015-08-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bcrypt
@@ -43,22 +43,16 @@ dependencies:
43
43
  name: eventmachine
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: 1.0.5
49
- - - "<"
46
+ - - "~>"
50
47
  - !ruby/object:Gem::Version
51
- version: '1.1'
48
+ version: 1.0.8
52
49
  type: :runtime
53
50
  prerelease: false
54
51
  version_requirements: !ruby/object:Gem::Requirement
55
52
  requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- version: 1.0.5
59
- - - "<"
53
+ - - "~>"
60
54
  - !ruby/object:Gem::Version
61
- version: '1.1'
55
+ version: 1.0.8
62
56
  - !ruby/object:Gem::Dependency
63
57
  name: http_parser.rb
64
58
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +95,34 @@ dependencies:
101
95
  - - "~>"
102
96
  - !ruby/object:Gem::Version
103
97
  version: '4.1'
98
+ - !ruby/object:Gem::Dependency
99
+ name: pronto
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: 0.4.2
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: 0.4.2
112
+ - !ruby/object:Gem::Dependency
113
+ name: pronto-rubocop
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: 0.4.4
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: 0.4.4
104
126
  - !ruby/object:Gem::Dependency
105
127
  name: rails
106
128
  requirement: !ruby/object:Gem::Requirement