pulse-meter 0.1.9 → 0.1.10

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.
@@ -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