fixpoints 0.1.3 → 0.2.4
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 +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
|