modis 1.3.0 → 1.4.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.
@@ -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