fixpoints 0.1.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +10 -1
- data/lib/fixpoint.rb +11 -13
- data/lib/fixpoint_test_helpers.rb +13 -11
- data/lib/fixpoints/version.rb +1 -1
- data/lib/incremental_fixpoint.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 458dad6937238c418302f72cb371a6ff84792bd90f5e3f7ca4ad481915dbc770
|
4
|
+
data.tar.gz: 78500279e1b0c01bbf9112e94bcf94ee2c1b52cf9b9b44de75bf9a8ccb376f8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c47ceec17bf52c8f287d8a31c46592da2c41cd1c7663f2bb8d668af3f1c98c13d8b932911809f3e0ec826c1997eb9539de1fc888cc1ba8b1f7a59a3305eb33a1
|
7
|
+
data.tar.gz: 8e7d0edf727a1efbf4140448cb014f2066d2bba2fb7ce2a8128956a2ccfcc4654d8d57ee6788ee7d9a81fde25fb82c19b7c77abd5e140a2df911a028e6dfe588
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -54,7 +54,7 @@ RSpec.describe 'User Flow', order: :defined do # !!! mind the order here !!!
|
|
54
54
|
fill_in 'Name', with: 'Tom'
|
55
55
|
click_on 'Save'
|
56
56
|
|
57
|
-
store_fixpoint_unless_present :
|
57
|
+
store_fixpoint_unless_present :registered_user
|
58
58
|
# creates a YAML file containing all records (/spec/fixpoints/registred_user.yml)
|
59
59
|
end
|
60
60
|
|
@@ -113,6 +113,15 @@ In order to achieve this, we must make sure that we let the store function know
|
|
113
113
|
end
|
114
114
|
```
|
115
115
|
|
116
|
+
**Multiple Databases** If an application uses multiple databases, you can use the optional `connection` parameter
|
117
|
+
to specify the database connection to use.
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
it 'posts an item' do
|
121
|
+
restore_fixpoint :registered_user, connection: ActiveRecord::Base.connection
|
122
|
+
# ...
|
123
|
+
end
|
124
|
+
```
|
116
125
|
|
117
126
|
## Limitations & Known issues
|
118
127
|
|
data/lib/fixpoint.rb
CHANGED
@@ -45,8 +45,8 @@ class Fixpoint
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# Creates a Fixpoint from the database contents. Empty tables are skipped.
|
48
|
-
def from_database
|
49
|
-
new(read_database_records)
|
48
|
+
def from_database(conn)
|
49
|
+
new(read_database_records(conn))
|
50
50
|
end
|
51
51
|
|
52
52
|
def remove(fixname)
|
@@ -56,7 +56,7 @@ class Fixpoint
|
|
56
56
|
# reset primary key sequences for all tables
|
57
57
|
# useful when tests sometimes run before the storing the first fixpoint.
|
58
58
|
# these test might have incremented the id sequence already, so the ids in the fixpoints chance (which leads to differences).
|
59
|
-
def reset_pk_sequences!
|
59
|
+
def reset_pk_sequences!(conn)
|
60
60
|
return unless conn.respond_to?(:reset_pk_sequence!)
|
61
61
|
conn.tables.each { |table_name| conn.reset_pk_sequence!(table_name) }
|
62
62
|
end
|
@@ -69,10 +69,6 @@ class Fixpoint
|
|
69
69
|
File.join(fspath, "#{fixname}.yml")
|
70
70
|
end
|
71
71
|
|
72
|
-
def conn
|
73
|
-
ActiveRecord::Base.connection
|
74
|
-
end
|
75
|
-
|
76
72
|
protected
|
77
73
|
|
78
74
|
def fixpoints_path
|
@@ -85,17 +81,21 @@ class Fixpoint
|
|
85
81
|
File.join(spec_path, FIXPOINT_FOLDER)
|
86
82
|
end
|
87
83
|
|
88
|
-
def read_database_records
|
84
|
+
def read_database_records(conn)
|
89
85
|
# adapted from: https://yizeng.me/2017/07/16/generate-rails-test-fixtures-yaml-from-database-dump/
|
90
86
|
tables = conn.tables
|
91
87
|
tables.reject! { |table_name| TABLES_TO_SKIP.include?(table_name) }
|
92
88
|
|
93
89
|
tables.each_with_object({}) do |table_name, acc|
|
94
|
-
result = conn.select_all("SELECT * FROM #{table_name}")
|
90
|
+
result = conn.select_all("SELECT * FROM #{conn.quote_table_name(table_name)}")
|
95
91
|
next if result.count.zero?
|
96
92
|
|
97
93
|
rows = result.to_a
|
98
94
|
rows.sort_by! { |row| row['id'] } if result.columns.include?('id') # let's make the order of items stable
|
95
|
+
# fix jsonb columns by re-parsing them, so they are not saved as string to the yaml file
|
96
|
+
jsonb_columns = result.column_types.select { |_, col_type| col_type.type == :jsonb }.collect { |col_name, _| col_name }
|
97
|
+
rows.collect! { |row| jsonb_columns.each {|jcol| row[jcol] = JSON.parse(row[jcol] || 'null') }; row }
|
98
|
+
|
99
99
|
acc[table_name] = rows
|
100
100
|
end
|
101
101
|
end
|
@@ -107,7 +107,7 @@ class Fixpoint
|
|
107
107
|
@records_in_tables = records_in_tables
|
108
108
|
end
|
109
109
|
|
110
|
-
def load_into_database
|
110
|
+
def load_into_database(conn)
|
111
111
|
# Here some more pointers on implementation details of fixtures:
|
112
112
|
# - https://github.com/rails/rails/blob/2998672fc22f0d5e1a79a29ccb60d0d0e627a430/activerecord/lib/active_record/fixtures.rb#L612
|
113
113
|
# - http://api.rubyonrails.org/v5.2.4/classes/ActiveRecord/FixtureSet.html#method-c-create_fixtures
|
@@ -123,7 +123,7 @@ class Fixpoint
|
|
123
123
|
|
124
124
|
# actually insert
|
125
125
|
conn.insert_fixtures_set(@records_in_tables)
|
126
|
-
self.class.reset_pk_sequences!
|
126
|
+
self.class.reset_pk_sequences!(conn)
|
127
127
|
end
|
128
128
|
|
129
129
|
def save_to_file(fixname)
|
@@ -146,8 +146,6 @@ class Fixpoint
|
|
146
146
|
|
147
147
|
protected
|
148
148
|
|
149
|
-
delegate :conn, to: :class
|
150
|
-
|
151
149
|
def contents_for_file
|
152
150
|
YAML.dump(@records_in_tables)
|
153
151
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# Helper methods to be included into RSpec
|
2
2
|
module FixpointTestHelpers
|
3
|
-
def restore_fixpoint(fixname)
|
3
|
+
def restore_fixpoint(fixname, connection: default_connection)
|
4
4
|
@last_restored = fixname
|
5
|
-
IncrementalFixpoint.from_file(fixname).load_into_database
|
5
|
+
IncrementalFixpoint.from_file(fixname).load_into_database(connection)
|
6
6
|
end
|
7
7
|
|
8
8
|
# Compares the fixpoint with the records in the database.
|
@@ -16,10 +16,10 @@ module FixpointTestHelpers
|
|
16
16
|
# ---
|
17
17
|
# If we refactor this to a gem, we should rely on rspec (e.g. use minitest or move comparison logic to Fixpoint class).
|
18
18
|
# Anyhow, we keep it like this for now, because the expectations give much nicer output than the minitest assertions.
|
19
|
-
def compare_fixpoint(fixname, ignored_columns=[:updated_at, :created_at], tables_to_compare: :all, store_fixpoint_and_fail: false, parent_fixname: nil)
|
19
|
+
def compare_fixpoint(fixname, ignored_columns=[:updated_at, :created_at], tables_to_compare: :all, store_fixpoint_and_fail: false, parent_fixname: nil, connection: default_connection)
|
20
20
|
if !IncrementalFixpoint.exists?(fixname)
|
21
21
|
if store_fixpoint_and_fail
|
22
|
-
store_fixpoint(fixname, parent_fixname)
|
22
|
+
store_fixpoint(fixname, parent_fixname, connection: connection)
|
23
23
|
pending("Fixpoint \"#{fixname}\" did not exist yet. Skipping comparison, but created fixpoint from database. Try re-running the test.")
|
24
24
|
fail
|
25
25
|
else
|
@@ -27,7 +27,7 @@ module FixpointTestHelpers
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
database_fp = IncrementalFixpoint.from_database
|
30
|
+
database_fp = IncrementalFixpoint.from_database(nil, connection)
|
31
31
|
fixpoint_fp = IncrementalFixpoint.from_file(fixname)
|
32
32
|
|
33
33
|
tables_to_compare = (database_fp.table_names + fixpoint_fp.table_names).uniq if tables_to_compare == :all
|
@@ -35,8 +35,6 @@ module FixpointTestHelpers
|
|
35
35
|
db_records = database_fp.records_for_table(table_name, ignored_columns)
|
36
36
|
fp_records = fixpoint_fp.records_for_table(table_name, ignored_columns)
|
37
37
|
|
38
|
-
# if a table is present in a fixpoint, there must be records in it because empty tables are stripped from fixpoints
|
39
|
-
expect(db_records).not_to be_empty, "#{table_name} not in database, but in fixpoint"
|
40
38
|
expect(fp_records).not_to be_empty, "#{table_name} not in fixpoint, but in database"
|
41
39
|
# we assume that the order of records returned by SELECT is stable (so we do not do any sorting)
|
42
40
|
expect(db_records).to eq(fp_records), "Database records for table \"#{table_name}\" did not match fixpoint \"#{fixname}\". Consider removing the fixpoint and re-running the test if the change is intended."
|
@@ -45,14 +43,18 @@ module FixpointTestHelpers
|
|
45
43
|
|
46
44
|
# it is not a good idea to overwrite the fixpoint each time because timestamps may change (which then shows up in version control).
|
47
45
|
# Hence we only provide a method to write to it if it does not exist.
|
48
|
-
def store_fixpoint_unless_present(fixname, parent_fixname = nil)
|
49
|
-
store_fixpoint(fixname, parent_fixname) unless IncrementalFixpoint.exists?(fixname)
|
46
|
+
def store_fixpoint_unless_present(fixname, parent_fixname = nil, connection: default_connection)
|
47
|
+
store_fixpoint(fixname, parent_fixname, connection: connection) unless IncrementalFixpoint.exists?(fixname)
|
50
48
|
end
|
51
49
|
|
52
50
|
# +parent_fixname+ when given, only the (incremental) changes to the parent are saved
|
53
51
|
# please see store_fixpoint_unless_present for note on why not to use this method
|
54
|
-
def store_fixpoint(fixname, parent_fixname = nil)
|
52
|
+
def store_fixpoint(fixname, parent_fixname = nil, connection: default_connection)
|
55
53
|
parent_fixname = @last_restored if parent_fixname == :last_restored
|
56
|
-
IncrementalFixpoint.from_database(parent_fixname).save_to_file(fixname)
|
54
|
+
IncrementalFixpoint.from_database(parent_fixname, connection).save_to_file(fixname)
|
55
|
+
end
|
56
|
+
|
57
|
+
private def default_connection
|
58
|
+
ActiveRecord::Base.connection
|
57
59
|
end
|
58
60
|
end
|
data/lib/fixpoints/version.rb
CHANGED
data/lib/incremental_fixpoint.rb
CHANGED
@@ -33,11 +33,11 @@ class IncrementalFixpoint < Fixpoint
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# Creates a Fixpoint from the database contents. Empty tables are skipped.
|
36
|
-
def self.from_database(parent_fixname=nil)
|
37
|
-
return super() if parent_fixname.nil?
|
36
|
+
def self.from_database(parent_fixname=nil, conn)
|
37
|
+
return super(conn) if parent_fixname.nil?
|
38
38
|
|
39
39
|
parent = from_file(parent_fixname)
|
40
|
-
changes_in_tables = FixpointDiff.extract_changes(parent.records_in_tables, read_database_records)
|
40
|
+
changes_in_tables = FixpointDiff.extract_changes(parent.records_in_tables, read_database_records(conn))
|
41
41
|
new(changes_in_tables, parent_fixname)
|
42
42
|
end
|
43
43
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fixpoints
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Rothe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|