ecwid_api 0.0.2 → 0.1.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -0
  3. data/Gemfile +2 -0
  4. data/README.md +228 -144
  5. data/ecwid_api.gemspec +1 -0
  6. data/lib/ecwid_api/api/base.rb +17 -0
  7. data/lib/ecwid_api/api/categories.rb +57 -0
  8. data/lib/ecwid_api/api/orders.rb +36 -0
  9. data/lib/ecwid_api/api/product_combinations.rb +51 -0
  10. data/lib/ecwid_api/api/products.rb +64 -0
  11. data/lib/ecwid_api/api.rb +31 -0
  12. data/lib/ecwid_api/category.rb +59 -4
  13. data/lib/ecwid_api/client.rb +65 -94
  14. data/lib/ecwid_api/entity.rb +138 -26
  15. data/lib/ecwid_api/error.rb +12 -2
  16. data/lib/ecwid_api/o_auth.rb +106 -0
  17. data/lib/ecwid_api/order.rb +82 -0
  18. data/lib/ecwid_api/order_item.rb +17 -0
  19. data/lib/ecwid_api/paged_ecwid_response.rb +55 -0
  20. data/lib/ecwid_api/paged_enumerator.rb +66 -0
  21. data/lib/ecwid_api/person.rb +7 -0
  22. data/lib/ecwid_api/product.rb +77 -0
  23. data/lib/ecwid_api/product_combination.rb +34 -0
  24. data/lib/ecwid_api/version.rb +1 -1
  25. data/lib/ecwid_api.rb +25 -39
  26. data/lib/ext/string.rb +12 -4
  27. data/spec/api/categories_spec.rb +31 -0
  28. data/spec/api/orders_spec.rb +30 -0
  29. data/spec/api/products_spec.rb +20 -0
  30. data/spec/category_spec.rb +33 -38
  31. data/spec/client_spec.rb +20 -48
  32. data/spec/entity_spec.rb +90 -5
  33. data/spec/fixtures/categories.json +28 -22
  34. data/spec/fixtures/order.json +162 -0
  35. data/spec/fixtures/orders.json +302 -0
  36. data/spec/fixtures/products.json +141 -0
  37. data/spec/helpers/client.rb +32 -0
  38. data/spec/oauth_spec.rb +40 -0
  39. data/spec/order_item_spec.rb +12 -0
  40. data/spec/order_spec.rb +71 -0
  41. data/spec/paged_enumerator_spec.rb +38 -0
  42. data/spec/spec_helper.rb +24 -23
  43. metadata +53 -9
  44. data/lib/ecwid_api/category_api.rb +0 -62
  45. data/spec/category_api_spec.rb +0 -36
  46. data/spec/ecwid_api_spec.rb +0 -15
  47. data/spec/helpers/faraday.rb +0 -30
@@ -0,0 +1,55 @@
1
+ require_relative "paged_enumerator"
2
+
3
+ # Public: Presents a paged Ecwid response as an Enumerator with a
4
+ # PagedEnumerator
5
+ #
6
+ # Example
7
+ #
8
+ # response = PagedEcwidResponse.new(client, "products", priceFrom: 10) do |product_hash|
9
+ # Product.new(product_hash, click: client)
10
+ # end
11
+ #
12
+ # response.each do |product|
13
+ # # do stuff the the product
14
+ # end
15
+ #
16
+ module EcwidApi
17
+ class PagedEcwidResponse
18
+ include Enumerable
19
+ extend Forwardable
20
+
21
+ def_delegator :@paged_enumerator, :each
22
+
23
+ # Public: Initialize a new PagedEcwidResponse
24
+ #
25
+ # client - an EcwidApi::Client
26
+ # path - a String that is the path to retrieve from the client
27
+ # params - a Hash of parameters to pass along with the request
28
+ # &block - a Block that processes each item returned in the Response
29
+ #
30
+ def initialize(client, path, params = {}, &block)
31
+ params[:limit] = 100
32
+ params.delete(:offset)
33
+
34
+ block ||= Proc.new { |item| item }
35
+
36
+ response = client.get(path, params)
37
+
38
+ @paged_enumerator = PagedEnumerator.new(response) do |response, yielder|
39
+ response.body["items"].each do |item|
40
+ yielder << block.call(item)
41
+ end
42
+
43
+ count, offset, total = %w(count offset total).map do |i|
44
+ response.body[i].to_i
45
+ end
46
+
47
+ if count == 0 || count + offset >= total
48
+ false
49
+ else
50
+ client.get(path, params.merge(offset: offset + count))
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,66 @@
1
+ module EcwidApi
2
+ # Public: Abstracts pagination into an Enumerator so all of the objects for
3
+ # a given response can be retreived without having to know that they were
4
+ # split into pages from the server
5
+ #
6
+ # Examples
7
+ #
8
+ # client.get("orders", limit: 10)
9
+ #
10
+ # paged = PagedEnumerator.new(orders) do |response, yielder|
11
+ # response.body["orders"].each do |obj|
12
+ # yielder << obj
13
+ # end
14
+ #
15
+ # next_url = response.body["nextUrl"]
16
+ # next_url ? client.get(next_url) : false
17
+ # end
18
+ #
19
+ # paged.each do |item|
20
+ # puts item.inspect
21
+ # end
22
+ #
23
+ class PagedEnumerator
24
+ include Enumerable
25
+
26
+ # Private: A response that we are evaluating
27
+ attr_reader :response
28
+ private :response
29
+
30
+ # Private: Gets the next response
31
+ attr_reader :next_block
32
+ private :next_block
33
+
34
+ # Public: Initializes a new PagedEnumerator
35
+ #
36
+ # response - the response that contains a collection of objects
37
+ # next_block - The block will receive the response and a yielder Proc.
38
+ # The block should use `yielder << item` to yield all of
39
+ # the items in the collection.
40
+ #
41
+ # Then the block should return the next response. If no
42
+ # response is given (eg: the last page), the block should
43
+ # return a falsey value.
44
+ #
45
+ def initialize(response, &next_block)
46
+ @response, @next_block = response, next_block
47
+ end
48
+
49
+ # Public: Iterates over each "page" yielding each "item" in every collection
50
+ def each(&block)
51
+ unless @next_enumerator
52
+ @yielder ||= []
53
+ @next_response ||= next_block.call(response, @yielder)
54
+
55
+ if @next_response
56
+ @next_enumerator ||= PagedEnumerator.new(@next_response, &@next_block)
57
+ else
58
+ @next_enumerator = []
59
+ end
60
+ end
61
+
62
+ @yielder.each(&block)
63
+ @next_enumerator.each(&block)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,7 @@
1
+ module EcwidApi
2
+ class Person < Entity
3
+ ecwid_reader :name, :companyName, :street, :city, :countryCode,
4
+ :countryName, :postalCode, :stateOrProvinceCode,
5
+ :stateOrProvinceName, :phone
6
+ end
7
+ end
@@ -0,0 +1,77 @@
1
+ require "open-uri"
2
+
3
+ module EcwidApi
4
+ class Product < Entity
5
+ self.url_root = "products"
6
+
7
+ ecwid_reader :id, :sku, :quantity, :unlimited, :inStock, :name, :price,
8
+ :priceInProductList, :wholesalePrices, :compareToPrice,
9
+ :weight, :url, :created, :updated, :productClassId,
10
+ :enabled, :options, :warningLimit, :fixedShippingRateOnly,
11
+ :fixedShippingRate, :defaultCombinationId, :thumbnailUrl,
12
+ :imageUrl, :smallThumbnailUrl, :originalImageUrl, :description,
13
+ :galleryImages, :categoryIds, :defaultCategoryId, :favorites,
14
+ :attributes, :files, :relatedProducts, :combinations
15
+
16
+ ecwid_writer :sku, :name, :quantity, :price, :wholesalePrices,
17
+ :compareToPrice, :weight, :productClassId, :enabled, :options,
18
+ :warningLimit, :fixedShippingRateOnly, :fixedShippingRate,
19
+ :description, :categoryIds, :defaultCategoryId, :attributes,
20
+ :relatedProducts
21
+
22
+ # Public: Uploads a primary image for a Product
23
+ #
24
+ # filename - a String that is either a local file name or URL
25
+ #
26
+ # Raises ResponseError if the API returns an error
27
+ #
28
+ # Returns a Faraday::Response object
29
+ def upload_image!(filename)
30
+ client.post("#{url}/image") do |req|
31
+ req.body = open(filename).read
32
+ end.tap do |response|
33
+ raise_on_failure(response)
34
+ end
35
+ end
36
+
37
+ # Public: Uploads gallery images for a Product
38
+ #
39
+ # *filenames - Strings that are either a local file name or URL
40
+ #
41
+ # Raises ResponseError if the API returns an error
42
+ #
43
+ # Returns an Array of Faraday::Response object
44
+ def upload_gallery_images!(*filenames)
45
+ filenames.map do |filename|
46
+ client.post("#{url}/gallery") do |req|
47
+ req.body = open(filename).read
48
+ end.tap do |response|
49
+ raise_on_failure(response)
50
+ end
51
+ end
52
+ end
53
+
54
+ # Public: Deletes all of the gallery images for a Product
55
+ #
56
+ # Raises ResponseError if the API returns an error
57
+ #
58
+ # Returns a Faraday::Response object
59
+ def delete_gallery_images!
60
+ client.delete("#{url}/gallery").tap do |response|
61
+ raise_on_failure(response)
62
+ end
63
+ end
64
+
65
+ def combinations
66
+ @combinations ||= Api::ProductCombinations.new(self, client)
67
+ end
68
+
69
+ def created
70
+ @created ||= Time.parse(super)
71
+ end
72
+
73
+ def updated
74
+ @updated ||= Time.parse(super)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,34 @@
1
+ module EcwidApi
2
+ class ProductCombination < Entity
3
+ attr_reader :product
4
+
5
+ self.url_root = -> { "products/#{product.id}/combinations" }
6
+
7
+ ecwid_reader :id, :combinationNumber, :options, :sku, :smallThumbnailUrl,
8
+ :thumbnailUrl, :imageUrl, :originalImageUrl, :quantity,
9
+ :unlimited, :price, :wholesalePrices, :weight, :warningLimit
10
+
11
+ ecwid_writer :options, :sku, :quantity, :unlimited, :price,
12
+ :wholesalePrices, :weight, :warningLimit, :inventoryDelta
13
+
14
+ def initialize(data, opts={})
15
+ super(data, opts)
16
+ @product = opts[:product]
17
+ end
18
+
19
+ # Public: Uploads a primary image for a ProductCombination
20
+ #
21
+ # filename - a String that is either a local file name or URL
22
+ #
23
+ # Raises ResponseError if the API returns an error
24
+ #
25
+ # Returns a Faraday::Response object
26
+ def upload_image!(filename)
27
+ client.post("#{url}/image") do |req|
28
+ req.body = open(filename).read
29
+ end.tap do |response|
30
+ raise_on_failure(response)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module EcwidApi
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/ecwid_api.rb CHANGED
@@ -1,39 +1,25 @@
1
- require "ecwid_api/version"
2
- require "ext/string"
3
-
4
- # Public: This is the main namespace for the EcwidApi. It can be used to store
5
- # the default client.
6
- #
7
- module EcwidApi
8
- autoload :Client, "ecwid_api/client"
9
- autoload :Error, "ecwid_api/error"
10
- autoload :Entity, "ecwid_api/entity"
11
-
12
- autoload :CategoryApi, "ecwid_api/category_api"
13
- autoload :Category, "ecwid_api/category"
14
-
15
- class << self
16
- # Public: Gets and configures a default client
17
- #
18
- # To configure the default client, just pass a block.
19
- #
20
- # Examples
21
- #
22
- # EcwidApi.default_client do |config|
23
- # config.store_id = '12345'
24
- # config.order_secret_key = 'ORDER_SECRET_KEY'
25
- # config.product_secret_key = 'PRODUCT_SECRET_KEY'
26
- # end
27
- #
28
- # client = EcwidApi.default_client.store_id
29
- # # => "12345"
30
- #
31
- # Returns an EcwidApi::Client, or null if one hasn't been configured
32
- def default_client(&block)
33
- if block_given?
34
- @default_client = Client.new(&block)
35
- end
36
- @default_client
37
- end
38
- end
39
- end
1
+ require "ecwid_api/version"
2
+ require "ext/string"
3
+ require 'faraday'
4
+ require 'faraday_middleware'
5
+
6
+ require_relative "ecwid_api/error"
7
+
8
+ # Public: This is the main namespace for the EcwidApi. It can be used to store
9
+ # the default client.
10
+ #
11
+ module EcwidApi
12
+ autoload :OAuth, "ecwid_api/o_auth"
13
+ autoload :Client, "ecwid_api/client"
14
+ autoload :ResponseError, "ecwid_api/error"
15
+ autoload :Entity, "ecwid_api/entity"
16
+ autoload :Api, "ecwid_api/api"
17
+
18
+ autoload :Category, "ecwid_api/category"
19
+ autoload :Order, "ecwid_api/order"
20
+ autoload :OrderItem, "ecwid_api/order_item"
21
+ autoload :Person, "ecwid_api/person"
22
+ autoload :ProductCombination, "ecwid_api/product_combination"
23
+
24
+ autoload :Product, "ecwid_api/product"
25
+ end
data/lib/ext/string.rb CHANGED
@@ -1,5 +1,13 @@
1
- class String
2
- def camel_case
3
- split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
4
- end
1
+ class String
2
+ def camel_case
3
+ split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
4
+ end unless method_defined?(:camel_case)
5
+
6
+ def underscore
7
+ self.gsub(/::/, '/').
8
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
+ tr("-", "_").
11
+ downcase
12
+ end unless method_defined?(:underscore)
5
13
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe EcwidApi::Api::Categories, faraday: true do
4
+ subject { client.categories }
5
+
6
+ describe "#all" do
7
+ it "gets all of the categories from the client" do
8
+ expect(client).to receive(:get).with("categories", hash_including({})).and_call_original
9
+ subject.all
10
+ end
11
+
12
+ it "gets sub categories" do
13
+ expect(client).to receive(:get).with("categories", hash_including(parent: 5)).and_call_original
14
+ subject.all(parent: 5)
15
+ end
16
+ end
17
+
18
+ describe "#root" do
19
+ it "gets the root level categories" do
20
+ expect(subject).to receive(:all).with(hash_including(parent: 0)).and_call_original
21
+ subject.root
22
+ end
23
+ end
24
+
25
+ describe "#find" do
26
+ it "finds a single category" do
27
+ expect(client).to receive(:get).with("categories/#{5}").and_call_original
28
+ subject.find(5)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe EcwidApi::Api::Orders, faraday: true do
4
+ subject { client.orders }
5
+
6
+ describe "#all" do
7
+ it "passes the parameters to the client" do
8
+ expect(client).to receive(:get).with("orders", hash_including(from_date: '1982-05-17'))
9
+ subject.all(from_date: '1982-05-17')
10
+ end
11
+
12
+ it "gets the proper response (see fixtures)" do
13
+ subject.all.count.should == 2
14
+ end
15
+
16
+ it "gets EcwidApi::Order types" do
17
+ subject.all.all? { |order| order.is_a?(EcwidApi::Order) }.should be_true
18
+ end
19
+ end
20
+
21
+ describe "#find" do
22
+ it "is an `EcwidApi::Order`" do
23
+ subject.find(35).is_a?(EcwidApi::Order).should be_true
24
+ end
25
+
26
+ it "is nil when not found" do
27
+ subject.find(404).should be_nil
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe EcwidApi::Api::Products, faraday: true do
4
+ subject { client.products }
5
+
6
+ describe "#all" do
7
+ it "passes any other paramters through" do
8
+ expect(client).to receive(:get).with("products", 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
+ subject.all.count.should == 5
14
+ end
15
+
16
+ it "gets the proper product (see fixture)" do
17
+ subject.all.first.sku.should == "NC53090"
18
+ end
19
+ end
20
+ end
@@ -1,39 +1,34 @@
1
- require 'spec_helper'
2
-
3
- describe EcwidApi::Category, faraday: true do
4
- let(:client) { EcwidApi::Client.new { |config| config.store_id = '12345' } }
5
- subject { EcwidApi::Category.new({"id" => 123, "parentId" => 456}, client: client) }
6
-
7
- before(:each) do
8
- faraday_client(client)
9
- end
10
-
11
- describe "#sub_categories" do
12
- it "sends the request to the CategoryApi" do
13
- expect(client.categories).to receive(:all).with(123)
14
- subject.sub_categories
15
- end
16
-
17
- it "is memoized" do
18
- subject.sub_categories
19
- expect(client.categories).to_not receive(:all)
20
- subject.sub_categories
21
- end
22
- end
23
-
24
- describe "#parent" do
25
- it "sends the request for the parent to the CategoryApi" do
26
- expect(client.categories).to receive(:find).with(456)
27
- subject.parent
28
- end
29
-
30
- context "without a parent" do
31
- subject { EcwidApi::Category.new({"id" => 123}) }
32
-
33
- it "returns nil" do
34
- expect(client.categories).to_not receive(:find)
35
- subject.parent.should be_nil
36
- end
37
- end
38
- end
1
+ require 'spec_helper'
2
+
3
+ describe EcwidApi::Category, faraday: true do
4
+ subject { EcwidApi::Category.new({"id" => 123, "parentId" => 456}, client: client) }
5
+
6
+ describe "#sub_categories" do
7
+ it "sends the request to the CategoryApi" do
8
+ expect(client.categories).to receive(:all).with(parent: 123)
9
+ subject.sub_categories
10
+ end
11
+
12
+ it "is memoized" do
13
+ subject.sub_categories
14
+ expect(client.categories).to_not receive(:all)
15
+ subject.sub_categories
16
+ end
17
+ end
18
+
19
+ describe "#parent" do
20
+ it "sends the request for the parent to the CategoryApi" do
21
+ expect(client.categories).to receive(:find).with(456)
22
+ subject.parent
23
+ end
24
+
25
+ context "without a parent" do
26
+ subject { EcwidApi::Category.new({"id" => 123}) }
27
+
28
+ it "returns nil" do
29
+ expect(client.categories).to_not receive(:find)
30
+ subject.parent.should be_nil
31
+ end
32
+ end
33
+ end
39
34
  end
data/spec/client_spec.rb CHANGED
@@ -1,49 +1,21 @@
1
- require "spec_helper"
2
-
3
- describe EcwidApi::Client do
4
- subject do
5
- EcwidApi::Client.new do |config|
6
- config.store_id = store_id
7
- end
8
- end
9
- let(:store_id) { 12345 }
10
-
11
- context "without a store_id" do
12
- it "raises an error" do
13
- expect { EcwidApi::Client.new }.to raise_error(EcwidApi::Error, /store_id/)
14
- end
15
- end
16
-
17
- describe "#url" do
18
- its(:url) { "http://app.ecwid.com/api/v1" }
19
-
20
- it "can be overridden" do
21
- client = EcwidApi::Client.new do |config|
22
- config.store_id = store_id
23
- config.url = "http://ladida.com"
24
- end
25
-
26
- client.url.should == "http://ladida.com"
27
- end
28
- end
29
-
30
- describe "#store_url" do
31
- its(:store_url) { "http://app.ecwid.com/api/v1/12345" }
32
- end
33
-
34
- describe "#get", faraday: true do
35
- before(:each) do
36
- faraday_client(subject)
37
- end
38
-
39
- it "delegates to the Faraday connection" do
40
- expect(subject.send(:connection)).to receive(:get).with("categories", parent: 1)
41
-
42
- subject.get "categories", parent: 1
43
- end
44
-
45
- it "returns a Faraday::Response" do
46
- subject.get("categories", parent: 1).is_a?(Faraday::Response).should be_true
47
- end
48
- end
1
+ require "spec_helper"
2
+
3
+ describe EcwidApi::Client do
4
+ subject { client }
5
+
6
+ describe "#store_url" do
7
+ its(:store_url) { "http://app.ecwid.com/api/v3/12345" }
8
+ end
9
+
10
+ describe "#get", faraday: true do
11
+ it "delegates to the Faraday connection" do
12
+ expect(subject.send(:connection)).to receive(:get).with("categories", parent: 1)
13
+
14
+ subject.get "categories", parent: 1
15
+ end
16
+
17
+ it "returns a Faraday::Response" do
18
+ subject.get("categories", parent: 1).is_a?(Faraday::Response).should be_true
19
+ end
20
+ end
49
21
  end
data/spec/entity_spec.rb CHANGED
@@ -1,9 +1,47 @@
1
1
  require 'spec_helper'
2
2
 
3
+ class EntitySubject < EcwidApi::Entity
4
+ self.url_root = "stuff"
5
+
6
+ ecwid_reader :id, :parentId, :type, :modify, :override
7
+ ecwid_writer :writeOnly
8
+ ecwid_accessor :theStatus
9
+
10
+ def override
11
+ super.upcase
12
+ end
13
+ end
14
+
15
+ class EntityUrlSubject < EcwidApi::Entity
16
+ ecwid_reader :id, :parentId
17
+
18
+ self.url_root = -> { "parent/#{parent_id}/and" }
19
+ end
20
+
3
21
  describe EcwidApi::Entity do
4
- let(:data) { {"id" => 123, "parentId" => 456} }
22
+ let(:data) do
23
+ {
24
+ "id" => 123,
25
+ "parentId" => 456,
26
+ "type" => "AWESOME",
27
+ "theStatus" => "YOUNG",
28
+ "hidden" => "tee hee",
29
+ "writeOnly" => "write me!",
30
+ "override" => "upcase me"
31
+ }
32
+ end
33
+
34
+ subject { EntitySubject.new(data) }
35
+
36
+ describe "::url_root" do
37
+ its(:url) { should == "stuff/123" }
38
+
39
+ context "with a proc" do
40
+ subject { EntityUrlSubject.new(data) }
41
+ its(:url) { should == "parent/456/and/123" }
42
+ end
43
+ end
5
44
 
6
- subject { EcwidApi::Entity.new(data) }
7
45
 
8
46
  describe "#[]" do
9
47
  it "gets data with a symbol key" do
@@ -13,11 +51,58 @@ describe EcwidApi::Entity do
13
51
  it "gets data with a string key" do
14
52
  subject["parentId"].should == 456
15
53
  end
54
+
55
+ it "get nil for unknown data" do
56
+ subject["whatever"].should be_nil
57
+ end
58
+
59
+ it "gets attributes not revealed by ecwid_reader or ecwid_accessor" do
60
+ subject["hidden"].should == "tee hee"
61
+ end
62
+ end
63
+
64
+ describe "overrides" do
65
+ its(:override) { should == "UPCASE ME" }
16
66
  end
17
67
 
18
- describe "#method_missing" do
19
- it "gets data with snake_cased messages" do
20
- subject.parent_id.should == 456
68
+ describe "accessors" do
69
+
70
+ describe "::ecwid_reader" do
71
+ it "makes data accessible with a snake cased method" do
72
+ subject.parent_id.should == 456
73
+ end
74
+
75
+ it "doesn't have a writer" do
76
+ expect { subject.parent_id = 4 }.to raise_error(NoMethodError)
77
+ end
78
+ end
79
+
80
+ describe "::ecwid_writer" do
81
+ it "creates a writer method" do
82
+ subject.write_only = "yee haw!"
83
+ subject["writeOnly"].should == "yee haw!"
84
+ end
85
+
86
+ it "doesn't have a reader" do
87
+ expect { subject.write_only }.to raise_error(NoMethodError)
88
+ end
89
+ end
90
+
91
+ describe "::ecwid_accessor" do
92
+ it "creates a reader and a writer" do
93
+ subject.the_status = "MATURE"
94
+ subject.the_status.should == "MATURE"
95
+ end
96
+ end
97
+
98
+ describe "without an accessor" do
99
+ it "is accessible with []" do
100
+ subject[:hidden].should == "tee hee"
101
+ end
102
+
103
+ it "doesn't have an access method" do
104
+ expect { subject.hidden }.to raise_error(NoMethodError)
105
+ end
21
106
  end
22
107
  end
23
108
  end