mq_reader 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +8 -0
- data/lib/mq_reader.rb +3 -0
- data/lib/mq_reader/mq_reader.rb +149 -0
- data/lib/mq_reader/version.rb +3 -0
- data/mq_reader.gemspec +17 -0
- data/spec/fixtures/address_found.json +1 -0
- data/spec/fixtures/address_not_found.json +1 -0
- data/spec/mq_reader/mq_reader_spec.rb +126 -0
- data/spec/spec_helper.rb +20 -0
- metadata +71 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 213f8ef4d130b18d54d5dde286ef08ad5984faf7
|
4
|
+
data.tar.gz: 1828e04bf2bbf9d1f3c2ebf914a3b3220977a2c5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 01b19271c4ee892c80ca975fad87dd6b205e666888beaf631eaa891b2535779251e3044db008f9112bc94decdb4cea38ed11f51890fb5fcf34822dce176bb04f
|
7
|
+
data.tar.gz: 2b327a7967b10d8c2cb04d508048ef2ea3358347253672bddf551840c3f1aea03ae90a3b28871a5c18ee2bea1a1d3cadf6ec20927c2c7a815b776ecc5f9c331d
|
data/Rakefile
ADDED
data/lib/mq_reader.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
module MQReader
|
2
|
+
|
3
|
+
BASE_URI = 'http://open.mapquestapi.com'
|
4
|
+
GEOCODING_PATH = '/geocoding/v1/address'
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
@options = []
|
9
|
+
|
10
|
+
# Geocode a address.
|
11
|
+
# This method takes an address as a string and performs the geocoding against mapquest's api.
|
12
|
+
# The options hash can have any option accepted by the mapquest geocoding api.
|
13
|
+
# The options key can be written ruby-style with underscores, they are transformed to mapquests format.
|
14
|
+
# If in the future a new option is added to the api by mapquest, you can add it in the options hash and it will work.
|
15
|
+
#
|
16
|
+
# @param [String] address to geocode
|
17
|
+
# @param [Hash] options for mapquest geocoding service
|
18
|
+
def geocode_address(address, options = {})
|
19
|
+
path = GEOCODING_PATH
|
20
|
+
params = ({ location: CGI::escape(address) }.merge!(to_mapquest_notation(options) ))
|
21
|
+
MQGeocode.new(send_get_to_mapquest(path, params))
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Method that posts to the mapquest geocoding api
|
27
|
+
#
|
28
|
+
# @params [String] path to the geocoding api. /geocoding/v1..
|
29
|
+
# @params [Hash] params to be sent with the request. See http://open.mapquestapi.com/geocoding/ for params details.
|
30
|
+
#
|
31
|
+
# @return [String] with geocoding response body.
|
32
|
+
def send_get_to_mapquest(path, params)
|
33
|
+
self.get(BASE_URI + path, query: { key: MQReader.configuration.api_key}.merge!(params)).body
|
34
|
+
end
|
35
|
+
|
36
|
+
# Turns underscore keys into mapquest's camelized keys
|
37
|
+
# I belive a good ruby api wrapper should let the developer write in a rubyish way.
|
38
|
+
# Mapquest accepts options that are camelcased and start with a lowercase letter.
|
39
|
+
#
|
40
|
+
# @param [Hash] options to turn into mapquest's key format
|
41
|
+
#
|
42
|
+
# @return [Hash] options hash with mapquest's key format
|
43
|
+
def to_mapquest_notation(options)
|
44
|
+
Hash[options.map{ |k, v| [camelize_string(k.to_s), v] }]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module UtilMethods
|
49
|
+
# Same as camelize(:lower) in ActiveSupport
|
50
|
+
#
|
51
|
+
# @param [String] string to be camelized
|
52
|
+
#
|
53
|
+
# @return [String] camelized string
|
54
|
+
#
|
55
|
+
# Example
|
56
|
+
# camelize_string("a_long_string") # => "aLongString"
|
57
|
+
def camelize_string(string)
|
58
|
+
string.split("_").each_with_index {|s, i| s.capitalize! unless i == 0 }.join("")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#Extend the module on inclusion.
|
63
|
+
#Include Httparty and prevent encoding the api_key(Already encoded by mapquest).
|
64
|
+
def self.included(base)
|
65
|
+
base.extend ClassMethods
|
66
|
+
base.extend UtilMethods
|
67
|
+
base.send :include, HTTParty
|
68
|
+
# Avoid encoding the api key
|
69
|
+
base.query_string_normalizer proc { |query|
|
70
|
+
query.map do |key, value|
|
71
|
+
"#{key}=#{value}"
|
72
|
+
end.join('&')
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Configuration Class
|
77
|
+
# Right now it's only used to set the API key from the application that's using the gem.
|
78
|
+
class Configuration
|
79
|
+
attr_accessor :api_key
|
80
|
+
end
|
81
|
+
|
82
|
+
class << self
|
83
|
+
attr_accessor :configuration
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.configuration
|
87
|
+
@configuration ||= Configuration.new
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.configure
|
91
|
+
yield(configuration)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Class used to be able to call #geocode_address directly.
|
95
|
+
class BaseClass
|
96
|
+
include MQReader
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.geocode_address(*args)
|
100
|
+
BaseClass.geocode_address(*args)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Class to handle the response from the mapquest api
|
104
|
+
#
|
105
|
+
# Provides methods to get every value from the geocoded address.
|
106
|
+
class MQGeocode
|
107
|
+
attr_reader :street, :city, :zip, :county, :state, :country, :lat, :lng, :raw_geocode
|
108
|
+
|
109
|
+
def initialize(json_geocode)
|
110
|
+
@raw_geocode = JSON.parse(json_geocode)
|
111
|
+
raise StandardError, "The request raised an error: #{@raw_geocode['info']['messages']}" if @raw_geocode['info']['statuscode'] != 0
|
112
|
+
return if @raw_geocode['results'].first['locations'].empty?
|
113
|
+
@lng,@lat = lat_lng_values
|
114
|
+
@street = value('street')
|
115
|
+
@city = value('adminArea5')
|
116
|
+
@county = value('adminArea4')
|
117
|
+
@state = value('adminArea3')
|
118
|
+
@country = value('adminArea1')
|
119
|
+
@zip = value('postalCode')
|
120
|
+
@type = value('type')
|
121
|
+
@geocode_quality = value('geocodeQuality')
|
122
|
+
@side_of_street = value('sideOfStreet')
|
123
|
+
end
|
124
|
+
|
125
|
+
def address_found?
|
126
|
+
@raw_geocode['results'].first['locations'].any?
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# Get the value of a field from the respond
|
132
|
+
def value(field)
|
133
|
+
@raw_geocode['results'].first['locations'].first[field]
|
134
|
+
end
|
135
|
+
|
136
|
+
# Get the latitude and longitude from the response
|
137
|
+
def lat_lng_values
|
138
|
+
latLng = value('latLng')
|
139
|
+
return [latLng['lng'],latLng['lat']]
|
140
|
+
end
|
141
|
+
|
142
|
+
# Use method_missing to define accesors for any response attributes that might not be listed in #initialize
|
143
|
+
# This accesors are rubyish(underscore notation).
|
144
|
+
def method_missing(method_sym, *arguments, &block)
|
145
|
+
result = send(:value, BaseClass.camelize_string(method_sym.to_s))
|
146
|
+
result.empty? ? super : result
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/mq_reader.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "mq_reader"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "Mapquest api wrapper"
|
5
|
+
s.date = "2013-02-18"
|
6
|
+
s.description = "This is a wrapper for mapquest's geocoding api."
|
7
|
+
s.authors = ["Santiago Piria"]
|
8
|
+
s.email = ["santiago.piria@gmail.com"]
|
9
|
+
s.homepage = "http://rubylearning.org/"
|
10
|
+
s.files = %w[Rakefile mq_reader.gemspec]
|
11
|
+
s.files += Dir.glob('lib/**/*.rb')
|
12
|
+
s.files += Dir.glob('spec/**/*')
|
13
|
+
s.require_paths = %w[lib]
|
14
|
+
s.test_files = Dir.glob('spec/**/*')
|
15
|
+
s.add_dependency 'httparty', '0.13.1'
|
16
|
+
s.license = 'MIT'
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"results":[{"locations":[{"latLng":{"lng":-56.15989,"lat":-34.889265},"adminArea4":"","adminArea5Type":"City","adminArea4Type":"County","adminArea5":"Montevideo","street":"Avenida 8 de Octubre 2710","adminArea1":"UY","adminArea3":"Montevideo","type":"s","displayLatLng":{"lng":-56.15989,"lat":-34.889265},"linkId":0,"postalCode":"11600","sideOfStreet":"N","dragPoint":false,"adminArea1Type":"Country","geocodeQuality":"POINT","geocodeQualityCode":"P1XXX","mapUrl":"http://open.mapquestapi.com/staticmap/v4/getmap?key=Fmjtd|luur2g61nl,bl=o5-9az25f&type=map&size=225,160&pois=purple-1,-34.8892649,-56.1598895,0,0|¢er=-34.8892649,-56.1598895&zoom=15&rand=1680921967","adminArea3Type":"State"}],"providedLocation":{"location":"2710 Avenida 8 de Octubre, Montevideo, Uruguay"}}],"options":{"ignoreLatLngInput":false,"maxResults":2,"thumbMaps":true},"info":{"copyright":{"text":"© 2014 MapQuest, Inc.","imageUrl":"http://api.mqcdn.com/res/mqlogo.gif","imageAltText":"© 2014 MapQuest, Inc."},"statuscode":0,"messages":[]}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"results":[{"locations":[],"providedLocation":{"location":"I INVENTEND THIS"}}],"options":{"ignoreLatLngInput":false,"maxResults":2,"thumbMaps":true},"info":{"copyright":{"text":"© 2014 MapQuest, Inc.","imageUrl":"http://api.mqcdn.com/res/mqlogo.gif","imageAltText":"© 2014 MapQuest, Inc."},"statuscode":0,"messages":[]}}
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
describe MQReader do
|
3
|
+
|
4
|
+
before(:each) do
|
5
|
+
MQReader.configure do |config|
|
6
|
+
config.api_key = YOUR_API_KEY
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'ClassMethods' do
|
11
|
+
|
12
|
+
before do
|
13
|
+
stub_get_geocode_with('address_found.json')
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#geocode_address' do
|
17
|
+
context 'address found' do
|
18
|
+
it 'should return MQGeocode object with attributes' do
|
19
|
+
geocode_obj = MQReader.geocode_address("2710 Avenida 8 de Octubre, Montevideo, Uruguay", { max_results: 2 })
|
20
|
+
expect(geocode_obj.class).to eq(MQReader::MQGeocode)
|
21
|
+
expect(geocode_obj.lat).to eq(-34.889265)
|
22
|
+
expect(geocode_obj.lng).to eq(-56.15989)
|
23
|
+
expect(geocode_obj.street).to eq('Avenida 8 de Octubre 2710')
|
24
|
+
expect(geocode_obj.geocode_quality).to eq('POINT')
|
25
|
+
expect(geocode_obj.country).to eq('UY')
|
26
|
+
expect(geocode_obj.geocode_quality_code).to eq('P1XXX')
|
27
|
+
expect(geocode_obj.address_found?).to be_true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
context 'address not found' do
|
31
|
+
it 'should return MQGeocode object with no attributes except raw_geocode' do
|
32
|
+
stub_get_geocode_with('address_not_found.json')
|
33
|
+
geocode_obj = MQReader.geocode_address("2710 Avenida 8 de Octubre, Montevideo, Uruguay", { max_results: 2 })
|
34
|
+
expect(geocode_obj.class).to eq(MQReader::MQGeocode)
|
35
|
+
expect(geocode_obj.street).to be_nil
|
36
|
+
expect(geocode_obj.address_found?).to be_false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
it 'should call #geocode_address on BaseClass' do
|
40
|
+
MQReader::BaseClass.should_receive(:geocode_address)
|
41
|
+
MQReader.geocode_address('home', max_results: 2)
|
42
|
+
end
|
43
|
+
it "should call #send_get_to_mapquest with correct params and MQGeocode#new" do
|
44
|
+
MQReader::BaseClass.should_receive(:send_get_to_mapquest).with(MQReader::GEOCODING_PATH, { location: 'home', 'maxResults' => 2 })
|
45
|
+
MQReader::MQGeocode.should_receive(:new)
|
46
|
+
MQReader.geocode_address('home', max_results: 2)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#send_get_to_mapquest' do
|
51
|
+
it 'should call #get on BaseClass, and the call #body on the result of #get' do
|
52
|
+
obj = double('object')
|
53
|
+
MQReader::BaseClass.should_receive(:get).with(MQReader::BASE_URI + 'path', { query: { key: MQReader.configuration.api_key, param: 'something' } }).and_return(obj)
|
54
|
+
obj.should_receive(:body)
|
55
|
+
MQReader::BaseClass.send(:send_get_to_mapquest, 'path', { param: 'something' })
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#to_mapquest_notation' do
|
60
|
+
it 'should transform keys' do
|
61
|
+
expect(MQReader::BaseClass.send(:to_mapquest_notation, ({}))).to eq({})
|
62
|
+
expect(MQReader::BaseClass.send(:to_mapquest_notation, ({a_key: 'value', another_key: 'value'}))).to eq({'aKey' => 'value', 'anotherKey' => 'value'})
|
63
|
+
expect(MQReader::BaseClass.send(:to_mapquest_notation, ({'' => 'value'}))).to eq({'' => 'value'})
|
64
|
+
expect(MQReader::BaseClass.send(:to_mapquest_notation, ({a_key: 'value'}))).to eq({'aKey' => 'value'})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'UtilMethods' do
|
71
|
+
describe 'camelize_string' do
|
72
|
+
it 'should camelize string and leave the first character lowercase' do
|
73
|
+
expect(MQReader::BaseClass.camelize_string('')).to eq('')
|
74
|
+
expect(MQReader::BaseClass.camelize_string('a_long_string')).to eq('aLongString')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'configuration' do
|
80
|
+
it 'should be possible to set api_key and retrieve it' do
|
81
|
+
MQReader.configure do |config|
|
82
|
+
config.api_key = "1234567"
|
83
|
+
end
|
84
|
+
expect(MQReader.configuration.api_key).to eq("1234567")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'MQGeocode class' do
|
89
|
+
|
90
|
+
let(:obj) { MQReader::MQGeocode.new("{\"results\":[{\"locations\":[{\"latLng\":{\"lng\":-56.15989,\"lat\":-34.889265},\"adminArea4\":\"\",\"adminArea5Type\":\"City\",\"adminArea4Type\":\"County\",\"adminArea5\":\"Montevideo\",\"street\":\"Avenida 8 de Octubre 2710\",\"adminArea1\":\"UY\",\"adminArea3\":\"Montevideo\",\"type\":\"s\",\"displayLatLng\":{\"lng\":-56.15989,\"lat\":-34.889265},\"linkId\":0,\"postalCode\":\"11600\",\"sideOfStreet\":\"N\",\"dragPoint\":false,\"adminArea1Type\":\"Country\",\"geocodeQuality\":\"POINT\",\"geocodeQualityCode\":\"P1XXX\",\"mapUrl\":\"http://open.mapquestapi.com/staticmap/v4/getmap?key=Fmjtd|luur2g61nl,bl=o5-9az25f&type=map&size=225,160&pois=purple-1,-34.8892649,-56.1598895,0,0|¢er=-34.8892649,-56.1598895&zoom=15&rand=1680921967\",\"adminArea3Type\":\"State\"}],\"providedLocation\":{\"location\":\"2710 Avenida 8 de Octubre, Montevideo, Uruguay\"}}],\"options\":{\"ignoreLatLngInput\":false,\"maxResults\":2,\"thumbMaps\":true},\"info\":{\"copyright\":{\"text\":\"© 2014 MapQuest, Inc.\",\"imageUrl\":\"http://api.mqcdn.com/res/mqlogo.gif\",\"imageAltText\":\"© 2014 MapQuest, Inc.\"},\"statuscode\":0,\"messages\":[]}}") }
|
91
|
+
|
92
|
+
describe 'intialization' do
|
93
|
+
context 'request with errors' do
|
94
|
+
it 'should raise an error' do
|
95
|
+
expect{MQReader::MQGeocode.new("{\"info\":{\"statuscode\":1,\"messages\":[\"The request failed.\"]}}")}.to raise_error(StandardError)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'request with no errors' do
|
100
|
+
it 'should have methods to access the geocode values' do
|
101
|
+
expect(obj.street).to eq('Avenida 8 de Octubre 2710')
|
102
|
+
expect(obj.geocode_quality).to eq('POINT')
|
103
|
+
expect(obj.address_found?).to be_true
|
104
|
+
end
|
105
|
+
it 'should have methods to access the variables that are not defined in the class. Via method_missing' do
|
106
|
+
expect(obj.street).to eq('Avenida 8 de Octubre 2710')
|
107
|
+
expect(obj.geocode_quality_code).to eq('P1XXX')
|
108
|
+
expect(obj.side_of_street).to eq('N')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'address_found?' do
|
114
|
+
context 'address found' do
|
115
|
+
it 'should return true' do
|
116
|
+
expect(obj.address_found?).to be_true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
context 'address not found' do
|
120
|
+
it 'should return false' do
|
121
|
+
expect(MQReader::MQGeocode.new("{\"results\":[{\"locations\":[]}], \"info\":{\"statuscode\":0}}").address_found?).to be_false
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../lib/mq_reader'
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'webmock/rspec'
|
5
|
+
require 'cgi'
|
6
|
+
WebMock.disable_net_connect!
|
7
|
+
|
8
|
+
def fixture_path
|
9
|
+
File.expand_path('../fixtures', __FILE__)
|
10
|
+
end
|
11
|
+
|
12
|
+
def fixture(file)
|
13
|
+
File.new(fixture_path + '/' + file)
|
14
|
+
end
|
15
|
+
|
16
|
+
YOUR_API_KEY = "Fmjtd%7Cluur2g61nl%2Cbl%3Do5-9az25f"
|
17
|
+
|
18
|
+
def stub_get_geocode_with(fixture)
|
19
|
+
stub_request(:get, "http://open.mapquestapi.com/geocoding/v1/address?key=#{CGI.unescape(YOUR_API_KEY)}&location=2710%20Avenida%208%20de%20Octubre,%20Montevideo,%20Uruguay&maxResults=2").to_return(:status => 200, :body => fixture(fixture))
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mq_reader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Santiago Piria
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-02-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.13.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.13.1
|
27
|
+
description: This is a wrapper for mapquest's geocoding api.
|
28
|
+
email:
|
29
|
+
- santiago.piria@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- Rakefile
|
35
|
+
- lib/mq_reader.rb
|
36
|
+
- lib/mq_reader/mq_reader.rb
|
37
|
+
- lib/mq_reader/version.rb
|
38
|
+
- mq_reader.gemspec
|
39
|
+
- spec/fixtures/address_found.json
|
40
|
+
- spec/fixtures/address_not_found.json
|
41
|
+
- spec/mq_reader/mq_reader_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
homepage: http://rubylearning.org/
|
44
|
+
licenses:
|
45
|
+
- MIT
|
46
|
+
metadata: {}
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.2.2
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: Mapquest api wrapper
|
67
|
+
test_files:
|
68
|
+
- spec/fixtures/address_found.json
|
69
|
+
- spec/fixtures/address_not_found.json
|
70
|
+
- spec/mq_reader/mq_reader_spec.rb
|
71
|
+
- spec/spec_helper.rb
|