pulse-meter 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,12 +10,23 @@ module PulseMeter
10
10
  module InstanceMethods
11
11
  # Serializes object and saves it to Redis
12
12
  # @raise [DumpError] if dumping fails for any reason
13
- def dump!
13
+ def dump!(safe = true)
14
14
  ensure_storability!
15
- serialized_obj = self.to_yaml
16
- redis.hset(DUMP_REDIS_KEY, self.name, serialized_obj)
17
- rescue
18
- raise DumpError, "object cannot be dumped"
15
+ serialized_obj = to_yaml
16
+ if safe
17
+ unless redis.hsetnx(DUMP_REDIS_KEY, name, serialized_obj)
18
+ stored = self.class.restore(name)
19
+ unless stored.class == self.class
20
+ raise DumpConflictError, "Attempt to create sensor #{name} of class #{self.class} but it already has class #{stored.class}"
21
+ end
22
+ end
23
+ else
24
+ redis.hset(DUMP_REDIS_KEY, name, serialized_obj)
25
+ end
26
+ rescue DumpError, RestoreError => exc
27
+ raise exc
28
+ rescue StandardError => exc
29
+ raise DumpError, "object cannot be dumped: #{exc}"
19
30
  end
20
31
 
21
32
  # Ensures that object is dumpable
@@ -37,6 +37,9 @@ module PulseMeter
37
37
  # Exception to be raised when sensor cannot be dumped
38
38
  class DumpError < SensorError; end
39
39
 
40
+ # Exception to be raised on attempts of using the same key for different sensors
41
+ class DumpConflictError < DumpError; end
42
+
40
43
  # Exception to be raised when sensor cannot be restored
41
44
  class RestoreError < SensorError; end
42
45
 
@@ -1,3 +1,3 @@
1
1
  module PulseMeter
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.10"
3
3
  end
@@ -8,19 +8,23 @@ describe PulseMeter::Mixins::Dumper do
8
8
  class Bad < Base; end
9
9
 
10
10
  class Good < Base
11
- attr_accessor :foo
12
- def name; foo.to_s; end
11
+ attr_accessor :some_value
12
+ attr_accessor :name
13
13
 
14
14
  def redis; PulseMeter.redis; end
15
15
 
16
- def initialize(foo)
17
- @foo = foo
16
+ def initialize(name)
17
+ @name = name.to_s
18
+ @some_value = name
18
19
  end
19
20
  end
20
21
 
22
+ class GoodButAnother < Good; end
23
+
21
24
  let(:bad_obj){ Bad.new }
22
25
  let(:good_obj){ Good.new(:foo) }
23
26
  let(:another_good_obj){ Good.new(:bar) }
27
+ let(:good_obj_of_another_type){ GoodButAnother.new(:quux) }
24
28
  let(:redis){ PulseMeter.redis }
25
29
 
26
30
  describe '#dump' do
@@ -57,6 +61,23 @@ describe PulseMeter::Mixins::Dumper do
57
61
  expect {good_obj.dump!}.to change {redis.hlen(Good::DUMP_REDIS_KEY)}.by(1)
58
62
  end
59
63
  end
64
+
65
+ context "when dump is safe" do
66
+ it "should not overwrite stored objects of the same type" do
67
+ good_obj.some_value = 123
68
+ good_obj.dump!
69
+ good_obj.some_value = 321
70
+ good_obj.dump!
71
+ Base.restore(good_obj.name).some_value.should == 123
72
+ end
73
+
74
+ it "should raise DumpConflictError exception if sensor with the same name but different type already exists" do
75
+ good_obj.name = "duplicate_name"
76
+ good_obj_of_another_type.name = "duplicate_name"
77
+ good_obj.dump!
78
+ expect{good_obj_of_another_type.dump!}.to raise_exception(PulseMeter::DumpConflictError)
79
+ end
80
+ end
60
81
  end
61
82
 
62
83
  describe ".restore" do
@@ -77,14 +98,14 @@ describe PulseMeter::Mixins::Dumper do
77
98
 
78
99
  it "should restore object data" do
79
100
  restored = Base.restore(good_obj.name)
80
- restored.foo.should == good_obj.foo
101
+ restored.some_value.should == good_obj.some_value
81
102
  end
82
103
 
83
104
  it "should restore last dumped object" do
84
- good_obj.foo = :bar
85
- good_obj.dump!
105
+ good_obj.some_value = :bar
106
+ good_obj.dump!(false)
86
107
  restored = Base.restore(good_obj.name)
87
- restored.foo.should == :bar
108
+ restored.some_value.should == :bar
88
109
  end
89
110
  end
90
111
  end
@@ -106,8 +127,8 @@ describe PulseMeter::Mixins::Dumper do
106
127
  end
107
128
 
108
129
  it "should return list of registered objects" do
109
- good_obj.dump!
110
- another_good_obj.dump!
130
+ good_obj.dump!(false)
131
+ another_good_obj.dump!(false)
111
132
  Base.list_names.should =~ [good_obj.name, another_good_obj.name]
112
133
  end
113
134
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pulse-meter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-06 00:00:00.000000000 Z
13
+ date: 2012-06-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gon-sinatra