chrono_model 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ Gemfile.lock
6
7
  InstalledFiles
7
8
  _yardoc
8
9
  coverage
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+
5
+ services:
6
+ - postgresql
7
+
8
+ bundler_args: --without development
9
+
10
+ before_script:
11
+ - psql -c "CREATE DATABASE chronomodel;" -U postgres
12
+
13
+ script: bundle exec rake TEST_CONFIG=./spec/config.travis.yml
data/Gemfile CHANGED
@@ -6,5 +6,9 @@ gemspec
6
6
  group :development do
7
7
  gem 'debugger'
8
8
  gem 'pry'
9
+ end
10
+
11
+ group :test do
9
12
  gem 'rspec'
13
+ gem 'rake'
10
14
  end
data/README.md CHANGED
@@ -8,6 +8,10 @@ This is a data structure for a
8
8
  [Slowly-Changing Dimension Type 2](http://en.wikipedia.org/wiki/Slowly_changing_dimension#Type_2)
9
9
  temporal database, implemented using only [PostgreSQL](http://www.postgresql.org) >= 9.0 features.
10
10
 
11
+ [![Build Status](https://travis-ci.org/ifad/chronomodel.png?branch=master)](https://travis-ci.org/ifad/chronomodel)
12
+ [![Dependency Status](https://gemnasium.com/ifad/chronomodel.png)](https://gemnasium.com/ifad/chronomodel)
13
+ [![Code Climate](https://codeclimate.com/github/ifad/chronomodel.png)](https://codeclimate.com/github/ifad/chronomodel)
14
+
11
15
  All the history recording is done inside the database system, freeing the application code from
12
16
  having to deal with it.
13
17
 
@@ -1,3 +1,3 @@
1
1
  module ChronoModel
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.3"
3
3
  end
data/spec/adapter_spec.rb CHANGED
@@ -46,7 +46,7 @@ describe ChronoModel::Adapter do
46
46
  end
47
47
  end
48
48
 
49
- let(:table) { 'test_table' }
49
+ table 'test_table'
50
50
  subject { table }
51
51
 
52
52
  columns do
@@ -80,8 +80,7 @@ describe ChronoModel::Adapter do
80
80
  end
81
81
 
82
82
  describe '.rename_table' do
83
- let(:table) { 'test_table' }
84
- let(:renamed) { 'foo_table' }
83
+ renamed = 'foo_table'
85
84
  subject { renamed }
86
85
 
87
86
  context ':temporal => true' do
@@ -0,0 +1,4 @@
1
+ hostname: localhost
2
+ username: postgres
3
+ password: ""
4
+ database: chronomodel
data/spec/spec_helper.rb CHANGED
@@ -16,7 +16,5 @@ RSpec.configure do |config|
16
16
  config.include(ChronoTest::Matchers::Column)
17
17
  config.include(ChronoTest::Matchers::Index)
18
18
 
19
- config.before :suite do
20
- ChronoTest.recreate_database!
21
- end
19
+ ChronoTest.recreate_database!
22
20
  end
@@ -25,6 +25,7 @@ module ChronoTest
25
25
  def connection
26
26
  AR.connection
27
27
  end
28
+ alias :adapter :connection
28
29
 
29
30
  def recreate_database!
30
31
  database = config.fetch(:database)
@@ -2,18 +2,17 @@ module ChronoTest::Helpers
2
2
 
3
3
  module Adapter
4
4
  def self.included(base)
5
- base.let!(:adapter) { ChronoTest.connection }
6
5
  base.extend DSL
7
- end
8
-
9
- def columns
10
- DSL.columns
6
+ base.instance_eval do
7
+ delegate :adapter, :to => ChronoTest
8
+ delegate :columns, :table, :to => DSL
9
+ end
11
10
  end
12
11
 
13
12
  module DSL
14
13
  def with_temporal_table(&block)
15
14
  context ':temporal => true' do
16
- before(:all) { adapter.create_table(table, :temporal => true, &columns) }
15
+ before(:all) { adapter.create_table(table, :temporal => true, &DSL.columns) }
17
16
  after(:all) { adapter.drop_table table }
18
17
 
19
18
  instance_eval(&block)
@@ -22,64 +21,59 @@ module ChronoTest::Helpers
22
21
 
23
22
  def with_plain_table(&block)
24
23
  context ':temporal => false' do
25
- before(:all) { adapter.create_table(table, :temporal => false, &columns) }
24
+ before(:all) { adapter.create_table(table, :temporal => false, &DSL.columns) }
26
25
  after(:all) { adapter.drop_table table }
27
26
 
28
27
  instance_eval(&block)
29
28
  end
30
29
  end
31
30
 
32
- def columns(&block)
33
- DSL.columns = block.call
31
+ def self.table(table = nil)
32
+ @table = table if table
33
+ @table
34
34
  end
35
35
 
36
- class << self
37
- attr_accessor :columns
36
+ def self.columns(&block)
37
+ @columns = block.call if block
38
+ @columns
38
39
  end
40
+ delegate :columns, :table, :to => self
39
41
  end
40
42
  end
41
43
 
42
44
  module TimeMachine
43
45
  def self.included(base)
44
- base.let!(:adapter) { ChronoTest.connection }
45
46
  base.extend(DSL)
47
+ base.extend(self)
46
48
  end
47
49
 
48
50
  module DSL
49
51
  def setup_schema!
50
52
  # Set up database structure
51
53
  #
52
- before(:all) do
53
- adapter.create_table 'foos', :temporal => true do |t|
54
- t.string :name
55
- t.integer :fooity
56
- end
57
-
58
- adapter.create_table 'bars', :temporal => true do |t|
59
- t.string :name
60
- t.references :foo
61
- end
62
-
63
- adapter.create_table 'bazs' do |t|
64
- t.string :name
65
- t.references :bar
66
- end
67
-
68
- adapter.create_table 'defoos', :temporal => true do |t|
69
- t.string :name
70
- t.boolean :active
71
- end
72
-
73
- adapter.create_table 'elements', :temporal => true do |t|
74
- t.string :title
75
- t.string :type
76
- end
54
+ adapter.create_table 'foos', :temporal => true do |t|
55
+ t.string :name
56
+ t.integer :fooity
57
+ end
58
+
59
+ adapter.create_table 'bars', :temporal => true do |t|
60
+ t.string :name
61
+ t.references :foo
77
62
  end
78
63
 
79
- after(:all) do
80
- adapter.drop_table 'foos'
81
- adapter.drop_table 'bars'
82
- adapter.drop_table 'bazs'
64
+ adapter.create_table 'bazs' do |t|
65
+ t.string :name
66
+ t.references :bar
67
+ end
68
+
69
+ adapter.create_table 'defoos', :temporal => true do |t|
70
+ t.string :name
71
+ t.boolean :active
72
+ end
73
+
74
+ adapter.create_table 'elements', :temporal => true do |t|
75
+ t.string :title
76
+ t.string :type
83
77
  end
84
78
  end
85
79
 
@@ -123,9 +117,12 @@ module ChronoTest::Helpers
123
117
  }
124
118
 
125
119
  def define_models!
126
- before(:all) { Models.call }
120
+ Models.call
127
121
  end
128
122
 
123
+ def adapter
124
+ ChronoTest.connection
125
+ end
129
126
  end
130
127
 
131
128
  # If a context object is given, evaluates the given
@@ -144,7 +141,7 @@ module ChronoTest::Helpers
144
141
  define_method(:ts) { @_ts ||= [] }
145
142
  end unless obj.methods.include?(:ts)
146
143
 
147
- now = adapter.select_value('select now()::timestamp')
144
+ now = ChronoTest.connection.select_value('select now()::timestamp')
148
145
  obj.ts.push(Time.parse(now))
149
146
  end
150
147
  end
@@ -7,6 +7,25 @@ describe ChronoModel::TimeMachine do
7
7
  setup_schema!
8
8
  define_models!
9
9
 
10
+ # Set up two associated records, with intertwined updates
11
+ #
12
+ foo = ts_eval { Foo.create! :name => 'foo', :fooity => 1 }
13
+ ts_eval(foo) { update_attributes! :name => 'foo bar' }
14
+
15
+ #
16
+ bar = ts_eval { Bar.create! :name => 'bar', :foo => foo }
17
+ ts_eval(bar) { update_attributes! :name => 'foo bar' }
18
+
19
+ ts_eval(foo) { update_attributes! :name => 'new foo' }
20
+
21
+ ts_eval(bar) { update_attributes! :name => 'bar bar' }
22
+ ts_eval(bar) { update_attributes! :name => 'new bar' }
23
+
24
+ #
25
+ baz = Baz.create :name => 'baz', :bar => bar
26
+
27
+ # Specs start here
28
+ #
10
29
  describe '.chrono_models' do
11
30
  subject { ChronoModel::TimeMachine.chrono_models }
12
31
 
@@ -18,30 +37,6 @@ describe ChronoModel::TimeMachine do
18
37
  } }
19
38
  end
20
39
 
21
-
22
- # Set up two associated records, with intertwined updates
23
- #
24
- let!(:foo) {
25
- foo = ts_eval { Foo.create! :name => 'foo', :fooity => 1 }
26
- ts_eval(foo) { update_attributes! :name => 'foo bar' }
27
- }
28
-
29
- let!(:bar) {
30
- bar = ts_eval { Bar.create! :name => 'bar', :foo => foo }
31
- ts_eval(bar) { update_attributes! :name => 'foo bar' }
32
-
33
- ts_eval(foo) { update_attributes! :name => 'new foo' }
34
-
35
- ts_eval(bar) { update_attributes! :name => 'bar bar' }
36
- ts_eval(bar) { update_attributes! :name => 'new bar' }
37
- }
38
-
39
- let!(:baz) {
40
- Baz.create :name => 'baz', :bar => bar
41
- }
42
-
43
- # Specs start here
44
- #
45
40
  describe '#as_of' do
46
41
  describe 'accepts a Time instance' do
47
42
  it { foo.as_of(Time.now).name.should == 'new foo' }
@@ -105,15 +100,11 @@ describe ChronoModel::TimeMachine do
105
100
  end
106
101
 
107
102
  describe 'it honors default_scopes' do
108
- let!(:active) {
109
- active = ts_eval { Defoo.create! :name => 'active 1', :active => true }
110
- ts_eval(active) { update_attributes! :name => 'active 2' }
111
- }
103
+ active = ts_eval { Defoo.create! :name => 'active 1', :active => true }
104
+ ts_eval(active) { update_attributes! :name => 'active 2' }
112
105
 
113
- let!(:hidden) {
114
- hidden = ts_eval { Defoo.create! :name => 'hidden 1', :active => false }
115
- ts_eval(hidden) { update_attributes! :name => 'hidden 2' }
116
- }
106
+ hidden = ts_eval { Defoo.create! :name => 'hidden 1', :active => false }
107
+ ts_eval(hidden) { update_attributes! :name => 'hidden 2' }
117
108
 
118
109
  it { Defoo.as_of(active.ts[0]).map(&:name).should == ['active 1'] }
119
110
  it { Defoo.as_of(active.ts[1]).map(&:name).should == ['active 2'] }
@@ -187,10 +178,8 @@ describe ChronoModel::TimeMachine do
187
178
  end
188
179
 
189
180
  context 'with STI models' do
190
- let!(:pub) {
191
- pub = ts_eval { Publication.create! :title => 'wrong title' }
192
- ts_eval(pub) { update_attributes! :title => 'correct title' }
193
- }
181
+ pub = ts_eval { Publication.create! :title => 'wrong title' }
182
+ ts_eval(pub) { update_attributes! :title => 'correct title' }
194
183
 
195
184
  it { pub.history.map(&:title).should == ['wrong title', 'correct title'] }
196
185
  end
@@ -271,10 +260,14 @@ describe ChronoModel::TimeMachine do
271
260
  end
272
261
 
273
262
  describe 'on current records' do
274
- let!(:rec) {
263
+ rec = nil
264
+ before(:all) do
275
265
  rec = ts_eval { Foo.create!(:name => 'alive foo', :fooity => 42) }
276
266
  ts_eval(rec) { update_attributes!(:name => 'dying foo') }
277
- }
267
+ end
268
+ after(:all) do
269
+ rec.history.delete_all
270
+ end
278
271
 
279
272
  subject { rec.destroy }
280
273
 
@@ -461,8 +454,8 @@ describe ChronoModel::TimeMachine do
461
454
 
462
455
  # Class methods
463
456
  context do
464
- let!(:foos) { Array.new(2) {|i| ts_eval { Foo.create! :name => "foo #{i}" } } }
465
- let!(:bars) { Array.new(2) {|i| ts_eval { Bar.create! :name => "bar #{i}", :foo => foos[i] } } }
457
+ foos = Array.new(2) {|i| ts_eval { Foo.create! :name => "foo #{i}" } }
458
+ bars = Array.new(2) {|i| ts_eval { Bar.create! :name => "bar #{i}", :foo => foos[i] } }
466
459
 
467
460
  after(:all) { foos.each(&:destroy); bars.each(&:destroy) }
468
461
 
@@ -504,7 +497,7 @@ describe ChronoModel::TimeMachine do
504
497
 
505
498
  describe '.history' do
506
499
  let(:foo_history) {
507
- ['foo', 'foo bar', 'new foo', 'alive foo', 'dying foo', 'foo 0', 'foo 1']
500
+ ['foo', 'foo bar', 'new foo', 'foo 0', 'foo 1']
508
501
  }
509
502
 
510
503
  let(:bar_history) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chrono_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2013-08-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &84655320 !ruby/object:Gem::Requirement
16
+ requirement: &74215960 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *84655320
24
+ version_requirements: *74215960
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: pg
27
- requirement: &84655110 !ruby/object:Gem::Requirement
27
+ requirement: &74215660 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *84655110
35
+ version_requirements: *74215660
36
36
  description: Give your models as-of date temporal extensions. Built entirely for PostgreSQL
37
37
  >= 9.0
38
38
  email:
@@ -43,8 +43,8 @@ extra_rdoc_files: []
43
43
  files:
44
44
  - .gitignore
45
45
  - .rspec
46
+ - .travis.yml
46
47
  - Gemfile
47
- - Gemfile.lock
48
48
  - LICENSE
49
49
  - README.md
50
50
  - README.sql
@@ -62,6 +62,7 @@ files:
62
62
  - lib/chrono_model/utils.rb
63
63
  - lib/chrono_model/version.rb
64
64
  - spec/adapter_spec.rb
65
+ - spec/config.travis.yml
65
66
  - spec/config.yml.example
66
67
  - spec/spec_helper.rb
67
68
  - spec/support/connection.rb
@@ -98,6 +99,7 @@ specification_version: 3
98
99
  summary: Temporal extensions (SCD Type II) for Active Record
99
100
  test_files:
100
101
  - spec/adapter_spec.rb
102
+ - spec/config.travis.yml
101
103
  - spec/config.yml.example
102
104
  - spec/spec_helper.rb
103
105
  - spec/support/connection.rb
data/Gemfile.lock DELETED
@@ -1,60 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- chrono_model (0.5.0.beta)
5
- activerecord (~> 3.2)
6
- pg
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- activemodel (3.2.8)
12
- activesupport (= 3.2.8)
13
- builder (~> 3.0.0)
14
- activerecord (3.2.8)
15
- activemodel (= 3.2.8)
16
- activesupport (= 3.2.8)
17
- arel (~> 3.0.2)
18
- tzinfo (~> 0.3.29)
19
- activesupport (3.2.8)
20
- i18n (~> 0.6)
21
- multi_json (~> 1.0)
22
- arel (3.0.2)
23
- builder (3.0.4)
24
- coderay (1.0.8)
25
- columnize (0.3.6)
26
- debugger (1.2.1)
27
- columnize (>= 0.3.1)
28
- debugger-linecache (~> 1.1.1)
29
- debugger-ruby_core_source (~> 1.1.4)
30
- debugger-linecache (1.1.2)
31
- debugger-ruby_core_source (>= 1.1.1)
32
- debugger-ruby_core_source (1.1.4)
33
- diff-lcs (1.1.3)
34
- i18n (0.6.1)
35
- method_source (0.8.1)
36
- multi_json (1.3.6)
37
- pg (0.14.1)
38
- pry (0.9.10)
39
- coderay (~> 1.0.5)
40
- method_source (~> 0.8)
41
- slop (~> 3.3.1)
42
- rspec (2.11.0)
43
- rspec-core (~> 2.11.0)
44
- rspec-expectations (~> 2.11.0)
45
- rspec-mocks (~> 2.11.0)
46
- rspec-core (2.11.1)
47
- rspec-expectations (2.11.3)
48
- diff-lcs (~> 1.1.3)
49
- rspec-mocks (2.11.3)
50
- slop (3.3.3)
51
- tzinfo (0.3.33)
52
-
53
- PLATFORMS
54
- ruby
55
-
56
- DEPENDENCIES
57
- chrono_model!
58
- debugger
59
- pry
60
- rspec