doattend 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4002d28ae6dbafae05ef592835e2c429b300c74c
4
- data.tar.gz: f1ee4c95a35f60544f5f17ffce1062573042ae2b
3
+ metadata.gz: 4c8f939f5c50767f5eb9bafad844ad915438a4fc
4
+ data.tar.gz: 921f1443be878ba218ace7f2971556d7988196db
5
5
  SHA512:
6
- metadata.gz: 7e9fd3f9fc03f9d2f498b3c3b83c2e40fa5415dc486e9c907c2046f3d1c61d35c08e334a731d3153f53a6828cc7a3af7795acef92f151b71cf76c726c6be6c43
7
- data.tar.gz: d843d0e2bc51af171d8a1200cc3b51b023c0cfadf195503c1a9e62d3ab43c6f97407ce80f0e578bbda15b2bb42b09f56c1af590bb15d005a8b77b1f030fc62a2
6
+ metadata.gz: f5a45681208778c0e4b2c4b448fb119ee6a1e4edb35eca86935f4131c66f9af104437d5a0032647c31f4a46e71f19aa8b12ec36268d94748dc2c69ccab42b15d
7
+ data.tar.gz: cf5f684471e6b01993d14cf598a9cb5ee5215a9b266637900ee8aef943ee25604b056409a6996de71f61d4b83330e2647e33dd21ce111b2e4feba96277e8b842
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/doattend.png)](http://badge.fury.io/rb/doattend)
4
4
  [![Code Climate](https://codeclimate.com/github/swaroopsm/doattend.png)](https://codeclimate.com/github/swaroopsm/doattend)
5
+ [![Dependency Status](https://gemnasium.com/swaroopsm/doattend.png)](https://gemnasium.com/swaroopsm/doattend)
6
+ [![Build Status](https://travis-ci.org/swaroopsm/doattend.png?branch=master)](https://travis-ci.org/swaroopsm/doattend)
7
+ [![Stories in Ready](https://badge.waffle.io/swaroopsm/doattend.png?label=ready)](https://waffle.io/swaroopsm/doattend)
5
8
 
6
9
  Rails generator and functions to communicate the DoAttend API. You need to have a DoAttend API key to communicate the DoAttend API. If you do not have one yet, you can contact DoAttend to get an API key.
7
10
 
@@ -21,12 +24,12 @@ Or install it yourself as:
21
24
 
22
25
  ## Usage
23
26
 
24
- Doattend provides a rails generator that gets you started quikly.
27
+ Doattend provides a rails generator that gets you started quickly.
25
28
  Run the following generator to generate config/doattend.yml
26
29
 
27
30
  $ rails g doattend:install -e YOUR_DOATTEND_EVENT_ID -k YOUR_DOATTEND_API_KEY
28
31
 
29
- If you are not using Rails you can use require to include it:
32
+ #####If you are not using Rails you can use require to include it:
30
33
  $ require "doattend"
31
34
 
32
35
  ## Getting Started
@@ -35,14 +38,16 @@ If you are not using Rails you can use require to include it:
35
38
 
36
39
  Non-Rails Way:
37
40
  doattend = Doattend::Base.new('YOUR_DOATTEND_EVENT_ID', 'YOUR_DOATTEND_API_KEY')
41
+
42
+ Fetch all data:
43
+ doattend.fetch
44
+
38
45
 
39
46
 
40
47
  ## Methods
41
- ### Tickets
42
- #### Fetch all data from DoAttend
43
- doattend.fetch
44
48
 
45
- #### Get total tickets
49
+ ### 1. Ticket
50
+ #### Get total number of tickets
46
51
  doattend.aggregate
47
52
 
48
53
  #### Get ticket names/types used in an event
@@ -54,12 +59,28 @@ If you are not using Rails you can use require to include it:
54
59
  Eg.:
55
60
  doattend.ticket.aggregate(doattend.ticket.names.first)
56
61
 
57
- ### Participants
58
- #### Pluck a field from all all participants
62
+ ### 2. Participants
63
+
64
+ #### Find a participant by ticket number
65
+ doattend.participant.find('TICKET_NUMBER')
66
+
67
+ #### Ascertain whether a key == value
68
+ doattend.participant.ascertain('KEY', 'VALUE')
69
+
70
+ Eg.:
71
+ doattend.participant.ascertain('Gender', 'Male')
72
+
73
+ #### Return participant objects registered on a specfied date
74
+ doattend.participant.registered.on(DATE_OBJECT)
75
+
76
+ Eg.:
77
+ doattend.participant.registered.on(Date.new(2013,5,8))
78
+
79
+ #### Pluck a field from all participants
59
80
  doattend.participant.pluck('FIELD_NAME')
60
81
 
61
82
  Eg.:
62
- doattend.participant.plcuk('Gender')
83
+ doattend.participant.pluck('Gender')
63
84
 
64
85
  ## Contributing
65
86
 
data/lib/doattend/base.rb CHANGED
@@ -8,7 +8,7 @@ module Doattend
8
8
 
9
9
  class Base
10
10
 
11
- attr_accessor :event, :key, :result
11
+ attr_accessor :event, :key, :result, :url
12
12
 
13
13
  def initialize(e=nil, k=nil)
14
14
  if defined? Rails
@@ -19,16 +19,15 @@ module Doattend
19
19
  self.event = e
20
20
  self.key = k
21
21
  end
22
-
22
+ self.url = "http://doattend.com/api/events/#{self.event}/participants_list.json?api_key=#{self.key}"
23
23
  end
24
24
 
25
25
  # Request DoAttend and fetch results.
26
26
  def fetch
27
- url = "http://doattend.com/api/events/#{self.event}/participants_list.json?api_key=#{self.key}"
28
27
  begin
29
28
  self.result = JSON.parse(RestClient.get(url))
30
29
  rescue Exception => e
31
- e
30
+ raise e
32
31
  end
33
32
  end
34
33
 
@@ -10,7 +10,7 @@ module Doattend
10
10
  self.general_info = ['Ticket_Number', 'Email', 'Date', 'Name']
11
11
  end
12
12
 
13
- # Pluck a particular field from participants
13
+ # Pluck a particular field from participants.
14
14
  def pluck(field)
15
15
  if self.general_info.include? field
16
16
  self.result.map{ |p| p[field] }
@@ -18,6 +18,30 @@ module Doattend
18
18
  self.result.map{ |p| p['participant_information'].select{ |a| a['desc'] == field } }.flatten.map{ |x| x['info'] }
19
19
  end
20
20
  end
21
+
22
+ # Default Participant Finder. Returns a participant having the specified ticket number.
23
+ def find(ticket)
24
+ self.result.select{ |p| p['Ticket_Number'] == ticket }.first
25
+ end
26
+
27
+ # Count occurences of key/value.
28
+ def ascertain(k, v)
29
+ if self.general_info.include? k
30
+ self.result.count{ |p| p[k] == v.downcase }
31
+ else
32
+ self.result.map{ |p| p['participant_information'].select{ |i| i['desc'].strip.downcase == k.split('_').join(' ').downcase and i['info'].strip.downcase == v.downcase } }.flatten.size
33
+ end
34
+ end
35
+
36
+ # Return participants who have registered on a particular date.
37
+ def registered
38
+ self
39
+ end
40
+
41
+ def on(date)
42
+ self.result.select{ |p| Date.iso8601(p['Date']).strftime == date.strftime }
43
+ end
44
+
21
45
 
22
46
  end
23
47
 
@@ -1,3 +1,3 @@
1
1
  module Doattend
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/spec/base_spec.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+ require "doattend/base"
3
+
4
+ describe Doattend::Base do
5
+
6
+ before(:each) do
7
+ @doattend = Doattend::Base.new('EVENT_ID', 'API_KEY')
8
+ sample_response = File.new(File.expand_path('../example.json', __FILE__))
9
+ stub_request(:get, @doattend.url).to_return(:body => sample_response)
10
+ @doattend.fetch
11
+ end
12
+
13
+ it "should be an instance of Ticket" do
14
+ @doattend.ticket.should be_instance_of Doattend::Ticket
15
+ end
16
+
17
+ it "should be an instance of Participant" do
18
+ @doattend.participant.should be_instance_of Doattend::Participant
19
+ end
20
+
21
+ it "should return total number of registrations" do
22
+ @doattend.aggregate.should eq 11
23
+ end
24
+
25
+ end
data/spec/example.json ADDED
@@ -0,0 +1,323 @@
1
+ {
2
+ "participants": [
3
+ {
4
+ "Date": "2013-05-08T05:11:08Z",
5
+ "Email": "abc@example.org",
6
+ "Name": null,
7
+ "Ticket_Name": "Test Registration",
8
+ "Ticket_Number": "326817",
9
+ "participant_information": [
10
+ {
11
+ "desc": "First Name",
12
+ "info": "Manic"
13
+ },
14
+ {
15
+ "desc": "Gender",
16
+ "info": "Other"
17
+ },
18
+ {
19
+ "desc": "Last Name",
20
+ "info": "Raman"
21
+ },
22
+ {
23
+ "desc": "Date of Birth",
24
+ "info": "May-15-1996"
25
+ },
26
+ {
27
+ "desc": "Nationality",
28
+ "info": "Albania"
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "Date": "2013-05-02T18:33:36Z",
34
+ "Email": "wolverine@example.org",
35
+ "Name": null,
36
+ "Ticket_Name": "Test Registration",
37
+ "Ticket_Number": "325434",
38
+ "participant_information": [
39
+ {
40
+ "desc": "First Name",
41
+ "info": "Logan"
42
+ },
43
+ {
44
+ "desc": "Gender",
45
+ "info": "Male"
46
+ },
47
+ {
48
+ "desc": "Last Name",
49
+ "info": "Torsekar"
50
+ },
51
+ {
52
+ "desc": "Date of Birth",
53
+ "info": "May-06-1975"
54
+ },
55
+ {
56
+ "desc": "Nationality",
57
+ "info": "empty"
58
+ }
59
+ ]
60
+ },
61
+ {
62
+ "Date": "2013-04-30T07:18:30Z",
63
+ "Email": "batman@example.org",
64
+ "Name": null,
65
+ "Ticket_Name": "Test Registration",
66
+ "Ticket_Number": "324549",
67
+ "participant_information": [
68
+ {
69
+ "desc": "First Name",
70
+ "info": "Bruce"
71
+ },
72
+ {
73
+ "desc": "Gender",
74
+ "info": "Male"
75
+ },
76
+ {
77
+ "desc": "Last Name",
78
+ "info": "Wayne"
79
+ },
80
+ {
81
+ "desc": "Date of Birth",
82
+ "info": "Apr-28-1982"
83
+ },
84
+ {
85
+ "desc": "Nationality",
86
+ "info": "empty"
87
+ }
88
+ ]
89
+ },
90
+ {
91
+ "Date": "2013-04-30T05:15:48Z",
92
+ "Email": "thor@example.org",
93
+ "Name": null,
94
+ "Ticket_Name": "Test Registration",
95
+ "Ticket_Number": "324521",
96
+ "participant_information": [
97
+ {
98
+ "desc": "thor",
99
+ "info": "Test"
100
+ },
101
+ {
102
+ "desc": "Gender",
103
+ "info": "Male"
104
+ },
105
+ {
106
+ "desc": "Last Name",
107
+ "info": "Thunder"
108
+ },
109
+ {
110
+ "desc": "Date of Birth",
111
+ "info": "Sep-04-1755"
112
+ },
113
+ {
114
+ "desc": "Nationality",
115
+ "info": "Asgard"
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "Date": "2013-04-26T10:16:10Z",
121
+ "Email": "van@example.org",
122
+ "Name": null,
123
+ "Ticket_Name": "Test Registration",
124
+ "Ticket_Number": "323367",
125
+ "participant_information": [
126
+ {
127
+ "desc": "First Name",
128
+ "info": "Van"
129
+ },
130
+ {
131
+ "desc": "Gender",
132
+ "info": "Male"
133
+ },
134
+ {
135
+ "desc": "Last Name",
136
+ "info": "Helsing"
137
+ },
138
+ {
139
+ "desc": "Date of Birth",
140
+ "info": "Jun-26-1986"
141
+ },
142
+ {
143
+ "desc": "Nationality",
144
+ "info": "empty"
145
+ }
146
+ ]
147
+ },
148
+ {
149
+ "Date": "2013-04-22T17:23:56Z",
150
+ "Email": "jonh.doe@example.org",
151
+ "Name": null,
152
+ "Ticket_Name": "Test Registration",
153
+ "Ticket_Number": "322474",
154
+ "participant_information": [
155
+ {
156
+ "desc": "First Name",
157
+ "info": "John"
158
+ },
159
+ {
160
+ "desc": "Gender",
161
+ "info": "Male"
162
+ },
163
+ {
164
+ "desc": "Last Name",
165
+ "info": "Doe"
166
+ },
167
+ {
168
+ "desc": "Date of Birth",
169
+ "info": "Apr-28-1913"
170
+ },
171
+ {
172
+ "desc": "Nationality",
173
+ "info": "empty"
174
+ }
175
+ ]
176
+ },
177
+ {
178
+ "Date": "2013-04-20T12:24:13Z",
179
+ "Email": "jack@example.org",
180
+ "Name": null,
181
+ "Ticket_Name": "Test Registration",
182
+ "Ticket_Number": "322085",
183
+ "participant_information": [
184
+ {
185
+ "desc": "First Name",
186
+ "info": "Jack"
187
+ },
188
+ {
189
+ "desc": "Gender",
190
+ "info": "Male"
191
+ },
192
+ {
193
+ "desc": "Last Name",
194
+ "info": "Fernandez"
195
+ },
196
+ {
197
+ "desc": "Date of Birth",
198
+ "info": "Oct-12-1981"
199
+ },
200
+ {
201
+ "desc": "Nationality",
202
+ "info": "empty"
203
+ }
204
+ ]
205
+ },
206
+ {
207
+ "Date": "2013-04-17T04:46:26Z",
208
+ "Email": "carter@example.org",
209
+ "Name": null,
210
+ "Ticket_Name": "Test Registration",
211
+ "Ticket_Number": "320774",
212
+ "participant_information": [
213
+ {
214
+ "desc": "First Name",
215
+ "info": "Paul"
216
+ },
217
+ {
218
+ "desc": "Gender",
219
+ "info": "Carter"
220
+ },
221
+ {
222
+ "desc": "Last Name",
223
+ "info": "J"
224
+ },
225
+ {
226
+ "desc": "Date of Birth",
227
+ "info": "Apr-17-2013"
228
+ },
229
+ {
230
+ "desc": "Nationality",
231
+ "info": "empty"
232
+ }
233
+ ]
234
+ },
235
+ {
236
+ "Date": "2013-04-12T04:27:33Z",
237
+ "Email": "fizz@example.org",
238
+ "Name": null,
239
+ "Ticket_Name": "Test Registration for Copy of test",
240
+ "Ticket_Number": "319951",
241
+ "participant_information": [
242
+ {
243
+ "desc": "First Name",
244
+ "info": "Fizz"
245
+ },
246
+ {
247
+ "desc": "Gender",
248
+ "info": "Male"
249
+ },
250
+ {
251
+ "desc": "Last Name",
252
+ "info": "Buzz"
253
+ },
254
+ {
255
+ "desc": "Date of Birth",
256
+ "info": "Oct-18-1984"
257
+ },
258
+ {
259
+ "desc": "Nationality",
260
+ "info": "empty"
261
+ }
262
+ ]
263
+ },
264
+ {
265
+ "Date": "2013-04-11T05:37:21Z",
266
+ "Email": "fred@example.com",
267
+ "Name": null,
268
+ "Ticket_Name": "Test Registration for Copy of test",
269
+ "Ticket_Number": "319165",
270
+ "participant_information": [
271
+ {
272
+ "desc": "First Name",
273
+ "info": "Derek"
274
+ },
275
+ {
276
+ "desc": "Gender",
277
+ "info": "empty"
278
+ },
279
+ {
280
+ "desc": "Last Name",
281
+ "info": "Fred"
282
+ },
283
+ {
284
+ "desc": "Date of Birth",
285
+ "info": "Apr-28-1982"
286
+ },
287
+ {
288
+ "desc": "Nationality",
289
+ "info": "Indian"
290
+ }
291
+ ]
292
+ },
293
+ {
294
+ "Date": "2013-04-09T06:08:59Z",
295
+ "Email": "mark@example.org",
296
+ "Name": null,
297
+ "Ticket_Name": "Test Registration for Copy of test",
298
+ "Ticket_Number": "318800",
299
+ "participant_information": [
300
+ {
301
+ "desc": "First Name",
302
+ "info": "Mark"
303
+ },
304
+ {
305
+ "desc": "Gender",
306
+ "info": "male"
307
+ },
308
+ {
309
+ "desc": "Last Name",
310
+ "info": "Brandin"
311
+ },
312
+ {
313
+ "desc": "Date of Birth",
314
+ "info": "Apr-28-1982"
315
+ },
316
+ {
317
+ "desc": "Nationality",
318
+ "info": "empty"
319
+ }
320
+ ]
321
+ }
322
+ ]
323
+ }
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+ require "doattend/base"
3
+
4
+ describe Doattend::Participant do
5
+
6
+ before(:each) do
7
+ @doattend = Doattend::Base.new('EVENT_ID', 'API_KEY')
8
+ sample_response = File.new(File.expand_path('../example.json', __FILE__))
9
+ stub_request(:get, @doattend.url).to_return(:body => sample_response)
10
+ @doattend.fetch
11
+ end
12
+
13
+ it "should pluck all ticket numbers" do
14
+ @doattend.participant.pluck("Ticket_Number").should eq ["326817", "325434", "324549", "324521", "323367", "322474", "322085", "320774", "319951", "319165", "318800"]
15
+ end
16
+
17
+ it "should return a valid particpant hash of the specified ticket" do
18
+ @doattend.participant.find('326817').should be_kind_of Hash
19
+ end
20
+
21
+ it "should return nil for an invalid ticket number" do
22
+ @doattend.participant.find('316117').should be_nil
23
+ end
24
+
25
+ it "should return the number of occurrences who are male participants" do
26
+ @doattend.participant.ascertain('Gender', 'Male').should eq 8
27
+ end
28
+
29
+ it "should return the number of " do
30
+ @doattend.participant.ascertain('Nationality', 'Asgard').should eq 1
31
+ end
32
+
33
+ it "should return an array of participant objects for a given date" do
34
+ @doattend.participant.registered.on(Date.new(2013,5,8)).should be_kind_of Array
35
+ end
36
+
37
+ end
@@ -0,0 +1,20 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require "webmock/rspec"
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+ require "doattend/base"
3
+
4
+ describe Doattend::Ticket do
5
+
6
+ before(:each) do
7
+ @doattend = Doattend::Base.new('EVENT_ID', 'API_KEY')
8
+ sample_response = File.new(File.expand_path('../example.json', __FILE__))
9
+ stub_request(:get, @doattend.url).to_return(:body => sample_response)
10
+ @doattend.fetch
11
+ end
12
+
13
+ it "ticket names should be an array" do
14
+ @doattend.ticket.names.should be_kind_of Array
15
+ end
16
+
17
+ it "should return the first ticket name" do
18
+ @doattend.ticket.names.first.should eq "Test Registration"
19
+ end
20
+
21
+ it "should return number of registrations for a ticket type" do
22
+ @doattend.ticket.aggregate(@doattend.ticket.names.first).should eq 8
23
+ end
24
+
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doattend
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Swaroop SM
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-04 00:00:00.000000000 Z
11
+ date: 2013-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,18 +38,46 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rails
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
- - - ~>
73
+ - - '>='
46
74
  - !ruby/object:Gem::Version
47
75
  version: 3.2.13
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
- - - ~>
80
+ - - '>='
53
81
  - !ruby/object:Gem::Version
54
82
  version: 3.2.13
55
83
  - !ruby/object:Gem::Dependency
@@ -80,7 +108,7 @@ dependencies:
80
108
  - - '>='
81
109
  - !ruby/object:Gem::Version
82
110
  version: '0'
83
- description: Communicating with DoAttend API
111
+ description: Methods to parse data from DoAttend API
84
112
  email:
85
113
  - swaroop.striker@gmail.com
86
114
  executables: []
@@ -90,6 +118,11 @@ files:
90
118
  - README.md
91
119
  - Gemfile
92
120
  - Rakefile
121
+ - spec/example.json
122
+ - spec/ticket_spec.rb
123
+ - spec/participant_spec.rb
124
+ - spec/spec_helper.rb
125
+ - spec/base_spec.rb
93
126
  - lib/doattend/ticket.rb
94
127
  - lib/doattend/version.rb
95
128
  - lib/doattend/participant.rb
@@ -121,6 +154,11 @@ rubyforge_project:
121
154
  rubygems_version: 2.0.7
122
155
  signing_key:
123
156
  specification_version: 4
124
- summary: This provides a rails generator and functions to communicate with the DoAttend
125
- API.
126
- test_files: []
157
+ summary: This provides a rails generator and functions to communicate and parse data
158
+ from DoAttend API.
159
+ test_files:
160
+ - spec/example.json
161
+ - spec/ticket_spec.rb
162
+ - spec/participant_spec.rb
163
+ - spec/spec_helper.rb
164
+ - spec/base_spec.rb