README.md in cistern-0.6.0 vs README.md in cistern-0.7.0
- old
+ new
@@ -11,11 +11,11 @@
This represents the remote service that you are wrapping. If the service name is 'foo' then a good name is 'Foo::Client'.
#### Requests
-Requests are enumerated using the ```request``` method and required immediately via the relative path specified via ```request_path```.
+Requests are enumerated using the `request` method and required immediately via the relative path specified via `request_path`.
class Foo::Client < Cistern::Service
request_path "my-foo/requests"
request :get_bar # require my-foo/requests/get_bar.rb
@@ -46,28 +46,28 @@
# do some mock things
end
end # Mock
end # Foo::client
-All declared requests can be listed via ```Cistern::Service#requests```.
+All declared requests can be listed via `Cistern::Service#requests`.
Foo::Client.requests # => [:get_bar, :get_bars]
#### Models and Collections
-Models and collections have declaration semantics similar to requests. Models and collections are enumerated via ```model``` and ```collection``` respectively.
+Models and collections have declaration semantics similar to requests. Models and collections are enumerated via `model` and `collection` respectively.
class Foo::Client < Cistern::Service
model_path "my-foo/models"
model :bar # require my-foo/models/bar.rb
collection :bars # require my-foo/models/bars.rb
end
#### Initialization
-Service initialization parameters are enumerated by ```requires``` and ```recognizes```. ```recognizes``` parameters are optional.
+Service initialization parameters are enumerated by `requires` and `recognizes`. `recognizes` parameters are optional.
class Foo::Client < Cistern::Service
requires :hmac_id, :hmac_secret
recognizes :url
end
@@ -79,13 +79,13 @@
# ArgumentError
Foo::Client.new(hmac_id: "1", url: "http://example.org")
Foo::Client.new(hmac_id: "1")
-#### Mocking
+### Mocking
-Cistern strongly encourages you to generate mock support for service. Mocking can be enabled using ```mock!```.
+Cistern strongly encourages you to generate mock support for service. Mocking can be enabled using `mock!`.
Foo::Client.mocking? # falsey
real = Foo::Client.new # Foo::Client::Real
Foo::Client.mock!
Foo::Client.mocking? # true
@@ -93,15 +93,103 @@
Foo::Client.unmock!
Foo::Client.mocking? # false
real.is_a?(Foo::Client::Real) # true
fake.is_a?(Foo::Client::Mock) # true
+#### Data
+A uniform interface for mock data is mixed into the `Mock` class by default.
+
+ Foo::Client.mock!
+ client = Foo::Client.new # Foo::Client::Mock
+ client.data # Cistern::Data::Hash
+ client.data["bars"] += ["x"] # ["x"]
+
+Mock data is class-level by default
+
+ Foo::Client::Mock.data["bars"] # ["x"]
+
+`reset!` dimisses the `data` object.
+
+ client.data.object_id # 70199868585600
+ client.reset!
+ client.data["bars"] # []
+ client.data.object_id # 70199868566840
+
+`clear` removes existing keys and values but keeps the same object.
+
+ client.data["bars"] += ["y"] # ["y"]
+ client.data.object_id # 70199868378300
+ client.clear
+ client.data["bars"] # []
+
+ client.data.object_id # 70199868566840
+
+* `store` and `[]=` write
+* `fetch` and `[]` read
+
+You can make the service bypass Cistern's mock data structures by simply creating a `self.data` function in your service `Mock` declaration.
+
+ class Foo::Client < Cistern::Service
+ class Mock
+ def self.data
+ @data ||= {}
+ end
+ end
+ end
+
+
+#### Requests
+
+Mock requests should be defined within the contextual `Mock` module and interact with the `data` object directly.
+
+ # lib/foo/requests/create_bar.rb
+ class Foo::Client
+ class Mock
+ def create_bar(options={})
+ id = Foo.random_hex(6)
+
+ bar = {
+ "id" => id
+ }.merge(options)
+
+ self.data[:bars][id] = bar
+
+ response(
+ :body => {"bar" => bar},
+ :status => 201,
+ :path => '/bar',
+ )
+ end
+ end # Mock
+ end # Foo::Client
+
+
+#### Storage
+
+Currently supported storage backends are:
+
+* `:hash` : `Cistern::Data::Hash` (default)
+* `:redis` : `Cistern::Data::Redis`
+
+
+Backends can be switched by using `store_in`.
+
+ # use redis with defaults
+ Patient::Mock.store_in(:redis)
+ # use redis with a specific client
+ Patient::Mock.store_in(:redis, client: Redis::Namespace.new("cistern", redis: Redis.new(host: "10.1.0.1"))
+ # use a hash
+ Patient::Mock.store_in(:hash)
+
### Model
-```connection``` represents the associated ```Foo::Client``` instance.
+* `connection` represents the associated `Foo::Client` instance.
+* `collection` represents the related collection (if applicable)
+Example
+
class Foo::Client::Bar < Cistern::Model
identity :id
attribute :flavor
attribute :keypair_id, aliases: "keypair", squash: "id"
@@ -134,10 +222,10 @@
end
end
### Collection
-```model``` tells Cistern which class is contained within the collection. ```Cistern::Collection``` inherits from ```Array``` and lazy loads where applicable.
+`model` tells Cistern which class is contained within the collection. `Cistern::Collection` inherits from `Array` and lazy loads where applicable.
class Foo::Client::Bars < Cistern::Collection
model Foo::Client::Bar