real_data_tests 0.3.2 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/lib/real_data_tests/configuration.rb +8 -0
- data/lib/real_data_tests/pg_dump_generator.rb +14 -7
- data/lib/real_data_tests/rspec_helper.rb +66 -4
- data/lib/real_data_tests/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a75133368f84b08bf44ad4f2ee73ed4eaf5636a7f19dbafdc5e6c47478055d8
|
4
|
+
data.tar.gz: 7693fa53c25af6c928ce61cb33e14667bf580fb18a32182452917932ca539bf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 366de9d95f5d8582c83cebcb89e20af819a6516dc6a1a30e3e560b3ba6de5e300404a781a08fc6b1063b562dd2519ce83ce80a0976844dfd09e0ce94551641ca
|
7
|
+
data.tar.gz: be867e1b473e90ea4bcb9041704fe6e4edac3d4e371c283dda8ac6c32b2903cd2d5b81a326f4aaa6bcb36859c2125ec995d6d115b594441bb6f23b1cbc019e5b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.4] - 2025-01-14
|
4
|
+
### Added
|
5
|
+
- Alternative native SQL loading method for CI environments
|
6
|
+
- Added `load_real_test_data_native` method that doesn't rely on system commands
|
7
|
+
- Works in restricted environments like GitHub Actions
|
8
|
+
- Uses ActiveRecord's native connection for SQL execution
|
9
|
+
- Maintains same transaction and foreign key handling behavior
|
10
|
+
|
11
|
+
## [0.3.3] - 2025-01-14
|
12
|
+
### Fixed
|
13
|
+
- Improved circular dependency handling in PgDumpGenerator for self-referential associations
|
14
|
+
- Added robust checks for self-referential associations during topological sort
|
15
|
+
- Updated dependency graph building to properly exclude prevented circular dependencies
|
16
|
+
- Fixed model name handling in circular dependency error messages
|
17
|
+
- Improved error reporting for circular dependency detection
|
18
|
+
- Enhanced PresetConfiguration circular dependency prevention
|
19
|
+
- Added more reliable tracking of prevented reciprocal associations using Sets
|
20
|
+
- Improved handling of both class and string model names in prevention checks
|
21
|
+
- Better support for multiple prevented dependencies per model
|
22
|
+
- Updated record collection depth handling
|
23
|
+
- Fixed max depth enforcement for nested associations
|
24
|
+
- Added proper depth tracking for self-referential relationships
|
25
|
+
- Improved interaction between max depth and circular dependency prevention
|
26
|
+
|
3
27
|
## [0.3.2] - 2025-01-14
|
4
28
|
### Fixed
|
5
29
|
- Enhanced association statistics tracking in RecordCollector
|
@@ -87,6 +87,14 @@ module RealDataTests
|
|
87
87
|
@prevented_reciprocals << key
|
88
88
|
end
|
89
89
|
|
90
|
+
def max_self_ref_depth=(depth)
|
91
|
+
@max_self_ref_depth = depth
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_max_self_ref_depth(model)
|
95
|
+
@max_self_ref_depth
|
96
|
+
end
|
97
|
+
|
90
98
|
def has_circular_dependency?(klass, association_name)
|
91
99
|
key = if klass.is_a?(String)
|
92
100
|
"#{klass}:#{association_name}"
|
@@ -34,15 +34,19 @@ module RealDataTests
|
|
34
34
|
|
35
35
|
def build_dependency_graph(models)
|
36
36
|
models.each_with_object({}) do |model, deps|
|
37
|
-
#
|
38
|
-
# the true foreign key dependencies that affect insert order
|
37
|
+
# Get direct dependencies from belongs_to associations
|
39
38
|
direct_dependencies = model.reflect_on_all_associations(:belongs_to)
|
40
39
|
.reject(&:polymorphic?) # Skip polymorphic associations
|
40
|
+
.reject do |assoc|
|
41
|
+
# Skip self-referential associations that are configured to prevent circular deps
|
42
|
+
assoc.klass == model &&
|
43
|
+
RealDataTests.configuration.current_preset.prevent_reciprocal?(model, assoc.name)
|
44
|
+
end
|
41
45
|
.map(&:klass)
|
42
|
-
.select { |klass| models.include?(klass) }
|
46
|
+
.select { |klass| models.include?(klass) }
|
43
47
|
.uniq
|
44
48
|
|
45
|
-
#
|
49
|
+
# Handle HABTM associations
|
46
50
|
habtm_dependencies = model.reflect_on_all_associations(:has_and_belongs_to_many)
|
47
51
|
.map { |assoc| assoc.join_table_model }
|
48
52
|
.compact
|
@@ -69,9 +73,12 @@ module RealDataTests
|
|
69
73
|
return if visited.include?(model)
|
70
74
|
|
71
75
|
if temporary.include?(model)
|
72
|
-
#
|
73
|
-
|
74
|
-
|
76
|
+
# Only raise if this isn't a prevented self-reference
|
77
|
+
unless RealDataTests.configuration.current_preset.prevent_reciprocal?(model, model.model_name.singular)
|
78
|
+
cycle = detect_cycle(model, dependencies, temporary)
|
79
|
+
raise "Circular dependency detected: #{cycle.map(&:name).join(' -> ')}"
|
80
|
+
end
|
81
|
+
return
|
75
82
|
end
|
76
83
|
|
77
84
|
temporary.add(model)
|
@@ -3,16 +3,13 @@ module RealDataTests
|
|
3
3
|
def load_real_test_data(name)
|
4
4
|
dump_path = File.join(RealDataTests.configuration.dump_path, "#{name}.sql")
|
5
5
|
raise Error, "Test data file not found: #{dump_path}" unless File.exist?(dump_path)
|
6
|
-
|
7
6
|
ActiveRecord::Base.transaction do
|
8
7
|
# Disable foreign key checks
|
9
8
|
ActiveRecord::Base.connection.execute('SET session_replication_role = replica;')
|
10
|
-
|
11
9
|
begin
|
12
10
|
# Load the SQL dump quietly
|
13
11
|
result = system("psql #{connection_options} -q < #{dump_path}")
|
14
12
|
raise Error, "Failed to load test data: #{dump_path}" unless result
|
15
|
-
|
16
13
|
ensure
|
17
14
|
# Re-enable foreign key checks
|
18
15
|
ActiveRecord::Base.connection.execute('SET session_replication_role = DEFAULT;')
|
@@ -20,6 +17,40 @@ module RealDataTests
|
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
20
|
+
# New method that doesn't rely on system commands
|
21
|
+
def load_real_test_data_native(name)
|
22
|
+
dump_path = File.join(RealDataTests.configuration.dump_path, "#{name}.sql")
|
23
|
+
raise Error, "Test data file not found: #{dump_path}" unless File.exist?(dump_path)
|
24
|
+
|
25
|
+
ActiveRecord::Base.transaction do
|
26
|
+
connection = ActiveRecord::Base.connection
|
27
|
+
|
28
|
+
# Disable foreign key checks
|
29
|
+
connection.execute('SET session_replication_role = replica;')
|
30
|
+
|
31
|
+
begin
|
32
|
+
# Read the SQL file content
|
33
|
+
sql_content = File.read(dump_path)
|
34
|
+
|
35
|
+
# Split the file into individual statements
|
36
|
+
statements = split_sql_statements(sql_content)
|
37
|
+
|
38
|
+
# Execute each statement
|
39
|
+
statements.each do |statement|
|
40
|
+
next if statement.strip.empty?
|
41
|
+
begin
|
42
|
+
connection.execute(statement)
|
43
|
+
rescue ActiveRecord::StatementInvalid => e
|
44
|
+
raise Error, "Failed to execute SQL statement: #{e.message}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
ensure
|
48
|
+
# Re-enable foreign key checks
|
49
|
+
connection.execute('SET session_replication_role = DEFAULT;')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
23
54
|
private
|
24
55
|
|
25
56
|
def connection_options
|
@@ -28,7 +59,6 @@ module RealDataTests
|
|
28
59
|
else
|
29
60
|
ActiveRecord::Base.connection_config
|
30
61
|
end
|
31
|
-
|
32
62
|
options = []
|
33
63
|
options << "-h #{config[:host]}" if config[:host]
|
34
64
|
options << "-p #{config[:port]}" if config[:port]
|
@@ -37,5 +67,37 @@ module RealDataTests
|
|
37
67
|
options << "-q"
|
38
68
|
options.join(" ")
|
39
69
|
end
|
70
|
+
|
71
|
+
def split_sql_statements(sql)
|
72
|
+
statements = []
|
73
|
+
current_statement = ''
|
74
|
+
in_string = false
|
75
|
+
escaped = false
|
76
|
+
|
77
|
+
sql.each_char do |char|
|
78
|
+
case char
|
79
|
+
when '\\'
|
80
|
+
escaped = !escaped
|
81
|
+
when "'"
|
82
|
+
in_string = !in_string unless escaped
|
83
|
+
escaped = false
|
84
|
+
when ';'
|
85
|
+
if !in_string
|
86
|
+
statements << current_statement.strip
|
87
|
+
current_statement = ''
|
88
|
+
else
|
89
|
+
current_statement << char
|
90
|
+
end
|
91
|
+
else
|
92
|
+
escaped = false
|
93
|
+
current_statement << char
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Add the last statement if it doesn't end with a semicolon
|
98
|
+
statements << current_statement.strip if current_statement.strip.length > 0
|
99
|
+
|
100
|
+
statements
|
101
|
+
end
|
40
102
|
end
|
41
103
|
end
|