postspec 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/postspec/config.rb +6 -3
- data/lib/postspec/environment.rb +16 -16
- data/lib/postspec/frame.rb +3 -3
- data/lib/postspec/render.rb +15 -15
- data/lib/postspec/state.rb +8 -8
- data/lib/postspec/version.rb +1 -1
- data/lib/postspec.rb +7 -4
- data/lib/postspec_helper.rb +4 -3
- data/lib/share/postspec_schema.sql +4 -4
- 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: c1f09285c5b3371fe89216b9cc46e332ece37aa56f2ba9146d06a1740556b44a
|
4
|
+
data.tar.gz: b38981f91ed988e67b426043c42f30649d7a40f537474cff34a2bc45bb8e0f82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c108fc4f53d68390f4917400cd616e32d58d8472cb2adc476277f5d34ef45c010974f800619e24ee7495f3e10d0db9b4918daadabc02089b7cbcc9be150b8c17
|
7
|
+
data.tar.gz: 57115a1312cc64fd60ea808c68496f4c995f680fe8b295cf07ec999bc960ce0823e49b99b6297c329140568058c3d385d6a22cc8389c526caf174ea7f3e10194
|
data/lib/postspec/config.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Used to initialize postspec from spec/spec_helper.rb or spec/postspec_helper.rb
|
2
2
|
#
|
3
3
|
module Postspec
|
4
|
-
Config = Struct.new(:database, :mode, :reflections, :anchors, :fail_fast, :ignore)
|
4
|
+
Config = Struct.new(:database, :mode, :reflections, :anchors, :fail_fast, :ignore, :cache)
|
5
5
|
|
6
6
|
@database = nil
|
7
7
|
@mode = nil
|
@@ -9,6 +9,7 @@ module Postspec
|
|
9
9
|
@anchors = nil
|
10
10
|
@fail_fast = nil
|
11
11
|
@ignore = nil
|
12
|
+
@cache = nil
|
12
13
|
|
13
14
|
DEFAULT_MODE = :empty
|
14
15
|
DEFAULT_FAIL_FAST = true
|
@@ -20,9 +21,10 @@ module Postspec
|
|
20
21
|
def self.anchors() @anchors end
|
21
22
|
def self.fail_fast() @fail_fast end
|
22
23
|
def self.ignore() @ignore end
|
24
|
+
def self.cache() @cache end
|
23
25
|
|
24
26
|
def self.configure(&block)
|
25
|
-
config = Config.new(@database, DEFAULT_MODE, nil, nil, DEFAULT_FAIL_FAST, DEFAULT_IGNORE)
|
27
|
+
config = Config.new(@database, DEFAULT_MODE, nil, nil, DEFAULT_FAIL_FAST, DEFAULT_IGNORE, nil)
|
26
28
|
yield(config)
|
27
29
|
@database = config.database
|
28
30
|
@mode = config.mode || DEFAULT_MODE
|
@@ -30,6 +32,7 @@ module Postspec
|
|
30
32
|
@anchors = config.anchors
|
31
33
|
@fail_fast = config.fail_fast || DEFAULT_FAIL_FAST
|
32
34
|
@ignore = config.ignore || DEFAULT_IGNORE # FIXME: Why not rely on Config defaults?
|
35
|
+
@cache = config.cache
|
33
36
|
self
|
34
37
|
end
|
35
38
|
|
@@ -37,7 +40,7 @@ module Postspec
|
|
37
40
|
!@database.nil? or raise Error, "Database unspecified"
|
38
41
|
@postspec ||= Postspec.new(
|
39
42
|
PgConn.new(@database),
|
40
|
-
mode: mode, reflector: @reflections, anchors: @anchors, fail: @fail_fast, ignore: @ignore)
|
43
|
+
mode: mode, reflector: @reflections, anchors: @anchors, fail: @fail_fast, ignore: @ignore, cache: cache)
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
data/lib/postspec/environment.rb
CHANGED
@@ -25,7 +25,7 @@ module Postspec
|
|
25
25
|
# the root table if this is a subtable
|
26
26
|
def table_max_ids
|
27
27
|
result = table_sequence_ids(all: true)
|
28
|
-
postspec.type.tables.select(&:sub_table?).each { |table|
|
28
|
+
postspec.type.tables.select(&:sub_table?).each { |table|
|
29
29
|
result[table.uid] = result[table.root_table.uid] or raise "Oops: #{table.uid}"
|
30
30
|
}
|
31
31
|
result
|
@@ -63,16 +63,16 @@ module Postspec
|
|
63
63
|
# puts "Environment#clean"
|
64
64
|
@uids = {}
|
65
65
|
user_tables = dirty_tables
|
66
|
-
|
66
|
+
|
67
67
|
postspec_tables = CHANGE_TABLE_UIDS
|
68
68
|
sql = render.delete_tables(user_tables) +
|
69
69
|
render.delete_tables(postspec_tables)
|
70
70
|
conn.execute render.execution_unit(user_tables.keys, sql)
|
71
71
|
end
|
72
72
|
|
73
|
-
def setup(mode)
|
73
|
+
def setup(mode)
|
74
74
|
# puts "Environment#setup"
|
75
|
-
sql =
|
75
|
+
sql =
|
76
76
|
case mode
|
77
77
|
when :seed
|
78
78
|
@uids = table_max_ids
|
@@ -100,7 +100,7 @@ module Postspec
|
|
100
100
|
conn.execute render.execution_unit(tables, sql)
|
101
101
|
end
|
102
102
|
|
103
|
-
def reset()
|
103
|
+
def reset()
|
104
104
|
# puts "Environment#reset"
|
105
105
|
conn.execute render.execution_unit(*reset_data)
|
106
106
|
end
|
@@ -174,7 +174,7 @@ __END__
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def teardown_change_environment
|
177
|
-
sql =
|
177
|
+
sql =
|
178
178
|
render.change_triggers(:drop) +
|
179
179
|
render.delete_tables(CHANGE_TABLE_UIDS)
|
180
180
|
conn.exec render.execution_unit(CHANGE_TABLE_UIDS, sql)
|
@@ -195,9 +195,9 @@ __END__
|
|
195
195
|
def teardown_seed_environment()
|
196
196
|
@uids = nil
|
197
197
|
uids = conn.map "select table_uid, min(record_id) from postspec.inserts"
|
198
|
-
sql =
|
198
|
+
sql =
|
199
199
|
render.seed_triggers(:drop) +
|
200
|
-
render.delete_tables(uids) +
|
200
|
+
render.delete_tables(uids) +
|
201
201
|
render.delete_tables(CHANGE_TABLE_UIDS) +
|
202
202
|
render.delete_tables(SEED_TABLE_UIDS)
|
203
203
|
conn.exec render.execution_unit(uids.keys, sql)
|
@@ -205,8 +205,8 @@ __END__
|
|
205
205
|
|
206
206
|
def reset_seed_environment
|
207
207
|
uids = conn.map "select table_uid, min(record_id) from postspec.inserts"
|
208
|
-
sql =
|
209
|
-
render.delete_tables(uids) +
|
208
|
+
sql =
|
209
|
+
render.delete_tables(uids) +
|
210
210
|
render.delete_tables(CHANGE_TABLE_UIDS)
|
211
211
|
conn.exec render.execution_unit(uids.keys, sql)
|
212
212
|
end
|
@@ -285,7 +285,7 @@ __END__
|
|
285
285
|
# ::new(postspec, state)
|
286
286
|
# ::new(postspec, mode)
|
287
287
|
def self.new(postspec, arg)
|
288
|
-
klass =
|
288
|
+
klass =
|
289
289
|
case mode
|
290
290
|
when :seed; SeedEnvironment
|
291
291
|
when :empty; EmptyEnvironment
|
@@ -366,8 +366,8 @@ __END__
|
|
366
366
|
|
367
367
|
def update
|
368
368
|
sql = %(
|
369
|
-
update postspec.runs
|
370
|
-
set status = #{status},
|
369
|
+
update postspec.runs
|
370
|
+
set status = #{status},
|
371
371
|
duration = #{duration}
|
372
372
|
where id = #{id}
|
373
373
|
)
|
@@ -435,11 +435,11 @@ __END__
|
|
435
435
|
attr_reader :state
|
436
436
|
forward_to :postspec, :conn, :meta, :render
|
437
437
|
|
438
|
-
def initialize(postspec, mode)
|
438
|
+
def initialize(postspec, mode)
|
439
439
|
@postspec = postspec
|
440
440
|
@state = State.create(postspec.conn, mode)
|
441
441
|
|
442
|
-
last_state
|
442
|
+
last_state
|
443
443
|
|
444
444
|
end
|
445
445
|
|
@@ -458,7 +458,7 @@ __END__
|
|
458
458
|
def reset()
|
459
459
|
conn.execute(render.reset_postspec_tables)
|
460
460
|
end
|
461
|
-
|
461
|
+
|
462
462
|
def drop()
|
463
463
|
conn.execute(render.change_triggers(:drop))
|
464
464
|
conn.execute("drop schema postspec cascade")
|
data/lib/postspec/frame.rb
CHANGED
@@ -15,10 +15,10 @@ module Postspec
|
|
15
15
|
|
16
16
|
forward_to :@stack, :empty?, :size, :each, :map
|
17
17
|
|
18
|
-
def push(frame) @stack.push frame; frame end
|
19
|
-
def pop() @stack.pop end
|
18
|
+
def push(frame) @stack.push frame; frame end
|
19
|
+
def pop() @stack.pop end
|
20
20
|
def top() @stack.last end
|
21
|
-
def dump()
|
21
|
+
def dump()
|
22
22
|
puts self.class
|
23
23
|
indent { @stack.reverse.map(&:dump) }
|
24
24
|
end
|
data/lib/postspec/render.rb
CHANGED
@@ -85,8 +85,8 @@ module Postspec
|
|
85
85
|
execute function postspec.readonly_failure('#{uid}')
|
86
86
|
EOS2
|
87
87
|
[
|
88
|
-
bud_sql.chomp,
|
89
|
-
bt_sql.chomp,
|
88
|
+
bud_sql.chomp,
|
89
|
+
bt_sql.chomp,
|
90
90
|
"insert into postspec.seeds (table_uid, record_id) values ('#{uid}', #{id})"
|
91
91
|
]
|
92
92
|
}.flatten
|
@@ -94,11 +94,11 @@ module Postspec
|
|
94
94
|
|
95
95
|
def execution_unit(tables, sql)
|
96
96
|
return [] if sql.empty?
|
97
|
-
materialized_views =
|
98
|
-
tables.select { |uid| uid !~ /^postspec\./ }.map { |uid|
|
99
|
-
postspec.type.dot(uid).depending_materialized_views
|
97
|
+
materialized_views =
|
98
|
+
tables.select { |uid| uid !~ /^postspec\./ }.map { |uid|
|
99
|
+
postspec.type.dot(uid).depending_materialized_views
|
100
100
|
}.flatten.map(&:uid).uniq
|
101
|
-
sql =
|
101
|
+
sql =
|
102
102
|
tables.map { |uid| "alter table #{uid} disable trigger all" } +
|
103
103
|
sql +
|
104
104
|
tables.map { |uid| "alter table #{uid} enable trigger all" } +
|
@@ -108,11 +108,11 @@ module Postspec
|
|
108
108
|
def delete_tables(arg)
|
109
109
|
constrain arg, Array, Hash
|
110
110
|
uids = arg.is_a?(Array) ? arg.map { |uid| [uid, 0] }.to_h : arg
|
111
|
-
sql =
|
111
|
+
sql =
|
112
112
|
uids.map { |uid, id| "delete from #{uid}" + (id > 0 ? " where id > #{id}" : "") } +
|
113
113
|
uids.select { |uid|
|
114
|
-
uid =~ /^postspec\./ ? true : !postspec.type.dot(uid).sub_table?
|
115
|
-
}.map { |uid, id|
|
114
|
+
uid =~ /^postspec\./ ? true : !postspec.type.dot(uid).sub_table?
|
115
|
+
}.map { |uid, id|
|
116
116
|
"alter table #{uid} alter column id restart" + (id > 0 ? " with #{id+1}" : "")
|
117
117
|
}
|
118
118
|
end
|
@@ -126,7 +126,7 @@ module Postspec
|
|
126
126
|
else
|
127
127
|
delete_all = []
|
128
128
|
delete_only = {}
|
129
|
-
arg.each { |uid, id|
|
129
|
+
arg.each { |uid, id|
|
130
130
|
if id == 0
|
131
131
|
delete_all << uid
|
132
132
|
else
|
@@ -139,16 +139,16 @@ module Postspec
|
|
139
139
|
delete_all_sql = []
|
140
140
|
else
|
141
141
|
delete_all_sql = [
|
142
|
-
"with " +
|
143
|
-
delete_all.map { |uid|
|
144
|
-
"t#{table_alias_index += 1} as (delete from #{uid} returning 1 as id)"
|
145
|
-
}.join(", ") +
|
142
|
+
"with " +
|
143
|
+
delete_all.map { |uid|
|
144
|
+
"t#{table_alias_index += 1} as (delete from #{uid} returning 1 as id)"
|
145
|
+
}.join(", ") +
|
146
146
|
" select " + (1...table_alias_index).map { |i| "t#{i}.id" }.join(", ") +
|
147
147
|
" from " + (1...table_alias_index).map { |i| "t#{i}" }.join(", ")
|
148
148
|
] +
|
149
149
|
delete_all.map { |uid| "alter table #{uid} alter column id restart" }
|
150
150
|
end
|
151
|
-
delete_only_sql =
|
151
|
+
delete_only_sql =
|
152
152
|
delete_only.map { |uid, id| "delete from #{uid}" + (id > 0 ? " > #{id}" : "") } +
|
153
153
|
delete_only.map { |uid, id| "alter table #{uid} alter column id restart with #{id+1}" }
|
154
154
|
sql = delete_all_sql + delete_only_sql
|
data/lib/postspec/state.rb
CHANGED
@@ -10,7 +10,7 @@ module Postspec
|
|
10
10
|
|
11
11
|
def duration() @duraction ||= (1000 * (updated_at - created_at)).round(0) end
|
12
12
|
|
13
|
-
# Maps from table UID to sorted list of record IDs.
|
13
|
+
# Maps from table UID to sorted list of record IDs.
|
14
14
|
# TODO: Are they in use? Should they be used?? Used from postspec!
|
15
15
|
# FIXME: Move to Frame - maybe?
|
16
16
|
def inserted() get_multimap("inserts") end
|
@@ -56,14 +56,14 @@ module Postspec
|
|
56
56
|
|
57
57
|
def self.write(conn, state)
|
58
58
|
conn.exec <<~EOS
|
59
|
-
update postspec.runs
|
59
|
+
update postspec.runs
|
60
60
|
set ready = #{state.ready},
|
61
61
|
clean = #{state.clean},
|
62
|
-
status = #{state.status.nil? ? 'null' : state.status},
|
62
|
+
status = #{state.status.nil? ? 'null' : state.status},
|
63
63
|
updated_at = now() at time zone 'UTC'
|
64
64
|
where id = #{state.id}
|
65
65
|
EOS
|
66
|
-
@updated_at = conn.value "select updated_at from postspec.runs where id = #{state.id}"
|
66
|
+
@updated_at = conn.value "select updated_at from postspec.runs where id = #{state.id}"
|
67
67
|
end
|
68
68
|
|
69
69
|
def dump
|
@@ -98,10 +98,10 @@ module Postspec
|
|
98
98
|
def get_multimap(table_name)
|
99
99
|
h = Hash.new #([])
|
100
100
|
conn.tuples(%(
|
101
|
-
select distinct table_uid,
|
102
|
-
record_id
|
103
|
-
from postspec.#{table_name}
|
104
|
-
order by
|
101
|
+
select distinct table_uid,
|
102
|
+
record_id
|
103
|
+
from postspec.#{table_name}
|
104
|
+
order by
|
105
105
|
table_uid, record_id
|
106
106
|
)).map { |uid, id|
|
107
107
|
(h[uid] ||= []) << id
|
data/lib/postspec/version.rb
CHANGED
data/lib/postspec.rb
CHANGED
@@ -34,7 +34,7 @@ module Postspec
|
|
34
34
|
|
35
35
|
# List of table types in the database except tables from hidden schemas (eg. postspec)
|
36
36
|
attr_reader :tables
|
37
|
-
|
37
|
+
|
38
38
|
# If true and a test case fails, postspec will commit all changes and
|
39
39
|
# ignore any further tests. If rspec is called with the --fail-fast option
|
40
40
|
# the test run will terminate immediately. Default true
|
@@ -178,9 +178,12 @@ module Postspec
|
|
178
178
|
# Postgres transaction while secondary transactions are savepoints
|
179
179
|
def primary_transaction?() @frames.size == 1 end
|
180
180
|
|
181
|
-
# Transactionn timestamp
|
181
|
+
# Transactionn timestamp without time zone
|
182
182
|
def timestamp() @conn.timestamp end
|
183
183
|
|
184
|
+
# Transactionn timestamp with time zone
|
185
|
+
def timestamptz() @conn.timestamptz end
|
186
|
+
|
184
187
|
# True if no tests failed. Default true
|
185
188
|
def success?() @success end
|
186
189
|
|
@@ -197,7 +200,7 @@ module Postspec
|
|
197
200
|
end
|
198
201
|
|
199
202
|
def search_path() @search_path end
|
200
|
-
def search_path=(*paths)
|
203
|
+
def search_path=(*paths)
|
201
204
|
@search_path = Array(paths).flatten.compact
|
202
205
|
@search_path = %w(public) if @search_path.empty?
|
203
206
|
end
|
@@ -320,7 +323,7 @@ module Postspec
|
|
320
323
|
def fixture()
|
321
324
|
@fixture ||= begin
|
322
325
|
if fox.ast
|
323
|
-
fox.data
|
326
|
+
fox.data
|
324
327
|
elsif @foxes.size >= 2
|
325
328
|
@foxes[-2].data
|
326
329
|
else
|
data/lib/postspec_helper.rb
CHANGED
@@ -7,6 +7,7 @@ def execute(*args, **opts, &block) postspec.execute(*args, **opts, &block) end
|
|
7
7
|
def fox() postspec.fox end
|
8
8
|
def db() postspec.db end
|
9
9
|
def timestamp() postspec.timestamp end
|
10
|
+
def timestamptz() postspec.timestamptz end
|
10
11
|
def data() postspec.data end
|
11
12
|
def inserted_records() postspec.inserted end
|
12
13
|
def updated_records() postspec.updated end
|
@@ -52,7 +53,7 @@ RSpec.configure do |config|
|
|
52
53
|
# Success - pop last transaction
|
53
54
|
postspec.conn.pop_transaction(commit: postspec.failed?, fail: false)
|
54
55
|
end
|
55
|
-
rescue => ex # Happens when rspec itself fails
|
56
|
+
rescue => ex # Happens when rspec itself fails
|
56
57
|
postspec.conn.cancel_transaction
|
57
58
|
postspec.fail!
|
58
59
|
raise
|
@@ -115,8 +116,8 @@ module RSpec
|
|
115
116
|
module Core
|
116
117
|
class ExampleGroup
|
117
118
|
class << self
|
118
|
-
def group(&block)
|
119
|
-
describe(nil, &block)
|
119
|
+
def group(&block)
|
120
|
+
describe(nil, &block)
|
120
121
|
end
|
121
122
|
end
|
122
123
|
end
|
@@ -7,15 +7,15 @@ set search_path to postspec;
|
|
7
7
|
-- Return a map from table UID to last value of sequence. All user tables are
|
8
8
|
-- included but tables without sequences (subtables) have last value set to
|
9
9
|
-- null
|
10
|
-
create or replace function table_sequence_ids(ignore_schemas varchar[])
|
11
|
-
returns table(table_uid text, record_id bigint)
|
10
|
+
create or replace function table_sequence_ids(ignore_schemas varchar[])
|
11
|
+
returns table(table_uid text, record_id bigint)
|
12
12
|
as $$
|
13
13
|
declare
|
14
14
|
name varchar(255);
|
15
15
|
tuple record;
|
16
16
|
begin
|
17
17
|
ignore_schemas := ignore_schemas || array['information_schema', 'postspec']::varchar[];
|
18
|
-
for tuple in
|
18
|
+
for tuple in
|
19
19
|
select tc.relnamespace::regnamespace::text || '.' || tc.relname as table_uid,
|
20
20
|
s.relnamespace::regnamespace::text || '.' || s.relname as sequence_uid
|
21
21
|
from pg_class tc
|
@@ -38,7 +38,7 @@ as $$
|
|
38
38
|
record_id := null;
|
39
39
|
return next;
|
40
40
|
else
|
41
|
-
return query execute
|
41
|
+
return query execute
|
42
42
|
'select ' || quote_literal(tuple.table_uid) || '::text as table_uid, ' ||
|
43
43
|
'case is_called when true then last_value else last_value - 1 end as last_value ' ||
|
44
44
|
'from ' || tuple.sequence_uid;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-inflector
|