human_attributes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +7 -0
  6. data/Gemfile +14 -0
  7. data/Gemfile.lock +187 -0
  8. data/Guardfile +15 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +402 -0
  11. data/Rakefile +10 -0
  12. data/human_attributes.gemspec +30 -0
  13. data/lib/human_attributes/active_record_extension.rb +53 -0
  14. data/lib/human_attributes/config.rb +92 -0
  15. data/lib/human_attributes/engine.rb +24 -0
  16. data/lib/human_attributes/errors.rb +46 -0
  17. data/lib/human_attributes/formatters/base.rb +27 -0
  18. data/lib/human_attributes/formatters/boolean.rb +10 -0
  19. data/lib/human_attributes/formatters/custom.rb +17 -0
  20. data/lib/human_attributes/formatters/date.rb +9 -0
  21. data/lib/human_attributes/formatters/enumerize.rb +11 -0
  22. data/lib/human_attributes/formatters/numeric.rb +11 -0
  23. data/lib/human_attributes/formatters_builder.rb +44 -0
  24. data/lib/human_attributes/method_builder.rb +20 -0
  25. data/lib/human_attributes/version.rb +3 -0
  26. data/lib/human_attributes.rb +26 -0
  27. data/lib/tasks/human_attributes_tasks.rake +32 -0
  28. data/spec/dummy/README.rdoc +28 -0
  29. data/spec/dummy/Rakefile +6 -0
  30. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  31. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  32. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  33. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  34. data/spec/dummy/app/models/purchase.rb +28 -0
  35. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  36. data/spec/dummy/bin/bundle +3 -0
  37. data/spec/dummy/bin/rails +4 -0
  38. data/spec/dummy/bin/rake +4 -0
  39. data/spec/dummy/bin/setup +29 -0
  40. data/spec/dummy/config/application.rb +32 -0
  41. data/spec/dummy/config/boot.rb +5 -0
  42. data/spec/dummy/config/database.yml +25 -0
  43. data/spec/dummy/config/environment.rb +5 -0
  44. data/spec/dummy/config/environments/development.rb +41 -0
  45. data/spec/dummy/config/environments/production.rb +79 -0
  46. data/spec/dummy/config/environments/test.rb +42 -0
  47. data/spec/dummy/config/initializers/assets.rb +11 -0
  48. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  50. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  51. data/spec/dummy/config/initializers/inflections.rb +16 -0
  52. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  53. data/spec/dummy/config/initializers/session_store.rb +3 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/en.yml +25 -0
  56. data/spec/dummy/config/routes.rb +56 -0
  57. data/spec/dummy/config/secrets.yml +22 -0
  58. data/spec/dummy/config.ru +4 -0
  59. data/spec/dummy/db/development.sqlite3 +0 -0
  60. data/spec/dummy/db/migrate/20161113032308_create_purchases.rb +15 -0
  61. data/spec/dummy/db/schema.rb +28 -0
  62. data/spec/dummy/db/test.sqlite3 +0 -0
  63. data/spec/dummy/log/development.log +16 -0
  64. data/spec/dummy/log/test.log +25913 -0
  65. data/spec/dummy/public/404.html +67 -0
  66. data/spec/dummy/public/422.html +67 -0
  67. data/spec/dummy/public/500.html +66 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/dummy/spec/assets/image.png +0 -0
  70. data/spec/dummy/spec/assets/video.mp4 +0 -0
  71. data/spec/dummy/spec/factories/purchases.rb +26 -0
  72. data/spec/dummy/spec/lib/active_record_extension_spec.rb +402 -0
  73. data/spec/dummy/spec/support/test_helpers.rb +5 -0
  74. data/spec/rails_helper.rb +28 -0
  75. data/spec/spec_helper.rb +9 -0
  76. metadata +293 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
Binary file
Binary file
@@ -0,0 +1,26 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: purchases
4
+ #
5
+ # id :integer not null, primary key
6
+ # paid :boolean
7
+ # commission :decimal(, )
8
+ # quantity :integer
9
+ # state :string
10
+ # expired_at :datetime
11
+ # amount :decimal(, )
12
+ # description :text
13
+ # created_at :datetime not null
14
+ # updated_at :datetime not null
15
+ #
16
+
17
+ FactoryGirl.define do
18
+ factory :purchase do
19
+ paid true
20
+ commission 1000.99
21
+ quantity 1
22
+ expired_at "1984-04-06 09:00"
23
+ amount 2_000_000.95
24
+ description "Just a text"
25
+ end
26
+ end
@@ -0,0 +1,402 @@
1
+ require "rails_helper"
2
+
3
+ RSpec.describe "ActiveRecordExtension" do
4
+ after do
5
+ class Purchase < ActiveRecord::Base
6
+ humanizers.each do |method|
7
+ remove_method method
8
+ end
9
+ end
10
+ end
11
+
12
+ describe "#humanize" do
13
+ let(:purchase) { build(:purchase) }
14
+
15
+ it "raises error passing invalid options" do
16
+ expect do
17
+ class Purchase < ActiveRecord::Base
18
+ humanize :amount, "invalid"
19
+ end
20
+ end.to raise_error(HumanAttributes::Error::InvalidHumanizeConfig)
21
+ end
22
+
23
+ it "raises error passing multiple types" do
24
+ expect do
25
+ class Purchase < ActiveRecord::Base
26
+ humanize :amount, invalid: true
27
+ end
28
+ end.to raise_error(HumanAttributes::Error::InvalidType)
29
+ end
30
+
31
+ it "raises error passing no type" do
32
+ expect do
33
+ class Purchase < ActiveRecord::Base
34
+ humanize :amount, {}
35
+ end
36
+ end.to raise_error(HumanAttributes::Error::RequiredAttributeType)
37
+ end
38
+
39
+ it "raises error trying to pass invalid options" do
40
+ expect do
41
+ class Purchase < ActiveRecord::Base
42
+ humanize :amount, currency: "invalid"
43
+ end
44
+ end.to raise_error(HumanAttributes::Error::InvalidAttributeOptions)
45
+ end
46
+
47
+ context "with default value" do
48
+ before do
49
+ class Purchase < ActiveRecord::Base
50
+ humanize :amount, currency: { default: 666 }
51
+ end
52
+
53
+ purchase.amount = nil
54
+ end
55
+
56
+ it { expect(purchase.human_amount).to eq("$666.00") }
57
+ end
58
+
59
+ context "with default value" do
60
+ before do
61
+ class Purchase < ActiveRecord::Base
62
+ humanize :amount, percentage: { suffix: true }, currency: { suffix: true }
63
+ end
64
+
65
+ purchase.amount = 20
66
+ end
67
+
68
+ it { expect(purchase.amount_to_currency).to eq("$20.00") }
69
+ it { expect(purchase.amount_to_percentage).to eq("20.000%") }
70
+ end
71
+
72
+ context "with suffix" do
73
+ before { purchase.amount = 20_000_000.5 }
74
+
75
+ context "with default suffix" do
76
+ before do
77
+ class Purchase < ActiveRecord::Base
78
+ humanize :amount, currency: { suffix: true }
79
+ end
80
+ end
81
+
82
+ it { expect(purchase.amount_to_currency).to eq("$20,000,000.50") }
83
+ end
84
+
85
+ context "with custom suffix" do
86
+ before do
87
+ class Purchase < ActiveRecord::Base
88
+ humanize :amount, currency: { suffix: "to_cur" }
89
+ end
90
+ end
91
+
92
+ it { expect(purchase.amount_to_cur).to eq("$20,000,000.50") }
93
+ end
94
+ end
95
+
96
+ context "with currency type" do
97
+ before do
98
+ purchase.amount = 20_000_000.5
99
+ purchase.commission = 5.3
100
+ end
101
+
102
+ context "with no options" do
103
+ before do
104
+ class Purchase < ActiveRecord::Base
105
+ humanize :amount, currency: true
106
+ end
107
+ end
108
+
109
+ it { expect(purchase.human_amount).to eq("$20,000,000.50") }
110
+ end
111
+
112
+ context "with valid options" do
113
+ before do
114
+ class Purchase < ActiveRecord::Base
115
+ humanize :amount, currency: { unit: "R$", separator: ",", delimiter: " " }
116
+ end
117
+ end
118
+
119
+ it { expect(purchase.human_amount).to eq("R$20 000 000,50") }
120
+ end
121
+
122
+ context "with multiple attributes" do
123
+ before do
124
+ class Purchase < ActiveRecord::Base
125
+ humanize :amount, :commission, currency: true
126
+ end
127
+ end
128
+
129
+ it { expect(purchase.human_amount).to eq("$20,000,000.50") }
130
+ it { expect(purchase.human_commission).to eq("$5.30") }
131
+ end
132
+
133
+ context "with calculated attributes (instance methods)" do
134
+ before do
135
+ class Purchase < ActiveRecord::Base
136
+ humanize :commission_amount, currency: true
137
+
138
+ def commission_amount
139
+ amount * commission / 100.0
140
+ end
141
+ end
142
+ end
143
+
144
+ it { expect(purchase.human_commission_amount).to eq("$1,060,000.03") }
145
+ end
146
+ end
147
+
148
+ context "with other numeric types" do
149
+ before { purchase.quantity = 20_000_000 }
150
+
151
+ context "with number type" do
152
+ before do
153
+ class Purchase < ActiveRecord::Base
154
+ humanize :quantity, number: true
155
+ end
156
+ end
157
+
158
+ it { expect(purchase.human_quantity).to eq("20 Million") }
159
+ end
160
+
161
+ context "with size type" do
162
+ before do
163
+ class Purchase < ActiveRecord::Base
164
+ humanize :quantity, size: true
165
+ end
166
+ end
167
+
168
+ it { expect(purchase.human_quantity).to eq("19.1 MB") }
169
+ end
170
+
171
+ context "with percentage type" do
172
+ before do
173
+ class Purchase < ActiveRecord::Base
174
+ humanize :quantity, percentage: true
175
+ end
176
+ end
177
+
178
+ after { purchase.instance_eval('undef :human_quantity') }
179
+
180
+ it { expect(purchase.human_quantity).to eq("20000000.000%") }
181
+ end
182
+
183
+ context "with phone type" do
184
+ before do
185
+ class Purchase < ActiveRecord::Base
186
+ humanize :quantity, phone: true
187
+ end
188
+ end
189
+
190
+ it { expect(purchase.human_quantity).to eq("2-000-0000") }
191
+ end
192
+
193
+ context "with delimiter type" do
194
+ before do
195
+ class Purchase < ActiveRecord::Base
196
+ humanize :quantity, delimiter: true
197
+ end
198
+ end
199
+
200
+ it { expect(purchase.human_quantity).to eq("20,000,000") }
201
+ end
202
+
203
+ context "with precision type" do
204
+ before do
205
+ class Purchase < ActiveRecord::Base
206
+ humanize :quantity, precision: true
207
+ end
208
+ end
209
+
210
+ it { expect(purchase.human_quantity).to eq("20000000.000") }
211
+ end
212
+ end
213
+
214
+ context "with boolean format" do
215
+ before { purchase.paid = true }
216
+
217
+ context "passing true value" do
218
+ before do
219
+ class Purchase < ActiveRecord::Base
220
+ humanize :paid, boolean: true
221
+ end
222
+ end
223
+
224
+ it { expect(purchase.human_paid).to eq("Yes") }
225
+ end
226
+
227
+ context "passing false value" do
228
+ before do
229
+ purchase.paid = false
230
+
231
+ class Purchase < ActiveRecord::Base
232
+ humanize :paid, boolean: true
233
+ end
234
+ end
235
+
236
+ it { expect(purchase.human_paid).to eq("No") }
237
+ end
238
+ end
239
+
240
+ context "with custom formatter" do
241
+ it "raises error with missing formatter option" do
242
+ expect do
243
+ class Purchase < ActiveRecord::Base
244
+ humanize :id, custom: true
245
+ end
246
+ end.to raise_error(HumanAttributes::Error::MissingFormatterOption)
247
+ end
248
+
249
+ context "passing valid formatter" do
250
+ before do
251
+ purchase.id = 1
252
+ purchase.paid = true
253
+
254
+ class Purchase < ActiveRecord::Base
255
+ humanize :id, custom: { formatter: ->(purchase, value) { "#{value}:#{purchase.paid}" } }
256
+ end
257
+ end
258
+
259
+ it { expect(purchase.human_id).to eq("1:true") }
260
+ end
261
+ end
262
+
263
+ context "with Enumerize attribute" do
264
+ context "passing valid value" do
265
+ before do
266
+ class Purchase < ActiveRecord::Base
267
+ extend Enumerize
268
+ enumerize :state, in: %i{canceled finished}
269
+ humanize :state, enumerize: true
270
+ end
271
+
272
+ purchase.state = :finished
273
+ end
274
+
275
+ it { expect(purchase.human_state).to eq("Finished") }
276
+ end
277
+
278
+ context "passing no enum value" do
279
+ before do
280
+ class Purchase < ActiveRecord::Base
281
+ extend Enumerize
282
+ humanize :quantity, enumerize: true
283
+ end
284
+ end
285
+
286
+ it do
287
+ expect { purchase.human_quantity }.to(
288
+ raise_error(HumanAttributes::Error::NotEnumerizeAttribute)
289
+ )
290
+ end
291
+ end
292
+ end
293
+
294
+ context "with date format" do
295
+ before { purchase.expired_at = "04/06/1984 09:20:00" }
296
+
297
+ context "passing custom format" do
298
+ before do
299
+ class Purchase < ActiveRecord::Base
300
+ humanize :expired_at, date: { format: "%Y" }
301
+ end
302
+ end
303
+
304
+ it { expect(purchase.human_expired_at).to eq("1984") }
305
+ end
306
+
307
+ context "without options" do
308
+ before do
309
+ class Purchase < ActiveRecord::Base
310
+ humanize :expired_at, date: true
311
+ end
312
+ end
313
+
314
+ it { expect(purchase.human_expired_at).to eq("Mon, 04 Jun 1984 09:20:00 +0000") }
315
+ end
316
+
317
+ context "with short format" do
318
+ before do
319
+ class Purchase < ActiveRecord::Base
320
+ humanize :expired_at, date: { format: :short }
321
+ end
322
+ end
323
+
324
+ it { expect(purchase.human_expired_at).to eq("04 Jun 09:20") }
325
+ end
326
+
327
+ context "with long format" do
328
+ before do
329
+ class Purchase < ActiveRecord::Base
330
+ humanize :expired_at, date: { format: :long }
331
+ end
332
+ end
333
+
334
+ it { expect(purchase.human_expired_at).to eq("June 04, 1984 09:20") }
335
+ end
336
+ end
337
+ end
338
+
339
+ describe "#humanize_attributes" do
340
+ let(:purchase) { create(:purchase) }
341
+
342
+ context "without options" do
343
+ before do
344
+ class Purchase < ActiveRecord::Base
345
+ humanize_attributes
346
+ end
347
+ end
348
+
349
+ it { expect(purchase.human_id).to eq("Purchase: ##{purchase.id}") }
350
+ it { expect(purchase.human_paid).to eq("Yes") }
351
+ it { expect(purchase.human_quantity).to eq("1") }
352
+ it { expect(purchase.human_commission).to eq("1 Thousand") }
353
+ it { expect(purchase.human_amount).to eq("2 Million") }
354
+ it { expect(purchase.human_expired_at).to eq("Fri, 06 Apr 1984 09:00:00 +0000") }
355
+ it { expect(purchase.expired_at_to_short_date).to eq("06 Apr 09:00") }
356
+ it { expect(purchase).to respond_to(:human_created_at) }
357
+ it { expect(purchase).to respond_to(:created_at_to_short_date) }
358
+ it { expect(purchase).to respond_to(:human_updated_at) }
359
+ it { expect(purchase).to respond_to(:updated_at_to_short_date) }
360
+ end
361
+
362
+ context "with only option" do
363
+ before do
364
+ class Purchase < ActiveRecord::Base
365
+ humanize_attributes only: [:id, :paid, :amount]
366
+ end
367
+ end
368
+
369
+ it { expect(purchase.human_id).to eq("Purchase: ##{purchase.id}") }
370
+ it { expect(purchase.human_paid).to eq("Yes") }
371
+ it { expect(purchase).not_to respond_to(:human_quantity) }
372
+ it { expect(purchase).not_to respond_to(:human_commission) }
373
+ it { expect(purchase.human_amount).to eq("2 Million") }
374
+ it { expect(purchase).not_to respond_to(:human_expired_at) }
375
+ it { expect(purchase).not_to respond_to(:expired_at_to_short_date) }
376
+ it { expect(purchase).not_to respond_to(:human_created_at) }
377
+ it { expect(purchase).not_to respond_to(:created_at_to_short_date) }
378
+ it { expect(purchase).not_to respond_to(:human_updated_at) }
379
+ it { expect(purchase).not_to respond_to(:updated_at_to_short_date) }
380
+ end
381
+
382
+ context "with except option" do
383
+ before do
384
+ class Purchase < ActiveRecord::Base
385
+ humanize_attributes except: [:id, :paid, :amount]
386
+ end
387
+ end
388
+
389
+ it { expect(purchase).not_to respond_to(:human_id) }
390
+ it { expect(purchase).not_to respond_to(:human_paid) }
391
+ it { expect(purchase.human_quantity).to eq("1") }
392
+ it { expect(purchase.human_commission).to eq("1 Thousand") }
393
+ it { expect(purchase).not_to respond_to(:human_amount) }
394
+ it { expect(purchase.human_expired_at).to eq("Fri, 06 Apr 1984 09:00:00 +0000") }
395
+ it { expect(purchase.expired_at_to_short_date).to eq("06 Apr 09:00") }
396
+ it { expect(purchase).to respond_to(:human_created_at) }
397
+ it { expect(purchase).to respond_to(:created_at_to_short_date) }
398
+ it { expect(purchase).to respond_to(:human_updated_at) }
399
+ it { expect(purchase).to respond_to(:updated_at_to_short_date) }
400
+ end
401
+ end
402
+ end
@@ -0,0 +1,5 @@
1
+ module TestHelpers
2
+ def helper_example
3
+ puts "Add your custom helpers here: #{File.dirname(__FILE__)}"
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ ENV["RAILS_ENV"] ||= "test"
2
+ require File.expand_path("../../spec/dummy/config/environment", __FILE__)
3
+ abort("The Rails environment is running in production mode!") if Rails.env.production?
4
+ require "pry"
5
+ require "spec_helper"
6
+ require "rspec/rails"
7
+ require "factory_girl_rails"
8
+
9
+ ActiveRecord::Migration.maintain_test_schema!
10
+
11
+ Dir[::Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
12
+
13
+ RSpec.configure do |config|
14
+ config.fixture_path = "#{::Rails.root}/spec/assets"
15
+ config.use_transactional_fixtures = true
16
+ config.infer_spec_type_from_file_location!
17
+ config.filter_rails_from_backtrace!
18
+
19
+ config.filter_run :focus
20
+ config.run_all_when_everything_filtered = true
21
+
22
+ FactoryGirl.definition_file_paths = ["#{::Rails.root}/spec/factories"]
23
+ FactoryGirl.find_definitions
24
+
25
+ config.include FactoryGirl::Syntax::Methods
26
+ config.include ActionDispatch::TestProcess
27
+ config.include TestHelpers
28
+ end
@@ -0,0 +1,9 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |expectations|
3
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
4
+ end
5
+
6
+ config.mock_with :rspec do |mocks|
7
+ mocks.verify_partial_doubles = true
8
+ end
9
+ end