stripe-rails 1.9.1 → 2.0.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +10 -6
- data/Changelog.md +26 -0
- data/Gemfile +4 -4
- data/README.md +19 -2
- data/gemfiles/{rails4.gemfile → rails51.gemfile} +6 -5
- data/gemfiles/rails52.gemfile +20 -0
- data/lib/generators/templates/products.rb +2 -2
- data/lib/stripe/billing_tier.rb +34 -0
- data/lib/stripe/callbacks.rb +3 -4
- data/lib/stripe/plans.rb +33 -5
- data/lib/stripe/products.rb +2 -0
- data/lib/stripe/rails.rb +1 -0
- data/lib/stripe/rails/version.rb +1 -1
- data/stripe-rails.gemspec +2 -2
- data/test/callbacks_spec.rb +15 -15
- data/test/coupon_builder_spec.rb +4 -4
- data/test/dummy/config/stripe/plans.rb +21 -0
- data/test/dummy_apis_controller_spec.rb +1 -1
- data/test/events_controller_spec.rb +5 -5
- data/test/javascript_helper_spec.rb +12 -12
- data/test/plan_builder_spec.rb +112 -36
- data/test/product_builder_spec.rb +11 -11
- data/test/stripe_initializers_spec.rb +23 -23
- data/test/support/application_system_test_case.rb +2 -7
- data/test/testing_spec.rb +8 -8
- metadata +13 -17
- data/app/controllers/stripe/pings_controller.rb +0 -10
- data/app/models/stripe/ping.rb +0 -9
- data/test/pings_controller_spec.rb +0 -18
- data/test/support/null_system_test_case.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b69dd28ba0f7e285499222f566f1a3d94792a3d928c07e6f820231758a1076f2
|
4
|
+
data.tar.gz: 20001b39f130cf45f32b4418acd4a7b25c2f855eb4c82150af7a0efdd1761b01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5ca715db15caf73a7261911590c31e8155bf65769ca5d28b3c2c548ddb76f5560ce2a56e45241daf8d614de0a4bfa2fd6c9b5f45d5909cdee8ef224cf7ae727
|
7
|
+
data.tar.gz: 5883ebce3e32917174404c92c9114e683de9e63bde4bb8c23c8a2d5bfe13ee8586a545bcc9a5c853289cf8be4812a14db0890eff795243f2aaef55a2ee548c4c
|
data/.github/workflows/ruby.yml
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
name: Ruby
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- master
|
4
10
|
|
5
11
|
jobs:
|
6
12
|
build:
|
@@ -8,9 +14,8 @@ jobs:
|
|
8
14
|
|
9
15
|
strategy:
|
10
16
|
matrix:
|
11
|
-
ruby: [2.
|
12
|
-
gemfile: [Gemfile, gemfiles/
|
13
|
-
|
17
|
+
ruby: [2.5.x, 2.6.x, 2.7.x]
|
18
|
+
gemfile: [Gemfile, gemfiles/rails51.gemfile, gemfiles/rails52.gemfile]
|
14
19
|
steps:
|
15
20
|
- uses: actions/checkout@v1
|
16
21
|
- name: Set up Ruby
|
@@ -28,9 +33,8 @@ jobs:
|
|
28
33
|
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
29
34
|
RUBY_VERSION: ${{ matrix.ruby }}
|
30
35
|
run: |
|
31
|
-
gem install bundler -v 1.17.3
|
32
36
|
bundle install --jobs 4 --retry 3
|
33
37
|
bundle exec rake
|
34
|
-
if [ `basename $BUNDLE_GEMFILE` == "Gemfile" ] && [ $RUBY_VERSION == "2.
|
38
|
+
if [ `basename $BUNDLE_GEMFILE` == "Gemfile" ] && [ $RUBY_VERSION == "2.7.x" ] && [ ! -z ${CC_TEST_REPORTER_ID} ] ;
|
35
39
|
then ./cc-test-reporter after-build --exit-code $? ;
|
36
40
|
fi
|
data/Changelog.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
## 2.0.0 (2020-09-18)
|
4
|
+
|
5
|
+
- Everything from on the 2.0.0.pre release
|
6
|
+
- includes changes from the 1.10.2 release
|
7
|
+
|
8
|
+
## 1.10.2 (2020-09-18)
|
9
|
+
|
10
|
+
- adds missing callback `invoice.paid`. Thanks @SyborgStudios.
|
11
|
+
|
12
|
+
## 2.0.0.pre (2020-05-29)
|
13
|
+
|
14
|
+
* [Breaking] Updated to work only with Rails >= 5.1
|
15
|
+
* [Breaking] It'll only be tested on Ruby 2.7, 2.6 and 2.5.
|
16
|
+
* [Breaking] Supports the Stripe gem => 3.15.0 (from 2 years ago)
|
17
|
+
* [Breaking] Removes Stripe::PingsController controller.
|
18
|
+
|
19
|
+
## 1.10.1 (2020-05-29)
|
20
|
+
|
21
|
+
- adds missing callbacks for `payment_intent`. Thanks @klapperkopp .
|
22
|
+
|
23
|
+
## 1.10.0 (2020-03-31)
|
24
|
+
|
25
|
+
- Adds support for using multiple tiers in a plan, thanks @cpsoinos
|
26
|
+
|
1
27
|
## 1.9.1 (2019-10-28)
|
2
28
|
|
3
29
|
- Fixes issue with `rake stripe:verify` thanks @Millariel !
|
data/Gemfile
CHANGED
@@ -11,12 +11,12 @@ end
|
|
11
11
|
|
12
12
|
group :test do
|
13
13
|
gem 'mocha'
|
14
|
-
gem 'simplecov', require: false
|
14
|
+
gem 'simplecov', '< 0.18', require: false
|
15
15
|
gem 'stripe-ruby-mock'
|
16
16
|
gem 'webmock'
|
17
|
-
#
|
17
|
+
# System tests
|
18
18
|
gem 'capybara'
|
19
|
-
gem 'webdrivers'
|
20
19
|
gem 'puma'
|
21
20
|
gem 'selenium-webdriver'
|
22
|
-
|
21
|
+
gem 'webdrivers'
|
22
|
+
end
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Stripe::Rails: A Rails Engine for use with [stripe.com](https://stripe.com)
|
2
|
-
[](https://badge.fury.io/rb/stripe-rails)
|
3
|
+
[](https://travis-ci.org/tansengming/stripe-rails)
|
4
4
|
[](https://codeclimate.com/github/tansengming/stripe-rails)
|
5
5
|
[](https://codeclimate.com/github/tansengming/stripe-rails/coverage)
|
6
6
|
[](#)
|
@@ -188,6 +188,23 @@ Stripe.plan :bronze do |plan|
|
|
188
188
|
plan.product_id = 'prod_XXXXXXXXXXXXXX'
|
189
189
|
plan.amount = 999 # $9.99
|
190
190
|
plan.interval = 'month'
|
191
|
+
|
192
|
+
# Use graduated pricing tiers
|
193
|
+
# ref: https://stripe.com/docs/api/plans/object#plan_object-tiers
|
194
|
+
plan.tiers = [
|
195
|
+
{
|
196
|
+
unit_amount: 1500,
|
197
|
+
up_to: 10
|
198
|
+
},
|
199
|
+
{
|
200
|
+
unit_amount: 1000,
|
201
|
+
up_to: 'inf'
|
202
|
+
}
|
203
|
+
]
|
204
|
+
plan.tiers_mode = 'graduated'
|
205
|
+
|
206
|
+
# set the usage type to 'metered'
|
207
|
+
plan.usage_type = 'metered'
|
191
208
|
end
|
192
209
|
```
|
193
210
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
|
-
gem 'rails', '~>
|
3
|
+
gem 'rails', '~> 5.1.0'
|
4
4
|
|
5
5
|
gem 'rake'
|
6
|
-
gem 'responders'
|
6
|
+
gem 'responders'
|
7
|
+
gem 'sprockets', '< 4'
|
7
8
|
gem 'stripe'
|
8
9
|
|
9
10
|
group :test do
|
@@ -13,7 +14,7 @@ group :test do
|
|
13
14
|
gem 'webmock'
|
14
15
|
# Required for system tests
|
15
16
|
gem 'capybara'
|
16
|
-
gem '
|
17
|
-
gem 'puma'
|
17
|
+
gem 'puma'
|
18
18
|
gem 'selenium-webdriver'
|
19
|
-
|
19
|
+
gem 'webdrivers'
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'rails', '~> 5.2.0'
|
4
|
+
|
5
|
+
gem 'rake'
|
6
|
+
gem 'responders'
|
7
|
+
gem 'sprockets', '< 4'
|
8
|
+
gem 'stripe'
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'mocha'
|
12
|
+
gem 'simplecov', require: false
|
13
|
+
gem 'stripe-ruby-mock'
|
14
|
+
gem 'webmock'
|
15
|
+
# Required for system tests
|
16
|
+
gem 'capybara'
|
17
|
+
gem 'puma'
|
18
|
+
gem 'selenium-webdriver'
|
19
|
+
gem 'webdrivers'
|
20
|
+
end
|
@@ -11,9 +11,9 @@
|
|
11
11
|
# product.type = 'service'
|
12
12
|
# end
|
13
13
|
|
14
|
-
# Once you have your
|
14
|
+
# Once you have your products defined, you can run
|
15
15
|
#
|
16
16
|
# rake stripe:prepare
|
17
17
|
#
|
18
|
-
# This will export any new
|
18
|
+
# This will export any new products to stripe.com so that you can
|
19
19
|
# begin using them in your API calls.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Stripe
|
2
|
+
module Plans
|
3
|
+
class BillingTier
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
validates_presence_of :up_to
|
7
|
+
validates_presence_of :flat_amount, if: ->(tier) { tier.unit_amount.nil? },
|
8
|
+
message: 'one of `flat_amount` or `unit_amount` must be specified!'
|
9
|
+
validates_presence_of :unit_amount, if: ->(tier) { tier.flat_amount.nil? },
|
10
|
+
message: 'one of `flat_amount` or `unit_amount` must be specified!'
|
11
|
+
validates_absence_of :flat_amount, if: ->(tier) { tier.unit_amount.present? },
|
12
|
+
message: 'only one of `flat_amount` or `unit_amount` should be specified!'
|
13
|
+
validates_absence_of :unit_amount, if: ->(tier) { tier.flat_amount.present? },
|
14
|
+
message: 'only one of `flat_amount` or `unit_amount` should be specified!'
|
15
|
+
|
16
|
+
attr_accessor :up_to, :flat_amount, :unit_amount
|
17
|
+
|
18
|
+
def initialize(attrs)
|
19
|
+
@up_to = attrs[:up_to]
|
20
|
+
@flat_amount = attrs[:flat_amount]
|
21
|
+
@unit_amount = attrs[:unit_amount]
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{
|
26
|
+
up_to: up_to,
|
27
|
+
flat_amount: flat_amount,
|
28
|
+
unit_amount: unit_amount
|
29
|
+
}.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/stripe/callbacks.rb
CHANGED
@@ -47,6 +47,7 @@ module Stripe
|
|
47
47
|
callback 'invoice.created'
|
48
48
|
callback 'invoice.finalized'
|
49
49
|
callback 'invoice.marked_uncollectible'
|
50
|
+
callback 'invoice.paid'
|
50
51
|
callback 'invoice.payment_action_required'
|
51
52
|
callback 'invoice.payment_failed'
|
52
53
|
callback 'invoice.payment_succeeded'
|
@@ -63,8 +64,10 @@ module Stripe
|
|
63
64
|
callback 'order.updated'
|
64
65
|
callback 'order_return.created'
|
65
66
|
callback 'payment_intent.amount_capturable_updated'
|
67
|
+
callback 'payment_intent.canceled'
|
66
68
|
callback 'payment_intent.created'
|
67
69
|
callback 'payment_intent.payment_failed'
|
70
|
+
callback 'payment_intent.processing'
|
68
71
|
callback 'payment_intent.succeeded'
|
69
72
|
callback 'payment_method.attached'
|
70
73
|
callback 'payment_method.card_automatically_updated'
|
@@ -103,10 +106,6 @@ module Stripe
|
|
103
106
|
callback 'ping'
|
104
107
|
callback 'stripe.event'
|
105
108
|
|
106
|
-
# Deprecated
|
107
|
-
callback 'transfer.failed' # https://stripe.com/docs/upgrades#2017-04-06
|
108
|
-
callback 'transfer.paid' # https://stripe.com/docs/upgrades#2017-04-06
|
109
|
-
|
110
109
|
class << self
|
111
110
|
def run_callbacks(evt, target)
|
112
111
|
_run_callbacks evt.type, evt, target
|
data/lib/stripe/plans.rb
CHANGED
@@ -12,16 +12,20 @@ module Stripe
|
|
12
12
|
:interval,
|
13
13
|
:interval_count,
|
14
14
|
:metadata,
|
15
|
-
:name,
|
15
|
+
:name,
|
16
16
|
:nickname,
|
17
17
|
:product_id,
|
18
18
|
:statement_descriptor,
|
19
|
+
:tiers,
|
19
20
|
:tiers_mode,
|
21
|
+
:transform_usage,
|
20
22
|
:trial_period_days,
|
21
23
|
:usage_type
|
22
24
|
|
23
|
-
validates_presence_of :id, :
|
24
|
-
|
25
|
+
validates_presence_of :id, :currency
|
26
|
+
validates_presence_of :amount, unless: ->(p) { p.billing_scheme == 'tiered' }
|
27
|
+
validates_absence_of :transform_usage, if: ->(p) { p.billing_scheme == 'tiered' }
|
28
|
+
validates_presence_of :tiers_mode, if: ->(p) { p.billing_scheme == 'tiered' }
|
25
29
|
validates_inclusion_of :interval,
|
26
30
|
in: %w(day week month year),
|
27
31
|
message: "'%{value}' is not one of 'day', 'week', 'month' or 'year'"
|
@@ -38,6 +42,11 @@ module Stripe
|
|
38
42
|
validate :aggregate_usage_must_be_metered, if: ->(p) { p.aggregate_usage.present? }
|
39
43
|
validate :valid_constant_name, unless: ->(p) { p.constant_name.nil? }
|
40
44
|
|
45
|
+
# validations for when using tiered billing
|
46
|
+
validate :tiers_must_be_array, if: ->(p) { p.tiers.present? }
|
47
|
+
validate :billing_scheme_must_be_tiered, if: ->(p) { p.tiers.present? }
|
48
|
+
validate :validate_tiers, if: ->(p) { p.billing_scheme == 'tiered' }
|
49
|
+
|
41
50
|
def initialize(*args)
|
42
51
|
super(*args)
|
43
52
|
@currency = 'usd'
|
@@ -54,6 +63,22 @@ module Stripe
|
|
54
63
|
errors.add(:base, 'must have a product_id or a name') unless (@product_id.present? ^ @name.present?)
|
55
64
|
end
|
56
65
|
|
66
|
+
def billing_scheme_must_be_tiered
|
67
|
+
errors.add(:billing_scheme, 'must be set to `tiered` when specifying `tiers`') unless billing_scheme == 'tiered'
|
68
|
+
end
|
69
|
+
|
70
|
+
def tiers_must_be_array
|
71
|
+
errors.add(:tiers, 'must be an Array') unless tiers.is_a?(Array)
|
72
|
+
end
|
73
|
+
|
74
|
+
def billing_tiers
|
75
|
+
@billing_tiers = tiers.map { |t| Stripe::Plans::BillingTier.new(t) } if tiers
|
76
|
+
end
|
77
|
+
|
78
|
+
def validate_tiers
|
79
|
+
billing_tiers.all?(&:valid?)
|
80
|
+
end
|
81
|
+
|
57
82
|
module ConstTester; end
|
58
83
|
def valid_constant_name
|
59
84
|
ConstTester.const_set(constant_name.to_s.upcase, constant_name)
|
@@ -82,8 +107,11 @@ module Stripe
|
|
82
107
|
usage_type: usage_type,
|
83
108
|
aggregate_usage: aggregate_usage,
|
84
109
|
billing_scheme: billing_scheme,
|
85
|
-
nickname: nickname
|
86
|
-
|
110
|
+
nickname: nickname,
|
111
|
+
tiers: tiers ? tiers.map(&:to_h) : nil,
|
112
|
+
tiers_mode: tiers_mode,
|
113
|
+
transform_usage: transform_usage
|
114
|
+
}.compact
|
87
115
|
end
|
88
116
|
|
89
117
|
def product_options
|
data/lib/stripe/products.rb
CHANGED
@@ -11,6 +11,7 @@ module Stripe
|
|
11
11
|
:caption,
|
12
12
|
:metadata,
|
13
13
|
:shippable,
|
14
|
+
:unit_label,
|
14
15
|
:url,
|
15
16
|
:statement_descriptor
|
16
17
|
|
@@ -42,6 +43,7 @@ module Stripe
|
|
42
43
|
caption: caption,
|
43
44
|
metadata: metadata,
|
44
45
|
shippable: shippable,
|
46
|
+
unit_label: unit_label,
|
45
47
|
url: url,
|
46
48
|
statement_descriptor: statement_descriptor
|
47
49
|
}
|
data/lib/stripe/rails.rb
CHANGED
data/lib/stripe/rails/version.rb
CHANGED
data/stripe-rails.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "stripe-rails"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Stripe::Rails::VERSION
|
17
|
-
gem.add_dependency 'rails', '>=
|
18
|
-
gem.add_dependency 'stripe', '>=
|
17
|
+
gem.add_dependency 'rails', '>= 5.1'
|
18
|
+
gem.add_dependency 'stripe', '>= 3.15.0'
|
19
19
|
gem.add_dependency 'responders'
|
20
20
|
end
|
data/test/callbacks_spec.rb
CHANGED
@@ -31,9 +31,9 @@ describe Stripe::Callbacks do
|
|
31
31
|
describe 'when it is invoked for the invoice.payment_succeeded event' do
|
32
32
|
it 'is invoked for the invoice.payment_succeeded event' do
|
33
33
|
subject
|
34
|
-
@event.wont_be_nil
|
35
|
-
@event.type.must_equal 'invoice.payment_succeeded'
|
36
|
-
@target.total.must_equal 6999
|
34
|
+
_(@event).wont_be_nil
|
35
|
+
_(@event.type).must_equal 'invoice.payment_succeeded'
|
36
|
+
_(@target.total).must_equal 6999
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -42,7 +42,7 @@ describe Stripe::Callbacks do
|
|
42
42
|
|
43
43
|
it 'the invoice.payment_succeeded callback is not invoked' do
|
44
44
|
subject
|
45
|
-
@event.must_be_nil
|
45
|
+
_(@event).must_be_nil
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -50,7 +50,7 @@ describe Stripe::Callbacks do
|
|
50
50
|
before { run_callback_with(callback) { fail } }
|
51
51
|
|
52
52
|
it 'causes the whole webhook to fail' do
|
53
|
-
->{ subject }.must_raise RuntimeError
|
53
|
+
_(-> { subject }).must_raise RuntimeError
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -61,8 +61,8 @@ describe Stripe::Callbacks do
|
|
61
61
|
|
62
62
|
it 'does not cause the webhook to fail' do
|
63
63
|
subject
|
64
|
-
last_response.status.must_be :>=, 200
|
65
|
-
last_response.status.must_be :<, 300
|
64
|
+
_(last_response.status).must_be :>=, 200
|
65
|
+
_(last_response.status).must_be :<, 300
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -75,7 +75,7 @@ describe Stripe::Callbacks do
|
|
75
75
|
|
76
76
|
it 'it will be run' do
|
77
77
|
subject
|
78
|
-
events.first.type.must_equal 'invoice.payment_failed'
|
78
|
+
_(events.first.type).must_equal 'invoice.payment_failed'
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -84,7 +84,7 @@ describe Stripe::Callbacks do
|
|
84
84
|
|
85
85
|
it 'it will be run' do
|
86
86
|
subject
|
87
|
-
events.first.type.must_equal 'foo.bar.baz'
|
87
|
+
_(events.first.type).must_equal 'foo.bar.baz'
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -109,7 +109,7 @@ describe Stripe::Callbacks do
|
|
109
109
|
describe 'when a prior attribute was not specified' do
|
110
110
|
it 'does not fire events' do
|
111
111
|
subject
|
112
|
-
events.length.must_equal 0
|
112
|
+
_(events.length).must_equal 0
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
@@ -117,7 +117,7 @@ describe Stripe::Callbacks do
|
|
117
117
|
before { @stubbed_event.data.previous_attributes['closed'] = true }
|
118
118
|
it 'fires events' do
|
119
119
|
subject
|
120
|
-
events.length.must_equal 1
|
120
|
+
_(events.length).must_equal 1
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -134,7 +134,7 @@ describe Stripe::Callbacks do
|
|
134
134
|
describe 'when a prior attribute was not specified' do
|
135
135
|
it 'does not fire events' do
|
136
136
|
subject
|
137
|
-
events.length.must_equal 0
|
137
|
+
_(events.length).must_equal 0
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
@@ -142,7 +142,7 @@ describe Stripe::Callbacks do
|
|
142
142
|
before { @stubbed_event.data.previous_attributes['subtotal'] = 699 }
|
143
143
|
it 'fire events' do
|
144
144
|
subject
|
145
|
-
events.length.must_equal 1
|
145
|
+
_(events.length).must_equal 1
|
146
146
|
end
|
147
147
|
end
|
148
148
|
end
|
@@ -159,7 +159,7 @@ describe Stripe::Callbacks do
|
|
159
159
|
describe 'when the lambda is not true' do
|
160
160
|
it 'does not fire events' do
|
161
161
|
subject
|
162
|
-
events.length.must_equal 0
|
162
|
+
_(events.length).must_equal 0
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
@@ -167,7 +167,7 @@ describe Stripe::Callbacks do
|
|
167
167
|
before { @stubbed_event.data.previous_attributes['closed'] = 'false' }
|
168
168
|
it 'fires events' do
|
169
169
|
subject
|
170
|
-
events.length.must_equal 1
|
170
|
+
_(events.length).must_equal 1
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|