Skip to content

Commit 5e4d717

Browse files
committed
Fix tests by introducing DSL separating DDL, relations, and seeding
Before that, emerging dependencies between spec parts were hard to navigate: when you call `container` it materializes the container meaning you won't be able to add new tables/relations to the container. It's a mystery to me how we've managed to continue without proper separation the stages so far. Finally, I've hit it pretty hard when fixing failing specs. What this introduces are three DSL methods accepting blocks: - setup_tables - setup_relations - seed No setup_relations blocks are yielded before all setup_tables are run. seed blocks follow setup_relations. These methods have an additional optional parameter for sequencing blocks within one stage: ```ruby setup_tables(:base) {} # called first setup_tables(dep: :base) {} # depends on base, called second setup_tables {} # no dependency provided, will be called last ``` Also, in a given spec you can use metadata to prevent seeding or declaring relations from a shared context: ```ruby include 'users and tasks' describe 'a block without seeding and relations', relations: false, seeds: false do .... end describe 'a block without seeding', seeds: false do .... end ```
1 parent b38bf3b commit 5e4d717

97 files changed

Lines changed: 1064 additions & 797 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.rubocop.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ Lint/EmptyClass:
5151
Exclude:
5252
- "spec/**/*.rb"
5353

54+
Lint/NestedMethodDefinition:
55+
Exclude:
56+
- "spec/**/*.rb"
57+
5458
Lint/RaiseException:
5559
Enabled: false
5660

@@ -63,6 +67,8 @@ Lint/SuppressedException:
6367

6468
Metrics/AbcSize:
6569
Max: 20
70+
Exclude:
71+
- "spec/**/*.rb"
6672

6773
Metrics/BlockLength:
6874
Enabled: false
@@ -76,6 +82,8 @@ Metrics/CyclomaticComplexity:
7682

7783
Metrics/MethodLength:
7884
Max: 22
85+
Exclude:
86+
- "spec/**/*.rb"
7987

8088
Naming/FileName:
8189
Exclude:

lib/rom/sql/plugin/associates.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def associate(
162162
def with_association(name, opts = EMPTY_HASH)
163163
self.class.build(
164164
relation,
165-
**options, associations: associations.merge(name => opts)
165+
**options, associations: { **associations, name => opts }
166166
)
167167
end
168168
end

lib/rom/sql/schema/inferrer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def call(schema, gateway)
3636
else
3737
infer_from_attributes(gateway, schema, **super)
3838
end
39-
rescue Sequel::Error => e
39+
rescue ::Sequel::Error => e
4040
on_error(schema.name, e)
4141
{ **FALLBACK_SCHEMA, indexes: schema.indexes }
4242
end

spec/extensions/postgres/attribute/array_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
include_context 'database setup'
77

8-
before do
8+
setup_relations do
99
conf.relation(:pg_arrays) do
1010
schema(infer: true)
1111
end
@@ -16,7 +16,7 @@
1616
end
1717

1818
context 'with a primitive type' do
19-
before do
19+
setup_tables do
2020
conn.create_table :pg_arrays do
2121
column :numbers, 'int[]'
2222
end
@@ -34,7 +34,7 @@
3434
end
3535

3636
context 'with a custom json type' do
37-
before do
37+
setup_tables do
3838
conn.create_table :pg_arrays do
3939
column :meta, 'json[]'
4040
end

spec/extensions/postgres/attribute/range_spec.rb

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,6 @@
33
RSpec.describe 'ROM::SQL::Attribute', :postgres do
44
include_context 'database setup'
55

6-
def create_ranges_table(db_type, values)
7-
conn.create_table :pg_ranges do
8-
primary_key :id
9-
text :name
10-
11-
send(db_type, :range)
12-
end
13-
14-
conf.relation(:pg_ranges) do
15-
schema(:pg_ranges, infer: true)
16-
end
17-
18-
conf.commands(:pg_ranges) do
19-
define(:create)
20-
end
21-
22-
values.each do |key, value|
23-
commands[:pg_ranges].create.(name: key.to_s, range: value)
24-
end
25-
end
26-
276
shared_examples 'range type' do
287
let(:rel) { pg_ranges.select { [name] } }
298

@@ -106,10 +85,33 @@ def create_ranges_table(db_type, values)
10685
let(:pg_ranges) { relations[:pg_ranges] }
10786
let(:range_value) { ROM::SQL::Postgres::Values::Range }
10887

109-
before do
88+
setup_tables do
11089
conn.extension(:pg_range)
11190
conn.drop_table?(:pg_ranges)
112-
create_ranges_table(db_type, values)
91+
92+
ctx = self
93+
conn.create_table :pg_ranges do
94+
primary_key :id
95+
text :name
96+
97+
send(ctx.db_type, :range)
98+
end
99+
end
100+
101+
setup_relations do
102+
conf.relation(:pg_ranges) do
103+
schema(:pg_ranges, infer: true)
104+
end
105+
106+
conf.commands(:pg_ranges) do
107+
define(:create)
108+
end
109+
end
110+
111+
seed do
112+
values.each do |key, value|
113+
commands[:pg_ranges].create.(name: key.to_s, range: value)
114+
end
113115
end
114116

115117
describe 'numrange' do

spec/extensions/postgres/attribute_spec.rb

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
RSpec.describe 'ROM::SQL::Attribute', :postgres do
44
include_context 'database setup'
55

6-
before do
6+
setup_tables do
77
conn.drop_table?(:pg_people)
88
conn.drop_table?(:people)
9+
end
910

11+
setup_relations do
1012
conf.relation(:people) do
1113
schema(:pg_people, infer: true)
1214
end
@@ -17,18 +19,22 @@
1719

1820
%i[json jsonb].each do |type|
1921
describe "using arrays in #{type}" do
20-
before do
22+
setup_tables do
2123
conn.create_table :pg_people do
2224
primary_key :id
2325
String :name
2426
column :fields, type
2527
end
28+
end
2629

30+
setup_relations do
2731
conf.commands(:people) do
2832
define(:create)
2933
define(:update)
3034
end
35+
end
3136

37+
seed do
3238
create_person.(
3339
name: 'John Doe',
3440
fields: [
@@ -100,18 +106,22 @@
100106
next unless type == :jsonb
101107

102108
describe "using maps in #{type}" do
103-
before do
109+
setup_tables do
104110
conn.create_table :pg_people do
105111
primary_key :id
106112
String :name
107113
column :data, type
108114
end
115+
end
109116

117+
setup_relations do
110118
conf.commands(:people) do
111119
define(:create)
112120
define(:update)
113121
end
122+
end
114123

124+
seed do
115125
create_person.(name: 'John Doe', data: { age: 30, height: 180 })
116126
create_person.(name: 'Jade Doe', data: { age: 25 })
117127
end
@@ -160,19 +170,23 @@
160170
end
161171

162172
describe 'using array types' do
163-
before do
173+
setup_tables do
164174
conn.create_table :pg_people do
165175
primary_key :id
166176
String :name
167177
column :emails, 'text[]'
168178
column :bigids, 'bigint[]'
169179
end
180+
end
170181

182+
setup_relations do
171183
conf.commands(:people) do
172184
define(:create)
173185
define(:update)
174186
end
187+
end
175188

189+
seed do
176190
create_person.(name: 'John Doe', emails: %w[john@doe.com john@example.com], bigids: [84])
177191
create_person.(name: 'Jade Doe', emails: %w[jade@hotmail.com], bigids: [42])
178192
end
@@ -253,7 +267,7 @@
253267
end
254268

255269
describe 'using ltree types' do
256-
before do
270+
setup_tables do
257271
conn.execute('create extension if not exists ltree')
258272

259273
conn.create_table :pg_people do
@@ -262,12 +276,16 @@
262276
column :ltree_tags, :ltree
263277
column :parents_tags, 'ltree[]', default: []
264278
end
279+
end
265280

281+
setup_relations do
266282
conf.commands(:people) do
267283
define(:create)
268284
define(:update)
269285
end
286+
end
270287

288+
seed do
271289
create_person.(name: 'John Wilkson', ltree_tags: ltree('Bottom'), parents_tags: [ltree('Top'), ltree('Top.Building')])
272290
create_person.(name: 'John Wayne', ltree_tags: ltree('Bottom.Countries'), parents_tags: [ltree('Left'), ltree('Left.Parks')])
273291
create_person.(name: 'John Fake', ltree_tags: ltree('Bottom.Cities'), parents_tags: [ltree('Top.Building.EmpireState'), ltree('Top.Building.EmpireState.381')])

spec/extensions/postgres/integration_spec.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
RSpec.describe 'PostgreSQL extension', :postgres do
44
include_context 'database setup'
55

6-
before do
6+
setup_tables do
77
conn.drop_table?(:pg_people)
88
conn.drop_table?(:people)
99
end
1010

1111
context 'with arrays' do
12-
before do
12+
setup_tables do
1313
conn.create_table :pg_people do
1414
primary_key :id
1515
String :name
1616
column :tags, 'text[]'
1717
column :allowed_subnets, 'cidr[]'
1818
end
19+
end
1920

21+
setup_relations do
2022
conf.relation(:people) do
2123
schema(:pg_people, infer: true)
2224
end
@@ -85,13 +87,15 @@
8587
end
8688

8789
context 'with jsonb' do
88-
before do
90+
setup_tables do
8991
conn.create_table :pg_people do
9092
primary_key :id
9193
String :name
9294
column :attributes, 'jsonb'
9395
end
96+
end
9497

98+
setup_relations do
9599
conf.relation(:people) do
96100
schema(:pg_people, infer: true)
97101
end

spec/integration/associations/many_to_many/custom_fks_spec.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
let(:puzzle_solvers) { relations[:puzzle_solvers] }
1616

1717
with_adapters do
18-
before do
18+
setup_tables do
1919
conn.create_table(:puzzles) do
2020
primary_key :id
2121
column :text, String, null: false
@@ -26,7 +26,9 @@
2626
foreign_key :puzzle_id, :puzzles, null: false
2727
primary_key [:solver_id, :puzzle_id]
2828
end
29+
end
2930

31+
setup_relations do
3032
conf.relation(:puzzles) { schema(infer: true) }
3133

3234
conf.relation(:puzzle_solvers) do
@@ -46,7 +48,9 @@
4648
end
4749
end
4850
end
51+
end
4952

53+
seed do
5054
p1_id = relations[:puzzles].insert(text: 'P1')
5155
p2_id = relations[:puzzles].insert(text: 'P2')
5256
p3_id = relations[:puzzles].insert(text: 'P3')

spec/integration/associations/many_to_many/from_view_spec.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
let(:puzzle_solvers) { relations[:puzzle_solvers] }
1616

1717
with_adapters do
18-
before do
18+
setup_tables do
1919
conn.create_table(:puzzles) do
2020
primary_key :id
2121
column :text, String, null: false
@@ -27,7 +27,9 @@
2727
foreign_key :puzzle_id, :puzzles, null: false
2828
primary_key [:user_id, :puzzle_id]
2929
end
30+
end
3031

32+
setup_relations do
3133
conf.relation(:puzzles) do
3234
schema(infer: true)
3335

@@ -54,7 +56,9 @@
5456
end
5557
end
5658
end
59+
end
5760

61+
seed do
5862
p1_id = relations[:puzzles].insert(text: 'P1')
5963
p2_id = relations[:puzzles].insert(text: 'P2', solved: true)
6064
p3_id = relations[:puzzles].insert(text: 'P3')

spec/integration/associations/many_to_many/self_ref_spec.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
end
1717

1818
with_adapters do
19-
before do
19+
setup_tables(hr: :db) do
2020
conn.create_table :employees do
2121
primary_key :id, Integer
2222
column :name, String
@@ -27,7 +27,9 @@
2727
foreign_key :manager_id, :employees
2828
foreign_key :participant_id, :employees
2929
end
30+
end
3031

32+
setup_relations do
3133
conf.relation(:employees) do
3234
schema(:employees, infer: true) do
3335
associations do
@@ -46,17 +48,19 @@
4648
end
4749
end
4850

51+
seed do
52+
jane = employees.insert(name: 'Jane')
53+
fred = employees.insert(name: 'Fred')
54+
55+
positions.insert(manager_id: jane, participant_id: fred)
56+
end
57+
4958
after do
5059
conn.drop_table?(:positions)
5160
conn.drop_table?(:employees)
5261
end
5362

5463
it 'preloads self-referenced tuples' do
55-
jane = employees.insert(name: 'Jane')
56-
fred = employees.insert(name: 'Fred')
57-
58-
positions.insert(manager_id: jane, participant_id: fred)
59-
6064
expect(assoc.().to_a).to eql([{ id: 1, name: 'Jane', participant_id: 2 }])
6165
end
6266
end

0 commit comments

Comments
 (0)