modis 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module Modis
2
- VERSION = '1.3.0'
2
+ VERSION = '1.4.0'
3
3
  end
@@ -1,17 +1,23 @@
1
1
  begin
2
- require 'cane/rake_task'
2
+ if ENV['TRAVIS']
3
+ namespace :spec do
4
+ task cane: ['spec']
5
+ end
6
+ else
7
+ require 'cane/rake_task'
3
8
 
4
- desc 'Run cane to check quality metrics'
5
- Cane::RakeTask.new(:cane_quality) do |cane|
6
- cane.add_threshold 'coverage/covered_percent', :>=, 99
7
- cane.no_style = false
8
- cane.style_measure = 1000
9
- cane.no_doc = true
10
- cane.abc_max = 25
11
- end
9
+ desc 'Run cane to check quality metrics'
10
+ Cane::RakeTask.new(:cane_quality) do |cane|
11
+ cane.add_threshold 'coverage/covered_percent', :>=, 99
12
+ cane.no_style = false
13
+ cane.style_measure = 1000
14
+ cane.no_doc = true
15
+ cane.abc_max = 25
16
+ end
12
17
 
13
- namespace :spec do
14
- task cane: %w(spec cane_quality)
18
+ namespace :spec do
19
+ task cane: %w(spec cane_quality)
20
+ end
15
21
  end
16
22
  rescue LoadError
17
23
  warn "cane not available."
@@ -23,7 +29,8 @@ end
23
29
 
24
30
  begin
25
31
  require 'rubocop/rake_task'
26
- RuboCop::RakeTask.new
32
+ t = RuboCop::RakeTask.new
33
+ t.options << '-D'
27
34
  rescue LoadError
28
35
  warn 'rubocop not available.'
29
36
  task rubocop: ['spec']
@@ -17,8 +17,16 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_dependency 'activemodel', '>= 3.0'
21
- gem.add_dependency 'activesupport', '>= 3.0'
22
- gem.add_dependency 'redis', '>= 3.0'
23
- gem.add_dependency 'connection_pool', '>= 2'
20
+ gem.add_runtime_dependency 'activemodel', '>= 3.0'
21
+ gem.add_runtime_dependency 'activesupport', '>= 3.0'
22
+ gem.add_runtime_dependency 'redis', '>= 3.0'
23
+ gem.add_runtime_dependency 'hiredis', '>= 0.5'
24
+ gem.add_runtime_dependency 'connection_pool', '>= 2'
25
+
26
+ if defined? JRUBY_VERSION
27
+ gem.platform = 'java'
28
+ gem.add_runtime_dependency 'msgpack-jruby'
29
+ else
30
+ gem.add_runtime_dependency 'msgpack', '>= 0.5'
31
+ end
24
32
  end
@@ -93,12 +93,12 @@ describe Modis::Attribute do
93
93
 
94
94
  describe ':timestamp type' do
95
95
  it 'is coerced' do
96
- now = Time.now
97
- model.created_at = now
96
+ time = Time.new(2014, 12, 11, 17, 31, 50, '-02:00')
97
+ model.created_at = time
98
98
  model.save!
99
99
  found = AttributeSpec::MockModel.find(model.id)
100
100
  expect(found.created_at).to be_kind_of(Time)
101
- expect(found.created_at.to_s).to eq(now.to_s)
101
+ expect(found.created_at.to_s).to eq(time.to_s)
102
102
  end
103
103
  end
104
104
 
@@ -144,7 +144,7 @@ describe Modis::Attribute do
144
144
  model.hash = { foo: :bar }
145
145
  model.save!
146
146
  found = AttributeSpec::MockModel.find(model.id)
147
- expect(found.hash).to eq(foo: :bar)
147
+ expect(found.hash).to eq('foo' => 'bar')
148
148
  end
149
149
 
150
150
  it 'raises an error when assigned another type' do
@@ -157,7 +157,7 @@ describe Modis::Attribute do
157
157
  model.string_or_hash = { foo: :bar }
158
158
  model.save!
159
159
  found = AttributeSpec::MockModel.find(model.id)
160
- expect(found.string_or_hash).to eq(foo: :bar)
160
+ expect(found.string_or_hash).to eq('foo' => 'bar')
161
161
 
162
162
  model.string_or_hash = 'test'
163
163
  model.save!
@@ -7,12 +7,15 @@ module FindersSpec
7
7
 
8
8
  attribute :name, :string
9
9
  attribute :age, :integer
10
+ attribute :parent_default, :string, default: 'omg'
10
11
  end
11
12
 
12
13
  class Consumer < User
14
+ attribute :consumed, :boolean
13
15
  end
14
16
 
15
17
  class Producer < User
18
+ attribute :child_default, :string, default: 'derp'
16
19
  end
17
20
  end
18
21
 
@@ -26,10 +29,22 @@ describe Modis::Finder do
26
29
  expect(found.age).to eq(model.age)
27
30
  end
28
31
 
29
- it 'raises an error if the record could not be found' do
32
+ it 'finds multiple by ID' do
33
+ model1 = FindersSpec::User.create!(name: 'Ian', age: 28)
34
+ model2 = FindersSpec::User.create!(name: 'Tanya', age: 32)
35
+ model3 = FindersSpec::User.create!(name: 'Kyle', age: 35)
36
+ models = FindersSpec::User.find(model1.id, model2.id, model3.id)
37
+ expect(models).to eq([model1, model2, model3])
38
+ end
39
+
40
+ it 'raises an error a record could not be found' do
30
41
  expect do
31
42
  FindersSpec::User.find(model.id + 1)
32
43
  end.to raise_error(Modis::RecordNotFound, "Couldn't find FindersSpec::User with id=#{model.id + 1}")
44
+
45
+ expect do
46
+ FindersSpec::User.find(model.id, model.id + 1)
47
+ end.to raise_error(Modis::RecordNotFound, "Couldn't find FindersSpec::User with id=#{model.id + 1}")
33
48
  end
34
49
 
35
50
  it 'does not flag an attribute as dirty on a found instance' do
@@ -79,5 +94,16 @@ describe Modis::Finder do
79
94
  expect(FindersSpec::User.find(kyle.id)).to be_kind_of(FindersSpec::Consumer)
80
95
  expect(FindersSpec::User.find(tanya.id)).to be_kind_of(FindersSpec::Producer)
81
96
  end
97
+
98
+ it 'inherits attributes from the parent' do
99
+ consumer = FindersSpec::Consumer.create!(name: 'Kyle', consumed: true)
100
+ expect(consumer.attributes.keys.sort).to eq(%w(consumed id name parent_default type))
101
+ end
102
+
103
+ it 'inherits default attribute values from the parent' do
104
+ producer = FindersSpec::Producer.create!(name: 'Kyle')
105
+ expect(producer.parent_default).to eq('omg')
106
+ expect(producer.child_default).to eq('derp')
107
+ end
82
108
  end
83
109
  end
@@ -93,11 +93,23 @@ describe Modis::Persistence do
93
93
  expect(model.name_changed?).to be false
94
94
  end
95
95
 
96
+ it 'does not identify an attribute as changed if the value is the default' do
97
+ expect(model.class.attributes_with_defaults).to eq('name' => 'Ian')
98
+ expect(model.name).to eq('Ian')
99
+ expect(model.name_changed?).to be false
100
+ end
101
+
96
102
  it 'is persisted' do
97
103
  expect(model.persisted?).to be true
98
104
  end
99
105
 
100
- it 'does not track the ID if the underlying Redis command failed'
106
+ it 'does not track the ID if the underlying Redis command failed' do
107
+ redis = double(hmset: double(value: nil), sadd: nil)
108
+ expect(model.class).to receive(:transaction).and_yield(redis)
109
+ expect(redis).to receive(:pipelined).and_yield
110
+ model.save
111
+ expect { model.class.find(model.id) }.to raise_error(Modis::RecordNotFound)
112
+ end
101
113
 
102
114
  it 'does not perform validation if validate: false' do
103
115
  model.name = nil
@@ -110,7 +122,18 @@ describe Modis::Persistence do
110
122
  end
111
123
 
112
124
  describe 'an existing record' do
113
- it 'only updates dirty attributes'
125
+ it 'only updates dirty attributes' do
126
+ model.name = 'Ian'
127
+ model.age = 10
128
+ model.save!
129
+ model.age = 11
130
+ redis = double
131
+ expect(redis).to receive(:hmset).with("modis:persistence_spec:mock_model:1", ["age", "\v"]).and_return(double(value: 'OK'))
132
+ expect(model.class).to receive(:transaction).and_yield(redis)
133
+ expect(redis).to receive(:pipelined).and_yield
134
+ model.save!
135
+ expect(model.age).to eq(11)
136
+ end
114
137
  end
115
138
 
116
139
  describe 'reload' do
@@ -183,11 +206,19 @@ describe Modis::Persistence do
183
206
  end
184
207
 
185
208
  describe 'a valid model' do
186
- it 'returns the created model'
209
+ it 'returns the created model' do
210
+ model = PersistenceSpec::MockModel.create(name: 'Ian')
211
+ expect(model.valid?).to be true
212
+ expect(model.new_record?).to be false
213
+ end
187
214
  end
188
215
 
189
216
  describe 'an invalid model' do
190
- it 'returns the unsaved model'
217
+ it 'returns the unsaved model' do
218
+ model = PersistenceSpec::MockModel.create(name: nil)
219
+ expect(model.valid?).to be false
220
+ expect(model.new_record?).to be true
221
+ end
191
222
  end
192
223
  end
193
224
 
@@ -263,4 +294,26 @@ describe Modis::Persistence do
263
294
  expect(model.update_attributes(name: nil)).to be false
264
295
  end
265
296
  end
297
+
298
+ describe 'YAML backward compatability' do
299
+ it 'loads a YAML serialized value' do
300
+ Modis.with_connection do |redis|
301
+ model.save!
302
+ key = model.class.key_for(model.id)
303
+ record = redis.hgetall(key)
304
+ record['age'] = YAML.dump(30)
305
+ redis.hmset(key, *record.to_a)
306
+ record = redis.hgetall(key)
307
+
308
+ expect(record['age']).to eq("--- 30\n...\n")
309
+
310
+ model.reload
311
+ expect(model.age).to eq(30)
312
+
313
+ model.save!(yaml_sucks: true)
314
+ record = redis.hgetall(key)
315
+ expect(record['age']).to eq("\x1E")
316
+ end
317
+ end
318
+ end
266
319
  end
@@ -1,9 +1,11 @@
1
- begin
2
- require './spec/support/simplecov_helper'
3
- include SimpleCovHelper
4
- start_simple_cov('unit')
5
- rescue LoadError
6
- puts "Coverage disabled."
1
+ unless ENV['TRAVIS']
2
+ begin
3
+ require './spec/support/simplecov_helper'
4
+ include SimpleCovHelper
5
+ start_simple_cov('unit')
6
+ rescue LoadError
7
+ puts "Coverage disabled."
8
+ end
7
9
  end
8
10
 
9
11
  require 'modis'
@@ -7,13 +7,17 @@ module SimpleCovHelper
7
7
  add_filter '/spec/'
8
8
  command_name name
9
9
 
10
+ formatters = [SimpleCov::Formatter::QualityFormatter]
11
+
10
12
  if ENV['TRAVIS']
11
- require 'coveralls'
12
- formatter SimpleCov::Formatter::MultiFormatter[SimpleCov::Formatter::QualityFormatter,
13
- Coveralls::SimpleCov::Formatter]
14
- else
15
- formatter SimpleCov::Formatter::QualityFormatter
13
+ require 'codeclimate-test-reporter'
14
+
15
+ if CodeClimate::TestReporter.run?
16
+ formatters << CodeClimate::TestReporter::Formatter
17
+ end
16
18
  end
19
+
20
+ formatter SimpleCov::Formatter::MultiFormatter[*formatters]
17
21
  end
18
22
  end
19
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modis
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Leitch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-01 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hiredis
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.5'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: connection_pool
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: msgpack
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0.5'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0.5'
69
97
  description: ActiveModel + Redis
70
98
  email:
71
99
  - port001@gmail.com
@@ -73,7 +101,6 @@ executables: []
73
101
  extensions: []
74
102
  extra_rdoc_files: []
75
103
  files:
76
- - ".coveralls.yml"
77
104
  - ".gitignore"
78
105
  - ".rubocop.yml"
79
106
  - ".ruby-gemset"
@@ -84,6 +111,10 @@ files:
84
111
  - LICENSE.txt
85
112
  - README.md
86
113
  - Rakefile
114
+ - benchmark/bench.rb
115
+ - benchmark/find.rb
116
+ - benchmark/persistence.rb
117
+ - benchmark/redis/connection/fakedis.rb
87
118
  - lib/modis.rb
88
119
  - lib/modis/attribute.rb
89
120
  - lib/modis/configuration.rb
@@ -125,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
156
  version: '0'
126
157
  requirements: []
127
158
  rubyforge_project:
128
- rubygems_version: 2.2.2
159
+ rubygems_version: 2.4.5
129
160
  signing_key:
130
161
  specification_version: 4
131
162
  summary: ActiveModel + Redis
@@ -1 +0,0 @@
1
- service-name: travis-ci