lims-core 3.2.3
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.
- checksums.yaml +15 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.rvmrc +2 -0
- data/.travis.yml +2 -0
- data/.vimrc +27 -0
- data/.yard_templates/default/layout/html/footer.erb +0 -0
- data/.yardopts +1 -0
- data/Gemfile +54 -0
- data/Gemfile.lock +197 -0
- data/Guardfile +21 -0
- data/Guardfile.tmux +28 -0
- data/README.markdown +67 -0
- data/Rakefile +16 -0
- data/config/database.yml +16 -0
- data/doc/Array.html +116 -0
- data/doc/Array/ArrayLoggerPersistor.html +152 -0
- data/doc/Lims.html +114 -0
- data/doc/Lims/Core.html +178 -0
- data/doc/Lims/Core/Action.html +91 -0
- data/doc/Lims/Core/Actions.html +116 -0
- data/doc/Lims/Core/Actions/Action.html +216 -0
- data/doc/Lims/Core/Actions/Action/AfterEval.html +853 -0
- data/doc/Lims/Core/Actions/Action/InvalidParameters.html +268 -0
- data/doc/Lims/Core/Actions/ActionGroup.html +196 -0
- data/doc/Lims/Core/Actions/ActionGroup/AfterEval.html +315 -0
- data/doc/Lims/Core/Actions/BulkAction.html +224 -0
- data/doc/Lims/Core/Actions/BulkAction/AfterEval.html +253 -0
- data/doc/Lims/Core/Actions/TestActionGroup.html +101 -0
- data/doc/Lims/Core/Actions/TestActionGroup/Action.html +133 -0
- data/doc/Lims/Core/Actions/TestActionGroup/ActionGroup.html +127 -0
- data/doc/Lims/Core/Base.html +287 -0
- data/doc/Lims/Core/Base/AccessibleViaSuper.html +252 -0
- data/doc/Lims/Core/Base/ClassMethod.html +177 -0
- data/doc/Lims/Core/Base/HashString.html +177 -0
- data/doc/Lims/Core/Base/IsArrayOf.html +606 -0
- data/doc/Lims/Core/Base/State.html +130 -0
- data/doc/Lims/Core/Organization.html +113 -0
- data/doc/Lims/Core/Organization/Batch.html +106 -0
- data/doc/Lims/Core/Persistence.html +267 -0
- data/doc/Lims/Core/Persistence/ComparisonFilter.html +318 -0
- data/doc/Lims/Core/Persistence/Filter.html +252 -0
- data/doc/Lims/Core/Persistence/IdentityMap.html +409 -0
- data/doc/Lims/Core/Persistence/IdentityMap/Class.html +144 -0
- data/doc/Lims/Core/Persistence/IdentityMap/DuplicateError.html +126 -0
- data/doc/Lims/Core/Persistence/IdentityMap/DuplicateIdError.html +136 -0
- data/doc/Lims/Core/Persistence/IdentityMap/DuplicateObjectError.html +136 -0
- data/doc/Lims/Core/Persistence/IdentityMapClass.html +133 -0
- data/doc/Lims/Core/Persistence/Logger.html +105 -0
- data/doc/Lims/Core/Persistence/Logger/Persistor.html +334 -0
- data/doc/Lims/Core/Persistence/Logger/Session.html +452 -0
- data/doc/Lims/Core/Persistence/Logger/Store.html +470 -0
- data/doc/Lims/Core/Persistence/MessageBus.html +871 -0
- data/doc/Lims/Core/Persistence/MessageBus/ConnectionError.html +123 -0
- data/doc/Lims/Core/Persistence/MessageBus/InvalidSettingsError.html +122 -0
- data/doc/Lims/Core/Persistence/MultiCriteriaFilter.html +293 -0
- data/doc/Lims/Core/Persistence/PersistAssociationTrait.html +91 -0
- data/doc/Lims/Core/Persistence/PersistableTrait.html +91 -0
- data/doc/Lims/Core/Persistence/Persistor.html +3072 -0
- data/doc/Lims/Core/Persistence/Persistor/DuplicateError.html +205 -0
- data/doc/Lims/Core/Persistence/Persistor/DuplicateIdError.html +147 -0
- data/doc/Lims/Core/Persistence/Persistor/DuplicateObjectError.html +147 -0
- data/doc/Lims/Core/Persistence/PersistorTrait.html +91 -0
- data/doc/Lims/Core/Persistence/ResourceState.html +1738 -0
- data/doc/Lims/Core/Persistence/Search.html +269 -0
- data/doc/Lims/Core/Persistence/Search/CreateSearch.html +251 -0
- data/doc/Lims/Core/Persistence/Search/SearchPersistor.html +240 -0
- data/doc/Lims/Core/Persistence/Search/SearchSequelPersistor.html +396 -0
- data/doc/Lims/Core/Persistence/Sequel.html +117 -0
- data/doc/Lims/Core/Persistence/Sequel/Filters.html +462 -0
- data/doc/Lims/Core/Persistence/Sequel/ForTest.html +101 -0
- data/doc/Lims/Core/Persistence/Sequel/ForTest/Name.html +137 -0
- data/doc/Lims/Core/Persistence/Sequel/ForTest/Name/NamePersitor.html +143 -0
- data/doc/Lims/Core/Persistence/Sequel/Migrations.html +266 -0
- data/doc/Lims/Core/Persistence/Sequel/Persistor.html +665 -0
- data/doc/Lims/Core/Persistence/Sequel/Session.html +501 -0
- data/doc/Lims/Core/Persistence/Sequel/Store.html +417 -0
- data/doc/Lims/Core/Persistence/Session.html +2751 -0
- data/doc/Lims/Core/Persistence/Session/UnmanagedObjectError.html +111 -0
- data/doc/Lims/Core/Persistence/StateGroup.html +696 -0
- data/doc/Lims/Core/Persistence/StateList.html +498 -0
- data/doc/Lims/Core/Persistence/Store.html +695 -0
- data/doc/Lims/Core/Persistence/UuidResource.html +1044 -0
- data/doc/Lims/Core/Persistence/UuidResource/InvalidUuidError.html +111 -0
- data/doc/Lims/Core/Persistence/UuidResource/UuidResourcePersistor.html +337 -0
- data/doc/Lims/Core/Persistence/Uuidable.html +799 -0
- data/doc/Lims/Core/Persistor.html +320 -0
- data/doc/Lims/Core/Resource.html +165 -0
- data/doc/Object.html +228 -0
- data/doc/SessionSpec.html +101 -0
- data/doc/SessionSpec/Model.html +279 -0
- data/doc/SessionSpec/Model/ModelPersistor.html +327 -0
- data/doc/_index.html +732 -0
- data/doc/class_list.html +47 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +55 -0
- data/doc/css/style.css +322 -0
- data/doc/file.README.html +127 -0
- data/doc/file_list.html +49 -0
- data/doc/frames.html +13 -0
- data/doc/index.html +127 -0
- data/doc/js/app.js +205 -0
- data/doc/js/full_list.js +167 -0
- data/doc/js/jquery.js +16 -0
- data/doc/method_list.html +1894 -0
- data/doc/top-level-namespace.html +100 -0
- data/lib/common.rb +18 -0
- data/lib/lims-core.rb +29 -0
- data/lib/lims-core/actions.rb +10 -0
- data/lib/lims-core/actions/action.rb +185 -0
- data/lib/lims-core/actions/action_group.rb +54 -0
- data/lib/lims-core/actions/bulk_action.rb +65 -0
- data/lib/lims-core/base.rb +132 -0
- data/lib/lims-core/helpers.rb +41 -0
- data/lib/lims-core/persistence.rb +15 -0
- data/lib/lims-core/persistence/comparison_filter.rb +54 -0
- data/lib/lims-core/persistence/filter.rb +23 -0
- data/lib/lims-core/persistence/identity_map.rb +55 -0
- data/lib/lims-core/persistence/logger/all.rb +5 -0
- data/lib/lims-core/persistence/logger/persistor.rb +35 -0
- data/lib/lims-core/persistence/logger/session.rb +30 -0
- data/lib/lims-core/persistence/logger/store.rb +37 -0
- data/lib/lims-core/persistence/message_bus.rb +131 -0
- data/lib/lims-core/persistence/multi_criteria_filter.rb +50 -0
- data/lib/lims-core/persistence/persist_association_trait.rb +96 -0
- data/lib/lims-core/persistence/persistable_trait.rb +150 -0
- data/lib/lims-core/persistence/persistor.rb +495 -0
- data/lib/lims-core/persistence/resource_state.rb +157 -0
- data/lib/lims-core/persistence/search.rb +3 -0
- data/lib/lims-core/persistence/search/all.rb +3 -0
- data/lib/lims-core/persistence/search/create_search.rb +55 -0
- data/lib/lims-core/persistence/search/search_persistor.rb +45 -0
- data/lib/lims-core/persistence/search/search_sequel_persistor.rb +40 -0
- data/lib/lims-core/persistence/sequel.rb +14 -0
- data/lib/lims-core/persistence/sequel/filters.rb +106 -0
- data/lib/lims-core/persistence/sequel/migrations.rb +14 -0
- data/lib/lims-core/persistence/sequel/migrations/add_audit_tables.rb +147 -0
- data/lib/lims-core/persistence/sequel/migrations/initial.rb +156 -0
- data/lib/lims-core/persistence/sequel/persistor.rb +200 -0
- data/lib/lims-core/persistence/sequel/session.rb +136 -0
- data/lib/lims-core/persistence/sequel/store.rb +37 -0
- data/lib/lims-core/persistence/session.rb +409 -0
- data/lib/lims-core/persistence/state_group.rb +97 -0
- data/lib/lims-core/persistence/state_list.rb +56 -0
- data/lib/lims-core/persistence/store.rb +73 -0
- data/lib/lims-core/persistence/uuid_resource.rb +115 -0
- data/lib/lims-core/persistence/uuid_resource_persistor.rb +43 -0
- data/lib/lims-core/persistence/uuidable.rb +107 -0
- data/lib/lims-core/resource.rb +21 -0
- data/lib/lims-core/subclass_tracker.rb +30 -0
- data/lib/lims-core/version.rb +5 -0
- data/lims-core.gemspec +40 -0
- data/makefile +52 -0
- data/showoff/core-2012-06-11/core/01_slide.md +237 -0
- data/showoff/core-2012-06-11/core/02_slide.md +110 -0
- data/showoff/core-2012-06-11/custom.css +44 -0
- data/showoff/core-2012-06-11/main/01_slide.md +53 -0
- data/showoff/core-2012-06-11/showoff.json +10 -0
- data/showoff/core-2012-06-11/tp1.tpl +1 -0
- data/spec/actions/action_group_spec.rb +39 -0
- data/spec/actions/spec_helper.rb +1 -0
- data/spec/persistence/identity_map_spec.rb +55 -0
- data/spec/persistence/logger/spec_helper.rb +7 -0
- data/spec/persistence/logger/store_spec.rb +48 -0
- data/spec/persistence/message_bus_spec.rb +76 -0
- data/spec/persistence/sequel/session_spec.rb +125 -0
- data/spec/persistence/sequel/spec_helper.rb +39 -0
- data/spec/persistence/sequel/store_shared.rb +25 -0
- data/spec/persistence/sequel/store_spec.rb +22 -0
- data/spec/persistence/session_spec.rb +199 -0
- data/spec/persistence/spec_helper.rb +2 -0
- data/spec/persistence/uuid_resource_spec.rb +80 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/subclass_tracker_sperc.rb +62 -0
- data/utils/constant_tree.rb +29 -0
- data/utils/stack.rb +48 -0
- metadata +402 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'persistence/spec_helper'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'sequel'
|
|
4
|
+
|
|
5
|
+
module Helper
|
|
6
|
+
def save(object)
|
|
7
|
+
store.with_session do |session|
|
|
8
|
+
session << object
|
|
9
|
+
lambda { session.id_for(object) }
|
|
10
|
+
end.call
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
RSpec.configure do |c|
|
|
15
|
+
c.include Helper
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if RUBY_PLATFORM == "java"
|
|
19
|
+
require 'jdbc/sqlite3'
|
|
20
|
+
shared_context "sqlite db" do |&block|
|
|
21
|
+
let(:db) { ::Sequel.connect('jdbc:sqlite::memory:') }
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
shared_context "sqlite db" do
|
|
25
|
+
let!(:db) { ::Sequel.sqlite('') }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
config_database = YAML.load_file(File.join("config", "database.yml"))
|
|
30
|
+
ENV["LIMS_SUPPORT_ENV"] = "development" unless ENV["LIMS_SUPPORT_ENV"]
|
|
31
|
+
env = ENV["LIMS_SUPPORT_ENV"]
|
|
32
|
+
connection_params = config_database['test_mysql']
|
|
33
|
+
|
|
34
|
+
shared_context "mysql db" do |&block|
|
|
35
|
+
let!(:db) { ::Sequel.connect(connection_params) }
|
|
36
|
+
let(:store) { Lims::Core::Persistence::Sequel::Store.new(db) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
# Spec requirements
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
# Model requirements
|
|
6
|
+
require 'sequel'
|
|
7
|
+
require 'lims-core/persistence/sequel/store'
|
|
8
|
+
Sequel.extension :migration
|
|
9
|
+
|
|
10
|
+
shared_context "prepare tables" do
|
|
11
|
+
def prepare_table(db)
|
|
12
|
+
Sequel::Migrator.run(db, 'db/migrations')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Loggers = []
|
|
17
|
+
#require 'logger'; Loggers << Logger.new($stdout)
|
|
18
|
+
|
|
19
|
+
shared_context "sequel store" do
|
|
20
|
+
include_context "prepare tables"
|
|
21
|
+
let(:db) { Sequel.sqlite '' , :loggers => Loggers }
|
|
22
|
+
let(:store) { Lims::Core::Persistence::Sequel::Store.new(db) }
|
|
23
|
+
before (:each) { prepare_table(db) }
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Spec requirements
|
|
2
|
+
require 'persistence/sequel/spec_helper'
|
|
3
|
+
|
|
4
|
+
# Model requirements
|
|
5
|
+
require 'lims-core/persistence/sequel/store'
|
|
6
|
+
|
|
7
|
+
module Lims::Core::Persistence
|
|
8
|
+
describe Sequel::Store, :store => true, :persistence => true, :persistence => true, :sequel => true do
|
|
9
|
+
context "initialized with a valid database" do
|
|
10
|
+
include_context "sqlite db"
|
|
11
|
+
it "must be valid" do
|
|
12
|
+
expect { described_class.new(db) }.to_not raise_error
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "initialized with something elese" do
|
|
17
|
+
it "must be invalid" do
|
|
18
|
+
expect { described_class.new("my database") }.to raise_error
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Spec requirements
|
|
2
|
+
require 'persistence/spec_helper'
|
|
3
|
+
|
|
4
|
+
# Model requirements
|
|
5
|
+
require 'lims-core/persistence/store'
|
|
6
|
+
require 'lims-core/persistence/session'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module SessionSpec
|
|
10
|
+
class Model
|
|
11
|
+
include Lims::Core::Resource
|
|
12
|
+
attribute :value, String
|
|
13
|
+
|
|
14
|
+
def initialize(args)
|
|
15
|
+
case args
|
|
16
|
+
when String then @value = args
|
|
17
|
+
else
|
|
18
|
+
super(args)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
def attributesX
|
|
22
|
+
{:nesting => {:value => @value} }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class ModelPersistor < Lims::Core::Persistence::Persistor
|
|
26
|
+
Model = SessionSpec::Model
|
|
27
|
+
@@objects ={}
|
|
28
|
+
def self.register(key, value)
|
|
29
|
+
key ||= @@objects.size + 1
|
|
30
|
+
@@objects[key] = value
|
|
31
|
+
key
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def bulk_load(states, *params, &block)
|
|
35
|
+
states.map { |state| block.call(@@objects[state.id].attributes.merge(id:state.id)) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.clear()
|
|
39
|
+
@@objects ={}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
shared_examples "doesn't save 'clean' objects" do
|
|
47
|
+
it "doesn't save read objects" do
|
|
48
|
+
store.with_session do |session|
|
|
49
|
+
loaded = session.model[1]
|
|
50
|
+
loaded.should == a # test the test works !
|
|
51
|
+
Model::ModelPersistor.any_instance.should_not_receive(:insert) do |state|
|
|
52
|
+
state.resource.should == a
|
|
53
|
+
end
|
|
54
|
+
Model::ModelPersistor.any_instance.should_receive(:insert) do |state|
|
|
55
|
+
state.resource.should == b
|
|
56
|
+
end
|
|
57
|
+
session << loaded << b
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
it "updates 'dirty' objects" do
|
|
61
|
+
store.with_session do |session|
|
|
62
|
+
loaded = session.model[1]
|
|
63
|
+
loaded.value = "new value"
|
|
64
|
+
Model::ModelPersistor.any_instance.should_not_receive(:insert) do |state|
|
|
65
|
+
state.resource.should == a
|
|
66
|
+
end
|
|
67
|
+
Model::ModelPersistor.any_instance.should_receive(:bulk_update) do |states|
|
|
68
|
+
states.size == 1
|
|
69
|
+
states.first.resource.should == loaded
|
|
70
|
+
1
|
|
71
|
+
end
|
|
72
|
+
Model::ModelPersistor.any_instance.should_receive(:insert) do |state|
|
|
73
|
+
state.resource.should == b
|
|
74
|
+
2
|
|
75
|
+
end
|
|
76
|
+
session << loaded << b
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
module Lims::Core::Persistence
|
|
82
|
+
describe Session, :session => true, :persistence => true, :persistence => true do
|
|
83
|
+
let(:store) { Store.new() }
|
|
84
|
+
|
|
85
|
+
context "#transaction" do
|
|
86
|
+
let(:a) { Model.new("A") }
|
|
87
|
+
let(:b) { Model.new("B") }
|
|
88
|
+
let(:c) { Model.new("C") }
|
|
89
|
+
|
|
90
|
+
it "save the 2 if no problem" do
|
|
91
|
+
Model::ModelPersistor.any_instance.should_receive(:insert) do |state|
|
|
92
|
+
state.resource.should == a
|
|
93
|
+
end
|
|
94
|
+
Model::ModelPersistor.any_instance.should_receive(:insert) do |state|
|
|
95
|
+
state.resource.should == b
|
|
96
|
+
end
|
|
97
|
+
store.with_session do |session|
|
|
98
|
+
session << a << b
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "#dirty attribute strategy" do
|
|
103
|
+
# Mock session and persistor to load object
|
|
104
|
+
let!(:persistor_class) {
|
|
105
|
+
Session.stub(:model_for) { Model }
|
|
106
|
+
Session.stub(:persistor_class_for).with(Model) do
|
|
107
|
+
Model::ModelPersistor::clear()
|
|
108
|
+
Model::ModelPersistor::register(1, a)
|
|
109
|
+
Model::ModelPersistor::register(2, b)
|
|
110
|
+
Model::ModelPersistor
|
|
111
|
+
end
|
|
112
|
+
}
|
|
113
|
+
context "no strategy" do
|
|
114
|
+
it "save read objects" do
|
|
115
|
+
store.with_session do |session|
|
|
116
|
+
session.dirty_attribute_strategy = nil
|
|
117
|
+
loaded = session.model[1];
|
|
118
|
+
loaded.should == a # test the test works !
|
|
119
|
+
Model::ModelPersistor.any_instance.should_not_receive(:bulk_update) do |states|
|
|
120
|
+
states.size == 1
|
|
121
|
+
states.first.resource.should == a
|
|
122
|
+
1
|
|
123
|
+
end
|
|
124
|
+
Model::ModelPersistor.any_instance.should_receive(:bulk_insert) do |states|
|
|
125
|
+
states.map(&:resource).should include b
|
|
126
|
+
states.map(&:resource).should_not include a
|
|
127
|
+
2
|
|
128
|
+
end
|
|
129
|
+
session << loaded << b
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context "deep copy strategy" do
|
|
135
|
+
before(:each) { store.dirty_attribute_strategy = Store::DIRTY_ATTRIBUTE_STRATEGY_DEEP_COPY }
|
|
136
|
+
include_context "doesn't save 'clean' objects"
|
|
137
|
+
end
|
|
138
|
+
context "sha1 strategy" do
|
|
139
|
+
before(:each) { store.dirty_attribute_strategy = Store::DIRTY_ATTRIBUTE_STRATEGY_SHA1 }
|
|
140
|
+
include_context "doesn't save 'clean' objects"
|
|
141
|
+
end
|
|
142
|
+
context "md5 strategy", :focus => true do
|
|
143
|
+
before(:each) { store.dirty_attribute_strategy = Store::DIRTY_ATTRIBUTE_STRATEGY_MD5 }
|
|
144
|
+
include_context "doesn't save 'clean' objects"
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context "#nested" do
|
|
149
|
+
before(:each) {
|
|
150
|
+
Model::ModelPersistor.any_instance.stub(:insert) do |state|
|
|
151
|
+
# We stub insert to register object so they can be reloaded.
|
|
152
|
+
# However, the registration is a class method therefore common
|
|
153
|
+
# to all Persistor. That should work because an new id is given
|
|
154
|
+
# even if the object has already been registered from another Persistor.
|
|
155
|
+
state.inserted(Model::ModelPersistor::register(nil, state.resource))
|
|
156
|
+
end
|
|
157
|
+
}
|
|
158
|
+
it "share object states with parent" do
|
|
159
|
+
store.with_session do |session|
|
|
160
|
+
session << a
|
|
161
|
+
|
|
162
|
+
session.with_subsession do |sub_session|
|
|
163
|
+
session.state_for(a).should equal(sub_session.state_for(a))
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "can access object from children session " do
|
|
169
|
+
store.with_session do |session|
|
|
170
|
+
id = session.with_subsession do |sub_session|
|
|
171
|
+
sub_session << a
|
|
172
|
+
lambda { sub_session.id_for(a) }
|
|
173
|
+
end.call
|
|
174
|
+
session.model[id].should equal(a)
|
|
175
|
+
|
|
176
|
+
store.with_session do |sub_session|
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "saves object in corresponding transaction" do
|
|
182
|
+
last_session = store.with_session do |session|
|
|
183
|
+
session << a
|
|
184
|
+
session.with_subsession do |sub_session|
|
|
185
|
+
sub_session << b
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
session.state_for(a).new?.should == true # not saved yet
|
|
189
|
+
session.state_for(b).new?.should == false # saved by now
|
|
190
|
+
|
|
191
|
+
session
|
|
192
|
+
end
|
|
193
|
+
last_session.state_for(a).new?.should == false # saved by now
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# vi: ts=2:sts=2:et:sw=2 spell:spelllang=en
|
|
2
|
+
require 'persistence/spec_helper'
|
|
3
|
+
|
|
4
|
+
require 'lims-core/persistence/uuid_resource'
|
|
5
|
+
|
|
6
|
+
module Lims::Core
|
|
7
|
+
module Persistence
|
|
8
|
+
describe UuidResource, :uuid_resource => true, :uuid => true, :persistence => true do
|
|
9
|
+
context "#class" do
|
|
10
|
+
subject { UuidResource }
|
|
11
|
+
it "validates valid uuid" do
|
|
12
|
+
subject.valid?("12345678-abcd-1234-ABCD-1234567890ab").should be_true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "invalidates unvaild uuid" do
|
|
16
|
+
subject.valid?("12345678-Zbcd-1234-ABCD-1234567890ab").should be_false
|
|
17
|
+
subject.valid?("12345678-Zbcd-1234-ABCD-1234567890").should be_false
|
|
18
|
+
subject.valid?("I am not a uuid").should be_false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "generates a UUID" do
|
|
22
|
+
subject.valid?(subject.generate_uuid()).should be_true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "generates different UUID" do
|
|
26
|
+
u1,u2 = 2.times { subject.generate_uuid()}
|
|
27
|
+
u1.should_not == u2
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "#conversion" do
|
|
31
|
+
context "to packed string" do
|
|
32
|
+
let(:to_pack) { "41424344-4546-4748-6162-636465666768" }
|
|
33
|
+
let(:packed) { "ABCDEFGHabcdefgh" }
|
|
34
|
+
|
|
35
|
+
it "pack" do
|
|
36
|
+
subject.pack(to_pack).should == packed
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "unpack" do
|
|
40
|
+
subject.unpack(packed).should == to_pack
|
|
41
|
+
end
|
|
42
|
+
it "converts unpacked to valid string" do
|
|
43
|
+
subject.valid?(subject.unpack(packed))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
context "to bignum" do
|
|
47
|
+
let(:bignum) { 0x12345678abcd1234abcd1234567890ab }
|
|
48
|
+
let(:string) { "12345678-abcd-1234-abcd-1234567890ab" }
|
|
49
|
+
|
|
50
|
+
it "converts string to bignum" do
|
|
51
|
+
subject.string_to_bignum(string).should == bignum
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "converts bignum to string" do
|
|
55
|
+
subject.bignum_to_string(bignum).should == string
|
|
56
|
+
end
|
|
57
|
+
it "converts bignum to valid string" do
|
|
58
|
+
subject.valid?(subject.bignum_to_string(bignum))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
context "created without an uuid" do
|
|
66
|
+
subject { described_class.new(:modeli => "model", :key => 1) }
|
|
67
|
+
it "should create an new uuid" do
|
|
68
|
+
subject.uuid.should_not be_nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
context "created with an uuid" do
|
|
72
|
+
let(:uuid) { UuidResource.generate_uuid }
|
|
73
|
+
subject { described_class.new(:model => "model", :key => 1, :uuid => uuid) }
|
|
74
|
+
it "keeps the same uuid" do
|
|
75
|
+
subject.uuid.should == uuid
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'lims-core/subclass_tracker'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module SubclassTrackerTest
|
|
7
|
+
class A
|
|
8
|
+
extend Lims::Core::SubclassTracker
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class B < A
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class B2 < A
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class C < B
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module M
|
|
21
|
+
extend Lims::Core::SubclassTracker
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class N
|
|
25
|
+
include M
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class N2
|
|
29
|
+
include M
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class O < N
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class O2 < N2
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe Lims::Core::SubclassTracker do
|
|
39
|
+
context "track classes" do
|
|
40
|
+
subject { A }
|
|
41
|
+
|
|
42
|
+
it "responds to subclasses" do
|
|
43
|
+
subject.should respond_to(:subclasses)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "list its children" do
|
|
47
|
+
subject.subclasses.should == [B, B2, C]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "track modules" do
|
|
52
|
+
subject { M }
|
|
53
|
+
it "responds to subclasses" do
|
|
54
|
+
subject.should respond_to(:subclasses)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "list its children" do
|
|
58
|
+
subject.subclasses.should == [N, N2, O, O2]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|