ecwid_api 0.2.2 → 0.2.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.
- checksums.yaml +5 -5
- data/.gitignore +0 -0
- data/.rspec +0 -0
- data/.travis.yml +0 -0
- data/Gemfile +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +12 -4
- data/Rakefile +0 -0
- data/ecwid_api.gemspec +8 -7
- data/lib/ecwid_api.rb +3 -0
- data/lib/ecwid_api/api.rb +6 -3
- data/lib/ecwid_api/api/base.rb +0 -0
- data/lib/ecwid_api/api/categories.rb +0 -0
- data/lib/ecwid_api/api/customers.rb +53 -0
- data/lib/ecwid_api/api/orders.rb +4 -4
- data/lib/ecwid_api/api/product_combinations.rb +0 -0
- data/lib/ecwid_api/api/product_types.rb +56 -0
- data/lib/ecwid_api/api/products.rb +93 -7
- data/lib/ecwid_api/category.rb +0 -0
- data/lib/ecwid_api/client.rb +7 -5
- data/lib/ecwid_api/customer.rb +10 -0
- data/lib/ecwid_api/entity.rb +15 -3
- data/lib/ecwid_api/error.rb +1 -1
- data/lib/ecwid_api/o_auth.rb +0 -0
- data/lib/ecwid_api/order.rb +39 -9
- data/lib/ecwid_api/order_item.rb +0 -0
- data/lib/ecwid_api/paged_ecwid_response.rb +11 -9
- data/lib/ecwid_api/paged_enumerator.rb +0 -0
- data/lib/ecwid_api/person.rb +0 -0
- data/lib/ecwid_api/product.rb +0 -0
- data/lib/ecwid_api/product_combination.rb +0 -0
- data/lib/ecwid_api/product_type.rb +18 -0
- data/lib/ecwid_api/product_type_attribute.rb +27 -0
- data/lib/ecwid_api/unpaged_ecwid_response.rb +38 -0
- data/lib/ecwid_api/version.rb +1 -1
- data/lib/ext/string.rb +0 -0
- data/spec/api/categories_spec.rb +0 -0
- data/spec/api/customers_spec.rb +20 -0
- data/spec/api/orders_spec.rb +5 -5
- data/spec/api/product_types_spec.rb +20 -0
- data/spec/api/products_spec.rb +0 -0
- data/spec/category_spec.rb +0 -0
- data/spec/client_spec.rb +3 -3
- data/spec/entity_spec.rb +41 -14
- data/spec/fixtures/categories.json +0 -0
- data/spec/fixtures/category.json +0 -0
- data/spec/fixtures/classes.json +44 -0
- data/spec/fixtures/customers.json +48 -0
- data/spec/fixtures/order.json +1 -1
- data/spec/fixtures/orders.json +2 -1
- data/spec/fixtures/products.json +0 -0
- data/spec/helpers/client.rb +4 -2
- data/spec/oauth_spec.rb +4 -4
- data/spec/order_item_spec.rb +0 -0
- data/spec/order_spec.rb +12 -12
- data/spec/paged_enumerator_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- metadata +37 -17
data/lib/ecwid_api/error.rb
CHANGED
|
@@ -4,7 +4,7 @@ module EcwidApi
|
|
|
4
4
|
class ResponseError < Error
|
|
5
5
|
def initialize(response)
|
|
6
6
|
if response.respond_to?(:reason_phrase)
|
|
7
|
-
super
|
|
7
|
+
super "#{response.reason_phrase} (#{response.status})\n#{response.body}"
|
|
8
8
|
else
|
|
9
9
|
super "The Ecwid API responded with an error (#{response.status})"
|
|
10
10
|
end
|
data/lib/ecwid_api/o_auth.rb
CHANGED
|
File without changes
|
data/lib/ecwid_api/order.rb
CHANGED
|
@@ -3,7 +3,7 @@ module EcwidApi
|
|
|
3
3
|
class Order < Entity
|
|
4
4
|
self.url_root = "orders"
|
|
5
5
|
|
|
6
|
-
ecwid_reader :orderNumber, :vendorOrderNumber, :subtotal, :total, :email,
|
|
6
|
+
ecwid_reader :id, :orderNumber, :vendorOrderNumber, :subtotal, :total, :email,
|
|
7
7
|
:paymentMethod, :paymentModule, :tax, :ipAddress,
|
|
8
8
|
:couponDiscount, :paymentStatus, :fulfillmentStatus,
|
|
9
9
|
:refererUrl, :orderComments, :volumeDiscount, :customerId,
|
|
@@ -13,7 +13,7 @@ module EcwidApi
|
|
|
13
13
|
:shippingPerson, :shippingOption, :additionalInfo,
|
|
14
14
|
:paymentParams, :discountInfo, :trackingNumber,
|
|
15
15
|
:paymentMessage, :extTransactionId, :affiliateId,
|
|
16
|
-
:creditCardStatus
|
|
16
|
+
:creditCardStatus, :handlingFee
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
ecwid_writer :subtotal, :total, :email, :paymentMethod, :paymentModule,
|
|
@@ -25,7 +25,7 @@ module EcwidApi
|
|
|
25
25
|
:items, :billingPerson, :shippingPerson, :shippingOption,
|
|
26
26
|
:additionalInfo, :paymentParams, :discountInfo,
|
|
27
27
|
:trackingNumber, :paymentMessage, :extTransactionId,
|
|
28
|
-
:affiliateId, :creditCardStatus
|
|
28
|
+
:affiliateId, :creditCardStatus, :handlingFee
|
|
29
29
|
|
|
30
30
|
VALID_FULFILLMENT_STATUSES = %w(
|
|
31
31
|
AWAITING_PROCESSING
|
|
@@ -34,11 +34,29 @@ module EcwidApi
|
|
|
34
34
|
DELIVERED
|
|
35
35
|
WILL_NOT_DELIVER
|
|
36
36
|
RETURNED
|
|
37
|
-
|
|
37
|
+
READY_FOR_PICKUP
|
|
38
|
+
OUT_FOR_DELIVERY
|
|
39
|
+
).freeze
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
VALID_PAYMENT_STATUSES = %w(
|
|
42
|
+
AWAITING_PAYMENT
|
|
43
|
+
PAID
|
|
44
|
+
CANCELLED
|
|
45
|
+
REFUNDED
|
|
46
|
+
PARTIALLY_REFUNDED
|
|
47
|
+
INCOMPLETE
|
|
48
|
+
).freeze
|
|
49
|
+
|
|
50
|
+
# @deprecated Please use {#id} instead
|
|
51
|
+
def vendor_order_number
|
|
52
|
+
warn "[DEPRECATION] `vendor_order_number` is deprecated. Please use `id` instead."
|
|
53
|
+
id
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @deprecated Please use {#id} instead
|
|
57
|
+
def order_number
|
|
58
|
+
warn "[DEPRECATION] `order_number` is deprecated. Please use `id` instead."
|
|
59
|
+
id
|
|
42
60
|
end
|
|
43
61
|
|
|
44
62
|
# Public: Returns the billing person
|
|
@@ -51,7 +69,7 @@ module EcwidApi
|
|
|
51
69
|
|
|
52
70
|
# Public: Returns the shipping person
|
|
53
71
|
#
|
|
54
|
-
# If there isn't a shipping_person, then it is assumed to be the
|
|
72
|
+
# If there isn't a shipping_person, then it is assumed to be the
|
|
55
73
|
# billing_person
|
|
56
74
|
#
|
|
57
75
|
def shipping_person
|
|
@@ -75,6 +93,18 @@ module EcwidApi
|
|
|
75
93
|
super && super.downcase.to_sym
|
|
76
94
|
end
|
|
77
95
|
|
|
96
|
+
def payment_status=(status)
|
|
97
|
+
status = status.to_s.upcase
|
|
98
|
+
unless VALID_PAYMENT_STATUSES.include?(status)
|
|
99
|
+
raise Error("#{status} is an invalid payment status")
|
|
100
|
+
end
|
|
101
|
+
super(status)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def payment_status
|
|
105
|
+
super && super.downcase.to_sym
|
|
106
|
+
end
|
|
107
|
+
|
|
78
108
|
private
|
|
79
109
|
|
|
80
110
|
def build_billing_person
|
|
@@ -85,4 +115,4 @@ module EcwidApi
|
|
|
85
115
|
@shipping_person ||= data["shippingPerson"] && Person.new(data["shippingPerson"])
|
|
86
116
|
end
|
|
87
117
|
end
|
|
88
|
-
end
|
|
118
|
+
end
|
data/lib/ecwid_api/order_item.rb
CHANGED
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require_relative
|
|
1
|
+
require_relative 'paged_enumerator'
|
|
2
2
|
|
|
3
3
|
# Public: Presents a paged Ecwid response as an Enumerator with a
|
|
4
4
|
# PagedEnumerator
|
|
@@ -31,20 +31,22 @@ module EcwidApi
|
|
|
31
31
|
params[:limit] = 100
|
|
32
32
|
params.delete(:offset)
|
|
33
33
|
|
|
34
|
-
block ||=
|
|
34
|
+
block ||= proc { |item| item }
|
|
35
35
|
|
|
36
36
|
response = client.get(path, params)
|
|
37
37
|
|
|
38
|
-
@paged_enumerator = PagedEnumerator.new(response) do |
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
@paged_enumerator = PagedEnumerator.new(response) do |enum_response, yielder|
|
|
39
|
+
count, offset, total = %w[count offset total].map do |i|
|
|
40
|
+
enum_response.body[i].to_i
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
if count > 0
|
|
44
|
+
enum_response.body['items'].each do |item|
|
|
45
|
+
yielder << block.call(item)
|
|
46
|
+
end
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
if count
|
|
49
|
+
if count.zero? || count + offset >= total
|
|
48
50
|
false
|
|
49
51
|
else
|
|
50
52
|
client.get(path, params.merge(offset: offset + count))
|
|
@@ -52,4 +54,4 @@ module EcwidApi
|
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
|
-
end
|
|
57
|
+
end
|
|
File without changes
|
data/lib/ecwid_api/person.rb
CHANGED
|
File without changes
|
data/lib/ecwid_api/product.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module EcwidApi
|
|
2
|
+
class ProductType < Entity
|
|
3
|
+
|
|
4
|
+
self.url_root = "classes"
|
|
5
|
+
|
|
6
|
+
ecwid_reader :id, :name, :googleTaxonomy, :attributes
|
|
7
|
+
|
|
8
|
+
ecwid_writer :name, :attributes
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Public: Returns a Array of `ProductTypeAttribute` objects
|
|
12
|
+
def attributes
|
|
13
|
+
@attributes ||= data["attributes"].map { |attribute| ProductTypeAttribute.new(attribute) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module EcwidApi
|
|
2
|
+
class ProductTypeAttribute < Entity
|
|
3
|
+
|
|
4
|
+
ecwid_reader :id, :name, :type, :show
|
|
5
|
+
|
|
6
|
+
VALID_TYPES = %w(CUSTOM UPC BRAND GENDER AGE_GROUP COLOR SIZE PRICE_PER_UNIT UNITS_IN_PRODUCT)
|
|
7
|
+
VALID_SHOWS = %w(NOTSHOW DESCR PRICE)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def type=(type_type)
|
|
11
|
+
type_type = type_type.to_s.upcase
|
|
12
|
+
unless VALID_TYPES.include?(type_type)
|
|
13
|
+
raise ::StandardError.new("#{type_type} is an invalid 'type'")
|
|
14
|
+
end
|
|
15
|
+
super(type_type)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def show=(show_type)
|
|
20
|
+
show_type = show_type.to_s.upcase
|
|
21
|
+
unless VALID_SHOWS.include?(show_type)
|
|
22
|
+
raise ::StandardError.new("#{show_type} is an invalid 'show'")
|
|
23
|
+
end
|
|
24
|
+
super(show_type)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
# Public: Presents an Ecwid response as an Array
|
|
3
|
+
#
|
|
4
|
+
# Example
|
|
5
|
+
#
|
|
6
|
+
# response = UnpagedEcwidResponse.new(client, "products", priceFrom: 10) do |product_hash|
|
|
7
|
+
# Product.new(product_hash, click: client)
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# response.each do |product|
|
|
11
|
+
# # do stuff the the product
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
module EcwidApi
|
|
15
|
+
class UnpagedEcwidResponse
|
|
16
|
+
include Enumerable
|
|
17
|
+
extend Forwardable
|
|
18
|
+
|
|
19
|
+
def_delegators :@records, *Enumerable.instance_methods
|
|
20
|
+
|
|
21
|
+
# Public: Initialize a new UnpagedEcwidResponse
|
|
22
|
+
#
|
|
23
|
+
# client - an EcwidApi::Client
|
|
24
|
+
# path - a String that is the path to retrieve from the client
|
|
25
|
+
# params - a Hash of parameters to pass along with the request
|
|
26
|
+
# &block - a Block that processes each item returned in the Response
|
|
27
|
+
#
|
|
28
|
+
def initialize(client, path, params = {}, &block)
|
|
29
|
+
block ||= Proc.new { |item| item }
|
|
30
|
+
@records = []
|
|
31
|
+
|
|
32
|
+
response = client.get(path, params)
|
|
33
|
+
response.body.each do |item|
|
|
34
|
+
@records << block.call(item)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/ecwid_api/version.rb
CHANGED
data/lib/ext/string.rb
CHANGED
|
File without changes
|
data/spec/api/categories_spec.rb
CHANGED
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe EcwidApi::Api::Customers, faraday: true do
|
|
4
|
+
subject { client.customers }
|
|
5
|
+
|
|
6
|
+
describe "#all" do
|
|
7
|
+
it "passes any other parameters through" do
|
|
8
|
+
expect(client).to receive(:get).with("customers", hash_including(from_date: '1982-05-17'))
|
|
9
|
+
subject.all(from_date: '1982-05-17')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "gets the proper response count (see fixture)" do
|
|
13
|
+
expect(subject.all.count).to eq 5
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "gets the proper customer (see fixture)" do
|
|
17
|
+
expect(subject.all.first.name).to eq "Abe Doe"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/spec/api/orders_spec.rb
CHANGED
|
@@ -10,21 +10,21 @@ describe EcwidApi::Api::Orders, faraday: true do
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
it "gets the proper response (see fixtures)" do
|
|
13
|
-
subject.all.count.
|
|
13
|
+
expect(subject.all.count).to be 2
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "gets EcwidApi::Order types" do
|
|
17
|
-
subject.all.all? { |order| order.is_a?(EcwidApi::Order) }.
|
|
17
|
+
expect(subject.all.all? { |order| order.is_a?(EcwidApi::Order) }).to be(true)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
describe "#find" do
|
|
22
22
|
it "is an `EcwidApi::Order`" do
|
|
23
|
-
subject.find(35).
|
|
23
|
+
expect(subject.find(35)).to be_a(EcwidApi::Order)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "is nil when not found" do
|
|
27
|
-
subject.find(404).
|
|
27
|
+
expect(subject.find(404)).to be_nil
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
|
-
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe EcwidApi::Api::ProductTypes, faraday: true do
|
|
4
|
+
subject { client.product_types }
|
|
5
|
+
|
|
6
|
+
describe "#all" do
|
|
7
|
+
it "returns an array" do
|
|
8
|
+
expect(client).to receive(:get).with("classes", {}).and_call_original
|
|
9
|
+
subject.all
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "gets the proper response count (see fixture)" do
|
|
13
|
+
expect(subject.all.count).to eq 2
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "gets the proper product_type (see fixture)" do
|
|
17
|
+
expect(subject.all.first.name).to eq "Foo"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/spec/api/products_spec.rb
CHANGED
|
File without changes
|
data/spec/category_spec.rb
CHANGED
|
File without changes
|
data/spec/client_spec.rb
CHANGED
|
@@ -4,7 +4,7 @@ describe EcwidApi::Client do
|
|
|
4
4
|
subject { client }
|
|
5
5
|
|
|
6
6
|
describe "#store_url" do
|
|
7
|
-
|
|
7
|
+
it { is_expected.to have_attributes(store_url: "https://app.ecwid.com/api/v3/12345") }
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
describe "#get", faraday: true do
|
|
@@ -15,7 +15,7 @@ describe EcwidApi::Client do
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
it "returns a Faraday::Response" do
|
|
18
|
-
subject.get("categories", parent: 1).
|
|
18
|
+
expect(subject.get("categories", parent: 1)).to be_a(Faraday::Response)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
-
end
|
|
21
|
+
end
|
data/spec/entity_spec.rb
CHANGED
|
@@ -34,42 +34,50 @@ describe EcwidApi::Entity do
|
|
|
34
34
|
subject { EntitySubject.new(data) }
|
|
35
35
|
|
|
36
36
|
describe "::url_root" do
|
|
37
|
-
|
|
37
|
+
it { is_expected.to have_attributes(url: "stuff/123") }
|
|
38
38
|
|
|
39
39
|
context "with a proc" do
|
|
40
40
|
subject { EntityUrlSubject.new(data) }
|
|
41
|
-
|
|
41
|
+
it { is_expected.to have_attributes(url: "parent/456/and/123") }
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
|
|
46
45
|
describe "#[]" do
|
|
47
46
|
it "gets data with a symbol key" do
|
|
48
|
-
subject[:id].
|
|
47
|
+
expect(subject[:id]).to eq 123
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
it "gets data with a string key" do
|
|
52
|
-
subject["parentId"].
|
|
51
|
+
expect(subject["parentId"]).to eq 456
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
it "get nil for unknown data" do
|
|
56
|
-
subject["whatever"].
|
|
55
|
+
expect(subject["whatever"]).to be_nil
|
|
57
56
|
end
|
|
58
57
|
|
|
59
58
|
it "gets attributes not revealed by ecwid_reader or ecwid_accessor" do
|
|
60
|
-
subject["hidden"].
|
|
59
|
+
expect(subject["hidden"]).to eq "tee hee"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe "#==" do
|
|
64
|
+
context "with and without a client" do
|
|
65
|
+
let(:other) { EntitySubject.new(data, client: client) }
|
|
66
|
+
|
|
67
|
+
it "returns true" do
|
|
68
|
+
expect(subject).to eq(other)
|
|
69
|
+
end
|
|
61
70
|
end
|
|
62
71
|
end
|
|
63
72
|
|
|
64
73
|
describe "overrides" do
|
|
65
|
-
|
|
74
|
+
it { is_expected.to have_attributes(override: "UPCASE ME") }
|
|
66
75
|
end
|
|
67
76
|
|
|
68
77
|
describe "accessors" do
|
|
69
|
-
|
|
70
78
|
describe "::ecwid_reader" do
|
|
71
79
|
it "makes data accessible with a snake cased method" do
|
|
72
|
-
subject.parent_id.
|
|
80
|
+
expect(subject.parent_id).to eq 456
|
|
73
81
|
end
|
|
74
82
|
|
|
75
83
|
it "doesn't have a writer" do
|
|
@@ -80,7 +88,7 @@ describe EcwidApi::Entity do
|
|
|
80
88
|
describe "::ecwid_writer" do
|
|
81
89
|
it "creates a writer method" do
|
|
82
90
|
subject.write_only = "yee haw!"
|
|
83
|
-
subject["writeOnly"].
|
|
91
|
+
expect(subject["writeOnly"]).to eq "yee haw!"
|
|
84
92
|
end
|
|
85
93
|
|
|
86
94
|
it "doesn't have a reader" do
|
|
@@ -91,13 +99,13 @@ describe EcwidApi::Entity do
|
|
|
91
99
|
describe "::ecwid_accessor" do
|
|
92
100
|
it "creates a reader and a writer" do
|
|
93
101
|
subject.the_status = "MATURE"
|
|
94
|
-
subject.the_status.
|
|
102
|
+
expect(subject.the_status).to eq "MATURE"
|
|
95
103
|
end
|
|
96
104
|
end
|
|
97
105
|
|
|
98
106
|
describe "without an accessor" do
|
|
99
107
|
it "is accessible with []" do
|
|
100
|
-
subject[:hidden].
|
|
108
|
+
expect(subject[:hidden]).to eq "tee hee"
|
|
101
109
|
end
|
|
102
110
|
|
|
103
111
|
it "doesn't have an access method" do
|
|
@@ -105,4 +113,23 @@ describe EcwidApi::Entity do
|
|
|
105
113
|
end
|
|
106
114
|
end
|
|
107
115
|
end
|
|
108
|
-
|
|
116
|
+
|
|
117
|
+
describe "marshaling" do
|
|
118
|
+
context "with a client" do
|
|
119
|
+
subject { EntitySubject.new(data, client: client) }
|
|
120
|
+
|
|
121
|
+
describe "dump" do
|
|
122
|
+
it "does not raise" do
|
|
123
|
+
expect { Marshal.dump(subject) }.not_to raise_error
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "load" do
|
|
128
|
+
it "converts a dumped object" do
|
|
129
|
+
source = Marshal.dump(subject)
|
|
130
|
+
expect(Marshal.load(source)).to eq(subject)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|