cistern 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7013053b6babdbcbc398b16bb018cc889cfd01c7
4
- data.tar.gz: 81c10f424574419b9bf216ea4a3fec9ec9327b23
3
+ metadata.gz: 21564d955c7fdeaa4da5659b23af34e3ef33a502
4
+ data.tar.gz: 16c0a32c23c662d1711ac3a1b0dd47bf78707fc5
5
5
  SHA512:
6
- metadata.gz: 9238df8c51907706409456fb98a7b1181610b7c761efee3f8d0bc427fb498d1fec4e21a1cbbab71e9619dad62aa33df0bd448b449c9706a5a5aa8bc8c1e55780
7
- data.tar.gz: a162d7a75411925f030e30070fb8ec28c1de78eaa10a897f37ebc8cdd9dee818e47b4d1233701f9061417da3b7d6292f5c39c9c5a859c9b9680ac3d3a2e6efa4
6
+ metadata.gz: a624addb8fd71e993b43550c1c3b7b6359a84ebd2f4918f46f6483836c177933a17ae2ff13267d8ab109386b5ccf6be91dccdffc85ba4aced97766b92ff5b3c8
7
+ data.tar.gz: 762a3e88c051ca923ed0a6a07a40ad09a24031df8059490715658e26f26b4277f9f92af65906cc5d303bb2b8ace09d4b5a7b31ff6f4dd9c5d00915c82e6754fd
data/.travis.yml CHANGED
@@ -1,13 +1,18 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.1.1"
4
- - "1.9.3"
5
- - "jruby-19mode"
3
+ - 2.1.1
4
+ - 1.9.3
5
+ - jruby-19mode
6
6
  bundler_args: "--without development"
7
7
  before_install:
8
- - "gem install bundler -v 1.5.2"
9
- script: "bundle exec rake --trace"
8
+ - gem install bundler -v 1.5.2
9
+ script: bundle exec rake --trace
10
10
  notifications:
11
11
  email:
12
12
  on_success: never
13
13
  on_failure: change
14
+ services:
15
+ - redis-server
16
+ env:
17
+ matrix:
18
+ secure: eiDhDgp8jBYKZVOqe891g4StnFsqRXcQwlDSnXthRSuWNMd6oFyFOo/s9aXd9lNFkaTBnSAFrUvywH1t2+H3j+cPMn/91W2s2Ldc+SxVxjrY3mWyr6NIudro/rdK7nIfIcWJFtm0teSXg/1nRPZt0qlXc4bZmvwvN3T8MvdgI2I=
data/Gemfile CHANGED
@@ -4,10 +4,13 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- gem "guard-rspec"
7
+ gem "guard-rspec", "~> 4.2", require: false
8
+ gem "guard-bundler", "~> 2.0", require: false
8
9
  gem "pry-nav"
9
10
  gem "rake"
10
11
  gem "rspec", "~> 2.0"
12
+ gem "redis-namespace"
13
+ gem "codeclimate-test-reporter", require: false
11
14
  end
12
15
 
13
16
  group :formatters do
data/Guardfile CHANGED
@@ -1,4 +1,10 @@
1
- guard 'rspec', cmd: 'bundle exec rspec' do
1
+ guard :bundler do
2
+ watch('Gemfile')
3
+ # Uncomment next line if your Gemfile contains the `gemspec' command.
4
+ watch(/^.+\.gemspec/)
5
+ end
6
+
7
+ guard 'rspec', all_on_start: true, all_after_pass: true, cmd: 'bundle exec rspec' do
2
8
  watch(%r{^spec/.+_spec\.rb$})
3
9
  watch(%r{^lib/(.+)\.rb$}) { "spec" }
4
10
  watch('spec/spec_helper.rb') { "spec" }
data/README.md CHANGED
@@ -13,7 +13,7 @@ This represents the remote service that you are wrapping. If the service name is
13
13
 
14
14
  #### Requests
15
15
 
16
- Requests are enumerated using the ```request``` method and required immediately via the relative path specified via ```request_path```.
16
+ Requests are enumerated using the `request` method and required immediately via the relative path specified via `request_path`.
17
17
 
18
18
  class Foo::Client < Cistern::Service
19
19
  request_path "my-foo/requests"
@@ -48,13 +48,13 @@ A request is method defined within the context of service and mode (Real or Mock
48
48
  end # Mock
49
49
  end # Foo::client
50
50
 
51
- All declared requests can be listed via ```Cistern::Service#requests```.
51
+ All declared requests can be listed via `Cistern::Service#requests`.
52
52
 
53
53
  Foo::Client.requests # => [:get_bar, :get_bars]
54
54
 
55
55
  #### Models and Collections
56
56
 
57
- Models and collections have declaration semantics similar to requests. Models and collections are enumerated via ```model``` and ```collection``` respectively.
57
+ Models and collections have declaration semantics similar to requests. Models and collections are enumerated via `model` and `collection` respectively.
58
58
 
59
59
  class Foo::Client < Cistern::Service
60
60
  model_path "my-foo/models"
@@ -65,7 +65,7 @@ Models and collections have declaration semantics similar to requests. Models a
65
65
 
66
66
  #### Initialization
67
67
 
68
- Service initialization parameters are enumerated by ```requires``` and ```recognizes```. ```recognizes``` parameters are optional.
68
+ Service initialization parameters are enumerated by `requires` and `recognizes`. `recognizes` parameters are optional.
69
69
 
70
70
  class Foo::Client < Cistern::Service
71
71
  requires :hmac_id, :hmac_secret
@@ -81,9 +81,9 @@ Service initialization parameters are enumerated by ```requires``` and ```recogn
81
81
  Foo::Client.new(hmac_id: "1")
82
82
 
83
83
 
84
- #### Mocking
84
+ ### Mocking
85
85
 
86
- Cistern strongly encourages you to generate mock support for service. Mocking can be enabled using ```mock!```.
86
+ Cistern strongly encourages you to generate mock support for service. Mocking can be enabled using `mock!`.
87
87
 
88
88
  Foo::Client.mocking? # falsey
89
89
  real = Foo::Client.new # Foo::Client::Real
@@ -95,10 +95,98 @@ Cistern strongly encourages you to generate mock support for service. Mocking ca
95
95
  real.is_a?(Foo::Client::Real) # true
96
96
  fake.is_a?(Foo::Client::Mock) # true
97
97
 
98
+ #### Data
99
+
100
+ A uniform interface for mock data is mixed into the `Mock` class by default.
101
+
102
+ Foo::Client.mock!
103
+ client = Foo::Client.new # Foo::Client::Mock
104
+ client.data # Cistern::Data::Hash
105
+ client.data["bars"] += ["x"] # ["x"]
106
+
107
+ Mock data is class-level by default
108
+
109
+ Foo::Client::Mock.data["bars"] # ["x"]
110
+
111
+ `reset!` dimisses the `data` object.
112
+
113
+ client.data.object_id # 70199868585600
114
+ client.reset!
115
+ client.data["bars"] # []
116
+ client.data.object_id # 70199868566840
117
+
118
+ `clear` removes existing keys and values but keeps the same object.
119
+
120
+ client.data["bars"] += ["y"] # ["y"]
121
+ client.data.object_id # 70199868378300
122
+ client.clear
123
+ client.data["bars"] # []
124
+
125
+ client.data.object_id # 70199868566840
126
+
127
+ * `store` and `[]=` write
128
+ * `fetch` and `[]` read
129
+
130
+ You can make the service bypass Cistern's mock data structures by simply creating a `self.data` function in your service `Mock` declaration.
131
+
132
+ class Foo::Client < Cistern::Service
133
+ class Mock
134
+ def self.data
135
+ @data ||= {}
136
+ end
137
+ end
138
+ end
139
+
140
+
141
+ #### Requests
142
+
143
+ Mock requests should be defined within the contextual `Mock` module and interact with the `data` object directly.
144
+
145
+ # lib/foo/requests/create_bar.rb
146
+ class Foo::Client
147
+ class Mock
148
+ def create_bar(options={})
149
+ id = Foo.random_hex(6)
150
+
151
+ bar = {
152
+ "id" => id
153
+ }.merge(options)
154
+
155
+ self.data[:bars][id] = bar
156
+
157
+ response(
158
+ :body => {"bar" => bar},
159
+ :status => 201,
160
+ :path => '/bar',
161
+ )
162
+ end
163
+ end # Mock
164
+ end # Foo::Client
165
+
166
+
167
+ #### Storage
168
+
169
+ Currently supported storage backends are:
170
+
171
+ * `:hash` : `Cistern::Data::Hash` (default)
172
+ * `:redis` : `Cistern::Data::Redis`
173
+
174
+
175
+ Backends can be switched by using `store_in`.
176
+
177
+ # use redis with defaults
178
+ Patient::Mock.store_in(:redis)
179
+ # use redis with a specific client
180
+ Patient::Mock.store_in(:redis, client: Redis::Namespace.new("cistern", redis: Redis.new(host: "10.1.0.1"))
181
+ # use a hash
182
+ Patient::Mock.store_in(:hash)
98
183
 
99
184
  ### Model
100
185
 
101
- ```connection``` represents the associated ```Foo::Client``` instance.
186
+ * `connection` represents the associated `Foo::Client` instance.
187
+ * `collection` represents the related collection (if applicable)
188
+
189
+ Example
102
190
 
103
191
  class Foo::Client::Bar < Cistern::Model
104
192
  identity :id
@@ -136,7 +224,7 @@ Cistern strongly encourages you to generate mock support for service. Mocking ca
136
224
 
137
225
  ### Collection
138
226
 
139
- ```model``` tells Cistern which class is contained within the collection. ```Cistern::Collection``` inherits from ```Array``` and lazy loads where applicable.
227
+ `model` tells Cistern which class is contained within the collection. `Cistern::Collection` inherits from `Array` and lazy loads where applicable.
140
228
 
141
229
  class Foo::Client::Bars < Cistern::Collection
142
230
 
@@ -0,0 +1,38 @@
1
+ class Cistern::Data::Hash
2
+ Cistern::Data.backends[:hash] = self
3
+
4
+ def initialize(options={}, &default)
5
+ @hash = Hash.new
6
+ @default = default
7
+ end
8
+
9
+ def clear
10
+ hash.clear
11
+ end
12
+
13
+ def store(key, *args)
14
+ assign_default(key)
15
+
16
+ hash.store(key, *args)
17
+ end
18
+
19
+ alias []= store
20
+
21
+ def fetch(key, *args)
22
+ assign_default(key)
23
+
24
+ hash.fetch(key, *args)
25
+ end
26
+
27
+ alias [] fetch
28
+
29
+ protected
30
+
31
+ attr_reader :hash, :default
32
+
33
+ def assign_default(key)
34
+ if !hash.key?(key) && default
35
+ default.call(hash, key)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ class Cistern::Data::Redis
2
+ Cistern::Data.backends[:redis] = self
3
+
4
+ def self.marshal
5
+ @marshal ||= begin
6
+ require 'multi_json'
7
+ MultiJson
8
+ rescue LoadError
9
+ require 'json'
10
+ ::JSON
11
+ end
12
+ end
13
+
14
+ def self.marshal=(marshal)
15
+ @marshal = marshal
16
+ end
17
+
18
+ def initialize(options={}, &block)
19
+ @client = options[:client] || ::Redis.new
20
+ @default = block
21
+ end
22
+
23
+ def clear
24
+ unless (keys = client.keys("*")).empty?
25
+ client.del(*keys)
26
+ end
27
+ end
28
+
29
+ def store(key, value, *args)
30
+ assign_default(key)
31
+
32
+ client.set(key, Cistern::Data::Redis.marshal.dump(value), *args)
33
+ end
34
+
35
+ alias []= store
36
+
37
+ def fetch(key, *args)
38
+ assign_default(key)
39
+
40
+ Cistern::Data::Redis.marshal.load(client.get(key, *args))
41
+ end
42
+
43
+ alias [] fetch
44
+
45
+ protected
46
+
47
+ attr_reader :client, :default
48
+
49
+ def assign_default(key)
50
+ if client.keys(key).empty? && default
51
+ default.call(client, key)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ module Cistern::Data
2
+ def self.extended(klass)
3
+ klass.send(:extend, ClassMethods)
4
+ klass.send(:include, InstanceMethods)
5
+ end
6
+
7
+ def self.backends
8
+ @backends ||= {}
9
+ end
10
+
11
+ module ClassMethods
12
+ def data
13
+ @data ||= Cistern::Data.backends[storage].new(@options || {}) { |d,k| d[k] = [] }
14
+ end
15
+
16
+ def reset!
17
+ clear!
18
+ @data = nil
19
+ end
20
+
21
+ def clear!
22
+ self.data.clear
23
+ end
24
+
25
+ def store_in(storage, options)
26
+ @storage = storage
27
+ @options = options
28
+ @data = nil
29
+ end
30
+
31
+ def storage
32
+ @storage ||= :hash
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ def data
38
+ self.class.data
39
+ end
40
+
41
+ def reset!
42
+ self.class.reset!
43
+ end
44
+ end
45
+ end
@@ -34,9 +34,13 @@ class Cistern::Service
34
34
  end
35
35
 
36
36
  class Real
37
+ def initialize(options={})
38
+ end
37
39
  end
38
40
 
39
41
  class Mock
42
+ def initialize(options={})
43
+ end
40
44
  end
41
45
  EOS
42
46
 
@@ -44,6 +48,7 @@ class Cistern::Service
44
48
 
45
49
  klass::Mock.send(:include, klass::Collections)
46
50
  klass::Mock.send(:extend, Cistern::WaitFor)
51
+ klass::Mock.send(:extend, Cistern::Data)
47
52
  klass::Mock.timeout_error = klass::Timeout
48
53
  klass::Real.send(:include, klass::Collections)
49
54
  klass::Real.send(:extend, Cistern::WaitFor)
@@ -108,12 +113,15 @@ class Cistern::Service
108
113
 
109
114
  def validate_options(options={})
110
115
  required_options = Cistern::Hash.slice(options, *required_arguments)
116
+
111
117
  missing_required_options = required_arguments - required_options.keys
118
+
112
119
  unless missing_required_options.empty?
113
120
  raise "Missing required options: #{missing_required_options.inspect}"
114
121
  end
115
- recognized_options = Cistern::Hash.slice(options, *(required_arguments + recognized_arguments))
122
+
116
123
  unrecognized_options = options.keys - (required_arguments + recognized_arguments)
124
+
117
125
  unless unrecognized_options.empty?
118
126
  raise "Unrecognized options: #{unrecognized_options.inspect}"
119
127
  end
@@ -132,7 +140,10 @@ class Cistern::Service
132
140
  EOS
133
141
  end
134
142
  requests.each do |request|
135
- require File.join(@request_path, request.to_s)
143
+ unless service::Real.method_defined?(request.to_s)
144
+ require File.join(@request_path, request.to_s)
145
+ end
146
+
136
147
  if service::Mock.method_defined?(request)
137
148
  mocked_requests << request
138
149
  else
@@ -1,3 +1,3 @@
1
1
  module Cistern
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
data/lib/cistern.rb CHANGED
@@ -16,10 +16,13 @@ module Cistern
16
16
  require 'cistern/model'
17
17
  require 'cistern/service'
18
18
  require 'cistern/singular'
19
+ require 'cistern/data'
20
+ require 'cistern/data/hash'
21
+ require 'cistern/data/redis'
19
22
 
20
23
  extend WaitFor
21
24
 
22
- autoload :Formatter, 'cistern/formatter'
25
+ require 'cistern/formatter'
23
26
 
24
27
  def self.formatter=(formatter); @formatter = formatter; end
25
28
 
data/spec/cistern_spec.rb CHANGED
@@ -26,17 +26,17 @@ describe "#inspect" do
26
26
  it "should use formatador" do
27
27
  Cistern.formatter = Cistern::Formatter::Formatador
28
28
 
29
- Inspector.new(id: 1, name: "name").inspect.should == %q{ <Inspector
29
+ expect(Inspector.new(id: 1, name: "name").inspect).to eq(%q{ <Inspector
30
30
  id=1,
31
31
  name="name"
32
- >}
32
+ >})
33
33
  end
34
34
  end
35
35
 
36
36
  describe "Cistern::Collection" do
37
37
  it "should use formatador" do
38
38
  Cistern.formatter = Cistern::Formatter::Formatador
39
- Inspectors.new.all.inspect.should == %q{ <Inspectors
39
+ expect(Inspectors.new.all.inspect).to eq(%q{ <Inspectors
40
40
  [
41
41
  <Inspector
42
42
  id=1,
@@ -47,12 +47,12 @@ describe "#inspect" do
47
47
  name="4"
48
48
  >
49
49
  ]
50
- >}
50
+ >})
51
51
  end
52
52
 
53
53
  it "should use awesome_print" do
54
54
  Cistern.formatter = Cistern::Formatter::AwesomePrint
55
- Inspectors.new.all.inspect.should match(/Inspectors\s+{.*}$/m) # close enough
55
+ expect(Inspectors.new.all.inspect).to match(/Inspectors\s+{.*}$/m) # close enough
56
56
  end
57
57
  end
58
58
  end
@@ -15,33 +15,33 @@ describe "Cistern::Collection" do
15
15
 
16
16
  it "should give to_s" do
17
17
  collection = SampleCollection.new
18
- collection.to_s.should_not eq "[]"
19
- collection.to_s.gsub(/:[^>]*/,'').should == collection.all.to_s.gsub(/:[^>]*/,'')
18
+ expect(collection.to_s).not_to eq "[]"
19
+ expect(collection.to_s.gsub(/:[^>]*/,'')).to eq(collection.all.to_s.gsub(/:[^>]*/,''))
20
20
  end
21
21
 
22
22
  it "should give size and count" do
23
- SampleCollection.new.size.should == 3
24
- SampleCollection.new.count.should == 3
23
+ expect(SampleCollection.new.size).to eq(3)
24
+ expect(SampleCollection.new.count).to eq(3)
25
25
  end
26
26
 
27
27
  it "should give first" do
28
- SampleCollection.new.first.should == SampleCollectionModel.new(id: 1)
28
+ expect(SampleCollection.new.first).to eq(SampleCollectionModel.new(id: 1))
29
29
  end
30
30
 
31
31
  it "should give last" do
32
- SampleCollection.new.last.should == SampleCollectionModel.new(id: 2)
32
+ expect(SampleCollection.new.last).to eq(SampleCollectionModel.new(id: 2))
33
33
  end
34
34
 
35
35
  it "should reject" do
36
- SampleCollection.new.reject{|m| m.id == 2}.should == [SampleCollectionModel.new(id: 1), SampleCollectionModel.new(id: 3)]
36
+ expect(SampleCollection.new.reject{|m| m.id == 2}).to eq([SampleCollectionModel.new(id: 1), SampleCollectionModel.new(id: 3)])
37
37
  end
38
38
 
39
39
  it "should select" do
40
- SampleCollection.new.select{|m| m.id == 2}.should == [SampleCollectionModel.new(id: 2)]
40
+ expect(SampleCollection.new.select{|m| m.id == 2}).to eq([SampleCollectionModel.new(id: 2)])
41
41
  end
42
42
 
43
43
  it "should slice" do
44
- SampleCollection.new.slice(0,2).should == [SampleCollectionModel.new(id: 1), SampleCollectionModel.new(id: 3, name: "tom")]
44
+ expect(SampleCollection.new.slice(0,2)).to eq([SampleCollectionModel.new(id: 1), SampleCollectionModel.new(id: 3, name: "tom")])
45
45
  end
46
46
 
47
47
  it "should ==" do
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'mock data' do
4
+ class Patient < Cistern::Service
5
+ request :diagnosis
6
+ request :treat
7
+
8
+ class Real
9
+ def diagnosis(options={})
10
+ end
11
+
12
+ def treat(options={})
13
+ end
14
+ end
15
+
16
+ class Mock
17
+ def diagnosis(diagnosis)
18
+ #self.data[:diagnosis] << rand(2) == 0 ? "sick" : "healthy"
19
+ self.data.store(:diagnosis, self.data.fetch(:diagnosis) + [diagnosis])
20
+ end
21
+
22
+ def treat(treatment)
23
+ self.data[:treatments] += [treatment]
24
+ end
25
+ end
26
+ end
27
+
28
+ shared_examples "mock_data#backend" do |backend, options|
29
+ it "should store mock data" do
30
+ Patient.mock!
31
+ Patient::Mock.store_in(backend, options)
32
+ Patient.reset!
33
+
34
+ p = Patient.new
35
+ p.diagnosis("sick")
36
+ expect(p.data[:diagnosis]).to eq(["sick"])
37
+
38
+ p.reset!
39
+
40
+ expect(p.data[:diagnosis]).to eq([])
41
+
42
+ p.treat("healthy")
43
+ expect(p.data[:treatments]).to eq(["healthy"])
44
+
45
+ Patient.reset!
46
+
47
+ expect(p.data[:treatments]).to eq([])
48
+ end
49
+
50
+ end
51
+
52
+ context "with a storage backend" do
53
+ describe "Cistern::Data::Hash" do
54
+ include_examples "mock_data#backend", :hash
55
+ end
56
+
57
+ describe "Cistern::Data::Redis" do
58
+ include_examples "mock_data#backend", :redis
59
+
60
+ context "with an explicit client" do
61
+ before(:each) {
62
+ @other = Redis::Namespace.new("other_cistern", Redis.new)
63
+ @other.set("x", "y")
64
+ }
65
+
66
+ include_examples "mock_data#backend", :redis, client: Redis::Namespace.new("cistern", Redis.new)
67
+
68
+ after(:each) {
69
+ expect(@other.get("x")).to eq("y")
70
+ @other.del("x")
71
+ }
72
+ end
73
+ end
74
+ end
75
+ end
data/spec/model_spec.rb CHANGED
@@ -12,11 +12,11 @@ describe "Cistern::Model" do
12
12
  model = DupSpec.new(id: 1, name: "string", properties: {value: "something", else: "what"})
13
13
  duplicate = model.dup
14
14
 
15
- duplicate.should == model
16
- duplicate.should_not eql model
15
+ expect(duplicate).to eq(model)
16
+ expect(duplicate).not_to eql model
17
17
 
18
18
  model.name= "anotherstring"
19
- duplicate.name.should == "string"
19
+ expect(duplicate.name).to eq("string")
20
20
  end
21
21
 
22
22
  context "attribute parsing" do
@@ -48,95 +48,95 @@ describe "Cistern::Model" do
48
48
  end
49
49
 
50
50
  it "should parse string" do
51
- TypeSpec.new(name: 1).name.should == "1"
51
+ expect(TypeSpec.new(name: 1).name).to eq("1")
52
52
  end
53
53
 
54
54
  it "should parse time" do
55
55
  time = Time.now
56
56
  created_at = TypeSpec.new(created_at: time.to_s).created_at
57
- created_at.should be_a(Time)
58
- created_at.to_i.should == time.to_i
57
+ expect(created_at).to be_a(Time)
58
+ expect(created_at.to_i).to eq(time.to_i)
59
59
  end
60
60
 
61
61
  it "should parse boolean" do
62
- TypeSpec.new(flag: "false").flag.should be_false
63
- TypeSpec.new(flag: "true").flag.should be_true
64
- TypeSpec.new(flag: false).flag.should be_false
65
- TypeSpec.new(flag: true).flag.should be_true
66
- TypeSpec.new(flag: "0").flag.should be_false
67
- TypeSpec.new(flag: "1").flag.should be_true
68
- TypeSpec.new(flag: 0).flag.should be_false
69
- TypeSpec.new(flag: 1).flag.should be_true
70
- TypeSpec.new(flag: false).should_not be_flag
71
- TypeSpec.new(flag: true).should be_flag
62
+ expect(TypeSpec.new(flag: "false").flag).to be_false
63
+ expect(TypeSpec.new(flag: "true").flag).to be_true
64
+ expect(TypeSpec.new(flag: false).flag).to be_false
65
+ expect(TypeSpec.new(flag: true).flag).to be_true
66
+ expect(TypeSpec.new(flag: "0").flag).to be_false
67
+ expect(TypeSpec.new(flag: "1").flag).to be_true
68
+ expect(TypeSpec.new(flag: 0).flag).to be_false
69
+ expect(TypeSpec.new(flag: 1).flag).to be_true
70
+ expect(TypeSpec.new(flag: false)).not_to be_flag
71
+ expect(TypeSpec.new(flag: true)).to be_flag
72
72
  end
73
73
 
74
74
  it "should parse an array" do
75
- TypeSpec.new(list: []).list.should == []
76
- TypeSpec.new(list: "item").list.should == ["item"]
75
+ expect(TypeSpec.new(list: []).list).to eq([])
76
+ expect(TypeSpec.new(list: "item").list).to eq(["item"])
77
77
  end
78
78
 
79
79
  it "should parse a float" do
80
- TypeSpec.new(floater: "0.01").floater.should == 0.01
81
- TypeSpec.new(floater: 0.01).floater.should == 0.01
80
+ expect(TypeSpec.new(floater: "0.01").floater).to eq(0.01)
81
+ expect(TypeSpec.new(floater: 0.01).floater).to eq(0.01)
82
82
  end
83
83
 
84
84
  it "should use custom parser" do
85
- TypeSpec.new(custom: "15").custom.should == "X!15"
85
+ expect(TypeSpec.new(custom: "15").custom).to eq("X!15")
86
86
  end
87
87
 
88
88
  it "should squash, cast, alias an attribute and keep a vanilla reference" do
89
89
  # vanilla squash
90
- TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).butternut_type.should == "fred"
91
- TypeSpec.new({"squash" => {"id" => "12", "type" => nil}}).butternut_type.should be_nil
92
- TypeSpec.new({"squash" => nil}).butternut_type.should be_nil
90
+ expect(TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).butternut_type).to eq("fred")
91
+ expect(TypeSpec.new({"squash" => {"id" => "12", "type" => nil}}).butternut_type).to be_nil
92
+ expect(TypeSpec.new({"squash" => nil}).butternut_type).to be_nil
93
93
 
94
94
  # composite processors: squash and cast
95
- TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).butternut_id.should == 12
96
- TypeSpec.new({"squash" => {"id" => nil, "type" => "fred"}}).butternut_id.should be_nil
97
- TypeSpec.new({"squash" => {"type" => "fred"}}).butternut_id.should be_nil
95
+ expect(TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).butternut_id).to eq(12)
96
+ expect(TypeSpec.new({"squash" => {"id" => nil, "type" => "fred"}}).butternut_id).to be_nil
97
+ expect(TypeSpec.new({"squash" => {"type" => "fred"}}).butternut_id).to be_nil
98
98
 
99
99
  # override intermediate processing
100
- TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).squash.should == {"id" => "12", "type" => "fred"}
100
+ expect(TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).squash).to eq({"id" => "12", "type" => "fred"})
101
101
 
102
102
  # alias of override
103
- TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).vegetable.should == {"id" => "12", "type" => "fred"}
103
+ expect(TypeSpec.new({"squash" => {"id" => "12", "type" => "fred"}}).vegetable).to eq({"id" => "12", "type" => "fred"})
104
104
  end
105
105
 
106
106
  it "should set a default value" do
107
- TypeSpec.new.default.should == "im a squash"
107
+ expect(TypeSpec.new.default).to eq("im a squash")
108
108
  end
109
109
 
110
110
  it "should override a default value" do
111
- TypeSpec.new(default: "now im a different squash").default.should == "now im a different squash"
111
+ expect(TypeSpec.new(default: "now im a different squash").default).to eq("now im a different squash")
112
112
  end
113
113
 
114
114
  context "allowing the same alias for multiple attributes" do
115
115
  it "should do so when not squashing" do
116
116
  type_spec = TypeSpec.new({"nested" => "bamboo"})
117
- type_spec.same_alias_1.should == "bamboo"
118
- type_spec.same_alias_2.should == "bamboo"
117
+ expect(type_spec.same_alias_1).to eq("bamboo")
118
+ expect(type_spec.same_alias_2).to eq("bamboo")
119
119
  end
120
120
 
121
121
  it "should do so when squashing" do
122
122
  type_spec = TypeSpec.new({"nested" => {"attr_1" => "bamboo", "attr_2" => "panda"}})
123
- type_spec.same_alias_squashed_1.should == "bamboo"
124
- type_spec.same_alias_squashed_2.should == "panda"
125
- type_spec.same_alias_squashed_3.should == "panda"
123
+ expect(type_spec.same_alias_squashed_1).to eq("bamboo")
124
+ expect(type_spec.same_alias_squashed_2).to eq("panda")
125
+ expect(type_spec.same_alias_squashed_3).to eq("panda")
126
126
  end
127
127
  end
128
128
 
129
129
  it "should slice out unaccounted for attributes" do
130
- TypeSpec.new({"something" => {"id" => "12"}}).attributes.keys.should_not include("something")
130
+ expect(TypeSpec.new({"something" => {"id" => "12"}}).attributes.keys).not_to include("something")
131
131
  end
132
132
 
133
133
  describe "#requires" do
134
134
  it "should raise if attribute not provided" do
135
- lambda { TypeSpec.new({"connection" => "fake", "something" => {"id" => "12"}}).save }.should raise_exception(ArgumentError)
135
+ expect { TypeSpec.new({"connection" => "fake", "something" => {"id" => "12"}}).save }.to raise_exception(ArgumentError)
136
136
  end
137
137
 
138
138
  it "should raise if attribute is provided and is nil" do
139
- lambda { TypeSpec.new({"connection" => "fake", "custom" => nil}).save }.should raise_exception(ArgumentError)
139
+ expect { TypeSpec.new({"connection" => "fake", "custom" => nil}).save }.to raise_exception(ArgumentError)
140
140
  end
141
141
  end
142
142
  end
@@ -153,25 +153,25 @@ describe "Cistern::Model" do
153
153
 
154
154
  before(:each) do
155
155
  CoverageSpec.attributes[:used][:coverage_hits] = 0
156
- obj.used.should == "foo" # once
157
- obj.used.should == "foo" # twice
156
+ expect(obj.used).to eq("foo") # once
157
+ expect(obj.used).to eq("foo") # twice
158
158
  end
159
159
 
160
160
  it "should store the file path where the attribute was defined" do
161
- CoverageSpec.attributes[:used][:coverage_file].should == __FILE__
162
- CoverageSpec.attributes[:unused][:coverage_file].should == __FILE__
161
+ expect(CoverageSpec.attributes[:used][:coverage_file]).to eq(__FILE__)
162
+ expect(CoverageSpec.attributes[:unused][:coverage_file]).to eq(__FILE__)
163
163
  end
164
164
 
165
165
  it "should store the line number where the attribute was defined" do
166
166
  src_lines = File.read(__FILE__).lines
167
167
 
168
- src_lines[CoverageSpec.attributes[:used][:coverage_line] - 1].should match(/attribute :used/)
169
- src_lines[CoverageSpec.attributes[:unused][:coverage_line] - 1].should match(/attribute :unused/)
168
+ expect(src_lines[CoverageSpec.attributes[:used][:coverage_line] - 1]).to match(/attribute :used/)
169
+ expect(src_lines[CoverageSpec.attributes[:unused][:coverage_line] - 1]).to match(/attribute :unused/)
170
170
  end
171
171
 
172
172
  it "should store how many times an attribute's reader is called" do
173
- CoverageSpec.attributes[:used][:coverage_hits].should == 2
174
- CoverageSpec.attributes[:unused][:coverage_hits].should == 0
173
+ expect(CoverageSpec.attributes[:used][:coverage_hits]).to eq(2)
174
+ expect(CoverageSpec.attributes[:unused][:coverage_hits]).to eq(0)
175
175
  end
176
176
  end
177
177
  end
@@ -16,13 +16,13 @@ describe "Cistern::Singular" do
16
16
  end
17
17
 
18
18
  it "should work" do
19
- SampleSingular.new(connection: :fake).name.should == "amazing"
19
+ expect(SampleSingular.new(connection: :fake).name).to eq("amazing")
20
20
  end
21
21
 
22
22
  it "should reload" do
23
23
  singular = SampleSingular.new(connection: :fake)
24
24
  old_count = singular.count
25
- singular.count.should == old_count
26
- singular.reload.count.should > old_count
25
+ expect(singular.count).to eq(old_count)
26
+ expect(singular.reload.count).to be > old_count
27
27
  end
28
28
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,8 @@
1
+ if ENV["TRAVIS"]
2
+ require "codeclimate-test-reporter"
3
+ CodeClimate::TestReporter.start
4
+ end
5
+
1
6
  require File.expand_path('../../lib/cistern', __FILE__)
2
7
 
3
8
  Bundler.require(:test)
@@ -26,13 +26,13 @@ end
26
26
 
27
27
  describe 'Cistern#wait_for' do
28
28
  it "should return false if timeout exceeded" do
29
- Cistern.wait_for(0, 0) { false }.should be_false
29
+ expect(Cistern.wait_for(0, 0) { false }).to be_false
30
30
  end
31
31
  end
32
32
 
33
33
  describe 'Cistern#wait_for!' do
34
34
  it "should raise if timeout exceeded" do
35
- lambda { Cistern.wait_for!(0, 0) { false } }.should raise_exception(Cistern::Timeout)
35
+ expect { Cistern.wait_for!(0, 0) { false } }.to raise_exception(Cistern::Timeout)
36
36
  end
37
37
  end
38
38
 
@@ -41,7 +41,7 @@ describe 'Cistern::Model#wait_for!' do
41
41
  let(:model) { service.wait_for_models.new(identity: 1) }
42
42
 
43
43
  it "should raise if timeout exceeded" do
44
- lambda { model.wait_for!(0, 0) { false } }.should raise_exception(WaitForService::Timeout)
44
+ expect { model.wait_for!(0, 0) { false } }.to raise_exception(WaitForService::Timeout)
45
45
  end
46
46
  end
47
47
 
@@ -57,9 +57,9 @@ describe "WaitForModel#timeout" do
57
57
  elapsed = 0
58
58
 
59
59
  timeout(2) do
60
- lambda do
60
+ expect do
61
61
  model.wait_for! { sleep(0.2); elapsed += 0.2; elapsed > 0.2 }
62
- end.should raise_exception(WaitForService::Timeout)
62
+ end.to raise_exception(WaitForService::Timeout)
63
63
  end
64
64
  end
65
65
 
@@ -70,9 +70,9 @@ describe "WaitForModel#timeout" do
70
70
  elapsed = 0
71
71
 
72
72
  timeout(2) do
73
- lambda do
73
+ expect do
74
74
  model.wait_for!(0.1) { sleep(0.2); elapsed += 0.2; elapsed > 0.2 }
75
- end.should raise_exception(WaitForService::Timeout)
75
+ end.to raise_exception(WaitForService::Timeout)
76
76
  end
77
77
  end
78
78
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cistern
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Lane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-29 00:00:00.000000000 Z
11
+ date: 2014-05-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: API client framework extracted from Fog
14
14
  email:
@@ -30,6 +30,9 @@ files:
30
30
  - lib/cistern/attributes.rb
31
31
  - lib/cistern/collection.rb
32
32
  - lib/cistern/coverage.rb
33
+ - lib/cistern/data.rb
34
+ - lib/cistern/data/hash.rb
35
+ - lib/cistern/data/redis.rb
33
36
  - lib/cistern/formatter.rb
34
37
  - lib/cistern/formatter/awesome_print.rb
35
38
  - lib/cistern/formatter/formatador.rb
@@ -43,6 +46,7 @@ files:
43
46
  - lib/cistern/wait_for.rb
44
47
  - spec/cistern_spec.rb
45
48
  - spec/collection_spec.rb
49
+ - spec/mock_data_spec.rb
46
50
  - spec/model_spec.rb
47
51
  - spec/singular_spec.rb
48
52
  - spec/spec_helper.rb
@@ -74,6 +78,7 @@ summary: API client framework
74
78
  test_files:
75
79
  - spec/cistern_spec.rb
76
80
  - spec/collection_spec.rb
81
+ - spec/mock_data_spec.rb
77
82
  - spec/model_spec.rb
78
83
  - spec/singular_spec.rb
79
84
  - spec/spec_helper.rb