fx 0.1.0 → 0.11.0
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 +5 -5
- data/.github/scripts/check-eol +95 -0
- data/.github/workflows/ci.yml +61 -0
- data/.github/workflows/eol-check.yml +30 -0
- data/.rspec +1 -1
- data/.standard.yml +3 -0
- data/CHANGELOG.md +186 -0
- data/CONTRIBUTING.md +13 -4
- data/Gemfile +21 -2
- data/LICENSE +18 -0
- data/README.md +99 -14
- data/Rakefile +11 -1
- data/bin/rake +2 -3
- data/bin/rspec +13 -3
- data/bin/setup +1 -4
- data/bin/standardrb +27 -0
- data/bin/yard +13 -3
- data/fx.gemspec +20 -27
- data/lib/fx/adapters/postgres/connection.rb +6 -0
- data/lib/fx/adapters/postgres/functions.rb +16 -28
- data/lib/fx/adapters/postgres/query_executor.rb +34 -0
- data/lib/fx/adapters/postgres/triggers.rb +14 -28
- data/lib/fx/adapters/postgres.rb +30 -17
- data/lib/fx/command_recorder.rb +104 -13
- data/lib/fx/configuration.rb +10 -25
- data/lib/fx/definition.rb +32 -10
- data/lib/fx/function.rb +23 -9
- data/lib/fx/railtie.rb +15 -0
- data/lib/fx/schema_dumper.rb +33 -10
- data/lib/fx/statements.rb +213 -11
- data/lib/fx/trigger.rb +5 -3
- data/lib/fx/version.rb +1 -1
- data/lib/fx.rb +40 -0
- data/lib/generators/fx/function/USAGE +2 -0
- data/lib/generators/fx/function/function_generator.rb +54 -39
- data/lib/generators/fx/function/templates/db/migrate/create_function.erb +1 -1
- data/lib/generators/fx/function/templates/db/migrate/update_function.erb +1 -1
- data/lib/generators/fx/migration_helper.rb +45 -0
- data/lib/generators/fx/name_helper.rb +33 -0
- data/lib/generators/fx/trigger/USAGE +2 -0
- data/lib/generators/fx/trigger/templates/db/migrate/create_trigger.erb +1 -1
- data/lib/generators/fx/trigger/templates/db/migrate/update_trigger.erb +1 -1
- data/lib/generators/fx/trigger/trigger_generator.rb +46 -51
- data/lib/generators/fx/version_helper.rb +55 -0
- data/spec/acceptance/user_manages_functions_spec.rb +26 -6
- data/spec/acceptance/user_manages_triggers_spec.rb +11 -11
- data/spec/acceptance_helper.rb +17 -11
- data/spec/dummy/Rakefile +8 -1
- data/spec/dummy/bin/bundle +2 -2
- data/spec/dummy/bin/rails +3 -3
- data/spec/dummy/bin/rake +2 -2
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/database.yml +2 -0
- data/spec/dummy/config.ru +1 -1
- data/spec/features/functions/migrations_spec.rb +9 -9
- data/spec/features/functions/revert_spec.rb +13 -13
- data/spec/features/triggers/migrations_spec.rb +11 -11
- data/spec/features/triggers/revert_spec.rb +21 -21
- data/spec/fx/adapters/postgres/functions_spec.rb +40 -0
- data/spec/fx/adapters/postgres/query_executor_spec.rb +75 -0
- data/spec/fx/adapters/postgres/triggers_spec.rb +48 -0
- data/spec/fx/adapters/postgres_spec.rb +115 -111
- data/spec/fx/command_recorder_spec.rb +39 -53
- data/spec/fx/configuration_spec.rb +20 -9
- data/spec/fx/definition_spec.rb +53 -38
- data/spec/fx/function_spec.rb +143 -0
- data/spec/fx/schema_dumper_spec.rb +241 -0
- data/spec/fx/statements_spec.rb +219 -0
- data/spec/fx/trigger_spec.rb +52 -0
- data/spec/fx_spec.rb +28 -0
- data/spec/generators/fx/function/function_generator_spec.rb +22 -10
- data/spec/generators/fx/migration_helper_spec.rb +108 -0
- data/spec/generators/fx/name_helper_spec.rb +114 -0
- data/spec/generators/fx/trigger/trigger_generator_spec.rb +55 -20
- data/spec/generators/fx/version_helper_spec.rb +157 -0
- data/spec/spec_helper.rb +16 -4
- data/spec/support/database_reset.rb +24 -0
- data/spec/support/definition_helpers.rb +5 -9
- data/spec/support/generator_setup.rb +46 -5
- data/spec/support/migration_helpers.rb +9 -1
- data/spec/support/warning_helper.rb +5 -0
- metadata +43 -215
- data/.ruby-version +0 -1
- data/.travis.yml +0 -27
- data/Appraisals +0 -21
- data/bin/appraisal +0 -17
- data/gemfiles/rails40.gemfile +0 -8
- data/gemfiles/rails40.gemfile.lock +0 -111
- data/gemfiles/rails41.gemfile +0 -8
- data/gemfiles/rails41.gemfile.lock +0 -113
- data/gemfiles/rails42.gemfile +0 -8
- data/gemfiles/rails42.gemfile.lock +0 -130
- data/gemfiles/rails50.gemfile +0 -8
- data/gemfiles/rails50.gemfile.lock +0 -126
- data/lib/fx/command_recorder/arguments.rb +0 -43
- data/lib/fx/command_recorder/function.rb +0 -30
- data/lib/fx/command_recorder/trigger.rb +0 -30
- data/lib/fx/schema_dumper/function.rb +0 -29
- data/lib/fx/schema_dumper/trigger.rb +0 -29
- data/lib/fx/statements/function.rb +0 -105
- data/lib/fx/statements/trigger.rb +0 -133
- data/spec/fx/command_recorder/arguments_spec.rb +0 -41
- data/spec/fx/schema_dumper/function_spec.rb +0 -22
- data/spec/fx/schema_dumper/trigger_spec.rb +0 -40
- data/spec/fx/statements/function_spec.rb +0 -103
- data/spec/fx/statements/trigger_spec.rb +0 -132
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe Fx::CommandRecorder, :db do
|
|
3
|
+
RSpec.describe Fx::CommandRecorder, :db do
|
|
4
4
|
describe "#create_function" do
|
|
5
5
|
it "records the created function" do
|
|
6
6
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
7
7
|
|
|
8
8
|
recorder.create_function :test
|
|
9
9
|
|
|
10
|
-
expect(recorder.commands).to eq
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "reverts to drop_function" do
|
|
14
|
-
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
15
|
-
|
|
16
|
-
recorder.create_function :test
|
|
17
|
-
|
|
18
|
-
expect(recorder.commands).to eq [[:create_function, [:test], nil]]
|
|
10
|
+
expect(recorder.commands).to eq([[:create_function, [:test], nil]])
|
|
19
11
|
end
|
|
20
12
|
|
|
21
13
|
it "reverts to drop_function" do
|
|
@@ -23,7 +15,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
23
15
|
|
|
24
16
|
recorder.revert { recorder.create_function :test }
|
|
25
17
|
|
|
26
|
-
expect(recorder.commands).to eq
|
|
18
|
+
expect(recorder.commands).to eq([[:drop_function, [:test]]])
|
|
27
19
|
end
|
|
28
20
|
end
|
|
29
21
|
|
|
@@ -33,54 +25,56 @@ describe Fx::CommandRecorder, :db do
|
|
|
33
25
|
|
|
34
26
|
recorder.drop_function :test
|
|
35
27
|
|
|
36
|
-
expect(recorder.commands).to eq
|
|
28
|
+
expect(recorder.commands).to eq([[:drop_function, [:test], nil]])
|
|
37
29
|
end
|
|
38
30
|
|
|
39
31
|
it "reverts to create_function with specified revert_to_version" do
|
|
40
32
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
41
|
-
args = [:test, {
|
|
42
|
-
revert_args = [:test, {
|
|
33
|
+
args = [:test, {revert_to_version: 3}]
|
|
34
|
+
revert_args = [:test, {version: 3}]
|
|
43
35
|
|
|
44
36
|
recorder.revert { recorder.drop_function(*args) }
|
|
45
37
|
|
|
46
|
-
expect(recorder.commands).to eq
|
|
38
|
+
expect(recorder.commands).to eq([[:create_function, revert_args]])
|
|
47
39
|
end
|
|
48
40
|
|
|
49
41
|
it "raises when reverting without revert_to_version set" do
|
|
50
42
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
51
|
-
args = [:test, {
|
|
43
|
+
args = [:test, {another_argument: 1}]
|
|
52
44
|
|
|
53
|
-
expect
|
|
54
|
-
|
|
45
|
+
expect do
|
|
46
|
+
recorder.revert { recorder.drop_function(*args) }
|
|
47
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
55
48
|
end
|
|
56
49
|
end
|
|
57
50
|
|
|
58
51
|
describe "#update_function" do
|
|
59
52
|
it "records the updated function" do
|
|
60
53
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
61
|
-
args = [:test, {
|
|
54
|
+
args = [:test, {version: 2}]
|
|
62
55
|
|
|
63
56
|
recorder.update_function(*args)
|
|
64
57
|
|
|
65
|
-
expect(recorder.commands).to eq
|
|
58
|
+
expect(recorder.commands).to eq([[:update_function, args, nil]])
|
|
66
59
|
end
|
|
67
60
|
|
|
68
61
|
it "reverts to update_function with the specified revert_to_version" do
|
|
69
62
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
70
|
-
args = [:test, {
|
|
71
|
-
revert_args = [:test, {
|
|
63
|
+
args = [:test, {version: 2, revert_to_version: 1}]
|
|
64
|
+
revert_args = [:test, {version: 1}]
|
|
72
65
|
|
|
73
66
|
recorder.revert { recorder.update_function(*args) }
|
|
74
67
|
|
|
75
|
-
expect(recorder.commands).to eq
|
|
68
|
+
expect(recorder.commands).to eq([[:update_function, revert_args]])
|
|
76
69
|
end
|
|
77
70
|
|
|
78
71
|
it "raises when reverting without revert_to_version set" do
|
|
79
72
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
80
|
-
args = [:test, {
|
|
73
|
+
args = [:test, {version: 42, another_argument: 1}]
|
|
81
74
|
|
|
82
|
-
expect
|
|
83
|
-
|
|
75
|
+
expect do
|
|
76
|
+
recorder.revert { recorder.update_function(*args) }
|
|
77
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
84
78
|
end
|
|
85
79
|
end
|
|
86
80
|
|
|
@@ -90,17 +84,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
90
84
|
|
|
91
85
|
recorder.create_trigger :greetings
|
|
92
86
|
|
|
93
|
-
expect(recorder.commands).to eq
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it "reverts to drop_trigger" do
|
|
97
|
-
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
98
|
-
|
|
99
|
-
recorder.create_trigger :greetings
|
|
100
|
-
|
|
101
|
-
expect(recorder.commands).to eq [
|
|
102
|
-
[:create_trigger, [:greetings], nil],
|
|
103
|
-
]
|
|
87
|
+
expect(recorder.commands).to eq([[:create_trigger, [:greetings], nil]])
|
|
104
88
|
end
|
|
105
89
|
|
|
106
90
|
it "reverts to drop_trigger" do
|
|
@@ -108,7 +92,7 @@ describe Fx::CommandRecorder, :db do
|
|
|
108
92
|
|
|
109
93
|
recorder.revert { recorder.create_trigger :greetings }
|
|
110
94
|
|
|
111
|
-
expect(recorder.commands).to eq
|
|
95
|
+
expect(recorder.commands).to eq([[:drop_trigger, [:greetings]]])
|
|
112
96
|
end
|
|
113
97
|
end
|
|
114
98
|
|
|
@@ -118,54 +102,56 @@ describe Fx::CommandRecorder, :db do
|
|
|
118
102
|
|
|
119
103
|
recorder.drop_trigger :users
|
|
120
104
|
|
|
121
|
-
expect(recorder.commands).to eq
|
|
105
|
+
expect(recorder.commands).to eq([[:drop_trigger, [:users], nil]])
|
|
122
106
|
end
|
|
123
107
|
|
|
124
108
|
it "reverts to create_trigger with specified revert_to_version" do
|
|
125
109
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
126
|
-
args = [:users, {
|
|
127
|
-
revert_args = [:users, {
|
|
110
|
+
args = [:users, {revert_to_version: 3}]
|
|
111
|
+
revert_args = [:users, {version: 3}]
|
|
128
112
|
|
|
129
113
|
recorder.revert { recorder.drop_trigger(*args) }
|
|
130
114
|
|
|
131
|
-
expect(recorder.commands).to eq
|
|
115
|
+
expect(recorder.commands).to eq([[:create_trigger, revert_args]])
|
|
132
116
|
end
|
|
133
117
|
|
|
134
118
|
it "raises when reverting without revert_to_version set" do
|
|
135
119
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
136
|
-
args = [:users, {
|
|
120
|
+
args = [:users, {another_argument: 1}]
|
|
137
121
|
|
|
138
|
-
expect
|
|
139
|
-
|
|
122
|
+
expect do
|
|
123
|
+
recorder.revert { recorder.drop_trigger(*args) }
|
|
124
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
140
125
|
end
|
|
141
126
|
end
|
|
142
127
|
|
|
143
128
|
describe "#update_trigger" do
|
|
144
129
|
it "records the updated trigger" do
|
|
145
130
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
146
|
-
args = [:users, {
|
|
131
|
+
args = [:users, {version: 2}]
|
|
147
132
|
|
|
148
133
|
recorder.update_trigger(*args)
|
|
149
134
|
|
|
150
|
-
expect(recorder.commands).to eq
|
|
135
|
+
expect(recorder.commands).to eq([[:update_trigger, args, nil]])
|
|
151
136
|
end
|
|
152
137
|
|
|
153
138
|
it "reverts to update_trigger with the specified revert_to_version" do
|
|
154
139
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
155
|
-
args = [:users, {
|
|
156
|
-
revert_args = [:users, {
|
|
140
|
+
args = [:users, {version: 2, revert_to_version: 1}]
|
|
141
|
+
revert_args = [:users, {version: 1}]
|
|
157
142
|
|
|
158
143
|
recorder.revert { recorder.update_trigger(*args) }
|
|
159
144
|
|
|
160
|
-
expect(recorder.commands).to eq
|
|
145
|
+
expect(recorder.commands).to eq([[:update_trigger, revert_args]])
|
|
161
146
|
end
|
|
162
147
|
|
|
163
148
|
it "raises when reverting without revert_to_version set" do
|
|
164
149
|
recorder = ActiveRecord::Migration::CommandRecorder.new
|
|
165
|
-
args = [:users, {
|
|
150
|
+
args = [:users, {version: 42, another_argument: 1}]
|
|
166
151
|
|
|
167
|
-
expect
|
|
168
|
-
|
|
152
|
+
expect do
|
|
153
|
+
recorder.revert { recorder.update_trigger(*args) }
|
|
154
|
+
end.to raise_error(ActiveRecord::IrreversibleMigration)
|
|
169
155
|
end
|
|
170
156
|
end
|
|
171
157
|
end
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe Fx::Configuration do
|
|
3
|
+
RSpec.describe Fx::Configuration do
|
|
4
4
|
it "defaults the database adapter to postgres" do
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
configuration = Fx::Configuration.new
|
|
6
|
+
|
|
7
|
+
expect(configuration.database).to be_a(Fx::Adapters::Postgres)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "defaults `dump_functions_at_beginning_of_schema` to false" do
|
|
11
|
+
configuration = Fx::Configuration.new
|
|
12
|
+
|
|
13
|
+
expect(configuration.dump_functions_at_beginning_of_schema).to eq(false)
|
|
7
14
|
end
|
|
8
15
|
|
|
9
16
|
it "allows the database adapter to be set" do
|
|
17
|
+
configuration = Fx::Configuration.new
|
|
10
18
|
adapter = double("Fx Adapter")
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
configuration.database = adapter
|
|
21
|
+
|
|
22
|
+
expect(configuration.database).to eq(adapter)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "allows `dump_functions_at_beginning_of_schema` to be set" do
|
|
26
|
+
configuration = Fx::Configuration.new
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
expect(Fx.database).to eq adapter
|
|
28
|
+
configuration.dump_functions_at_beginning_of_schema = true
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
expect(configuration.dump_functions_at_beginning_of_schema).to eq(true)
|
|
20
31
|
end
|
|
21
32
|
end
|
data/spec/fx/definition_spec.rb
CHANGED
|
@@ -1,65 +1,84 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe Fx::Definition do
|
|
3
|
+
RSpec.describe Fx::Definition do
|
|
4
4
|
describe "#to_sql" do
|
|
5
5
|
context "representing a function definition" do
|
|
6
6
|
it "returns the content of a function definition" do
|
|
7
|
-
sql_definition = <<~
|
|
7
|
+
sql_definition = <<~SQL
|
|
8
8
|
CREATE OR REPLACE FUNCTION test()
|
|
9
9
|
RETURNS text AS $$
|
|
10
10
|
BEGIN
|
|
11
11
|
RETURN 'test';
|
|
12
12
|
END;
|
|
13
13
|
$$ LANGUAGE plpgsql;
|
|
14
|
-
|
|
14
|
+
SQL
|
|
15
15
|
allow(File).to receive(:read).and_return(sql_definition)
|
|
16
16
|
|
|
17
|
-
definition = Fx::Definition.
|
|
17
|
+
definition = Fx::Definition.function(name: "test", version: 1)
|
|
18
18
|
|
|
19
|
-
expect(definition.to_sql).to eq
|
|
19
|
+
expect(definition.to_sql).to eq(sql_definition)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "raises an error if the file is empty" do
|
|
23
23
|
allow(File).to receive(:read).and_return("")
|
|
24
|
-
definition = Fx::Definition.
|
|
24
|
+
definition = Fx::Definition.function(name: "test", version: 1)
|
|
25
25
|
|
|
26
|
-
expect
|
|
26
|
+
expect do
|
|
27
|
+
definition.to_sql
|
|
28
|
+
end.to raise_error(
|
|
27
29
|
RuntimeError,
|
|
28
|
-
%r
|
|
30
|
+
%r{Define function in db/functions/test_v01.sql before migrating}
|
|
29
31
|
)
|
|
30
32
|
end
|
|
33
|
+
|
|
34
|
+
context "when definition is at Rails engine" do
|
|
35
|
+
it "returns the content of a function definition" do
|
|
36
|
+
sql_definition = <<~SQL
|
|
37
|
+
CREATE OR REPLACE FUNCTION test()
|
|
38
|
+
RETURNS text AS $$
|
|
39
|
+
BEGIN
|
|
40
|
+
RETURN 'test';
|
|
41
|
+
END;
|
|
42
|
+
$$ LANGUAGE plpgsql;
|
|
43
|
+
SQL
|
|
44
|
+
engine_path = Rails.root.join("tmp", "engine")
|
|
45
|
+
FileUtils.mkdir_p(engine_path.join("db", "functions"))
|
|
46
|
+
File.write(engine_path.join("db", "functions", "custom_test_v01.sql"), sql_definition)
|
|
47
|
+
Rails.application.config.paths["db/migrate"].push(engine_path.join("db", "migrate"))
|
|
48
|
+
|
|
49
|
+
definition = Fx::Definition.function(name: "custom_test", version: 1)
|
|
50
|
+
|
|
51
|
+
expect(definition.to_sql).to eq(sql_definition)
|
|
52
|
+
|
|
53
|
+
FileUtils.rm_rf(engine_path)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
31
56
|
end
|
|
32
57
|
|
|
33
58
|
context "representing a trigger definition" do
|
|
34
59
|
it "returns the content of a trigger definition" do
|
|
35
|
-
sql_definition = <<~
|
|
60
|
+
sql_definition = <<~SQL
|
|
36
61
|
CREATE TRIGGER check_update
|
|
37
62
|
BEFORE UPDATE ON accounts
|
|
38
63
|
FOR EACH ROW
|
|
39
|
-
EXECUTE
|
|
40
|
-
|
|
64
|
+
EXECUTE FUNCTION check_account_update();
|
|
65
|
+
SQL
|
|
41
66
|
allow(File).to receive(:read).and_return(sql_definition)
|
|
42
67
|
|
|
43
|
-
definition = Fx::Definition.
|
|
44
|
-
name: "test",
|
|
45
|
-
version: 1,
|
|
46
|
-
type: "trigger",
|
|
47
|
-
)
|
|
68
|
+
definition = Fx::Definition.trigger(name: "test", version: 1)
|
|
48
69
|
|
|
49
|
-
expect(definition.to_sql).to eq
|
|
70
|
+
expect(definition.to_sql).to eq(sql_definition)
|
|
50
71
|
end
|
|
51
72
|
|
|
52
73
|
it "raises an error if the file is empty" do
|
|
53
74
|
allow(File).to receive(:read).and_return("")
|
|
54
|
-
definition = Fx::Definition.
|
|
55
|
-
name: "test",
|
|
56
|
-
version: 1,
|
|
57
|
-
type: "trigger",
|
|
58
|
-
)
|
|
75
|
+
definition = Fx::Definition.trigger(name: "test", version: 1)
|
|
59
76
|
|
|
60
|
-
expect
|
|
77
|
+
expect do
|
|
78
|
+
definition.to_sql
|
|
79
|
+
end.to raise_error(
|
|
61
80
|
RuntimeError,
|
|
62
|
-
%r
|
|
81
|
+
%r{Define trigger in db/triggers/test_v01.sql before migrating}
|
|
63
82
|
)
|
|
64
83
|
end
|
|
65
84
|
end
|
|
@@ -68,44 +87,40 @@ describe Fx::Definition do
|
|
|
68
87
|
describe "#path" do
|
|
69
88
|
context "representing a function definition" do
|
|
70
89
|
it "returns a sql file with padded version and function name" do
|
|
71
|
-
definition = Fx::Definition.
|
|
90
|
+
definition = Fx::Definition.function(name: "test", version: 1)
|
|
72
91
|
|
|
73
|
-
expect(definition.path).to eq
|
|
92
|
+
expect(definition.path).to eq("db/functions/test_v01.sql")
|
|
74
93
|
end
|
|
75
94
|
end
|
|
76
95
|
|
|
77
96
|
context "representing a trigger definition" do
|
|
78
97
|
it "returns a sql file with padded version and trigger name" do
|
|
79
|
-
definition = Fx::Definition.
|
|
80
|
-
name: "test",
|
|
81
|
-
version: 1,
|
|
82
|
-
type: "trigger",
|
|
83
|
-
)
|
|
98
|
+
definition = Fx::Definition.trigger(name: "test", version: 1)
|
|
84
99
|
|
|
85
|
-
expect(definition.path).to eq
|
|
100
|
+
expect(definition.path).to eq("db/triggers/test_v01.sql")
|
|
86
101
|
end
|
|
87
102
|
end
|
|
88
103
|
end
|
|
89
104
|
|
|
90
105
|
describe "#full_path" do
|
|
91
106
|
it "joins the path with Rails.root" do
|
|
92
|
-
definition = Fx::Definition.
|
|
107
|
+
definition = Fx::Definition.function(name: "test", version: 15)
|
|
93
108
|
|
|
94
|
-
expect(definition.full_path).to eq
|
|
109
|
+
expect(definition.full_path).to eq(Rails.root.join(definition.path))
|
|
95
110
|
end
|
|
96
111
|
end
|
|
97
112
|
|
|
98
113
|
describe "#version" do
|
|
99
114
|
it "pads the version number with 0" do
|
|
100
|
-
definition = Fx::Definition.
|
|
115
|
+
definition = Fx::Definition.function(name: :_, version: 1)
|
|
101
116
|
|
|
102
|
-
expect(definition.version).to eq
|
|
117
|
+
expect(definition.version).to eq("01")
|
|
103
118
|
end
|
|
104
119
|
|
|
105
120
|
it "does not pad more than 2 characters" do
|
|
106
|
-
definition = Fx::Definition.
|
|
121
|
+
definition = Fx::Definition.function(name: :_, version: 15)
|
|
107
122
|
|
|
108
|
-
expect(definition.version).to eq
|
|
123
|
+
expect(definition.version).to eq("15")
|
|
109
124
|
end
|
|
110
125
|
end
|
|
111
126
|
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.describe Fx::Function do
|
|
4
|
+
describe "#<=>" do
|
|
5
|
+
it "delegates to `signature`" do
|
|
6
|
+
function_a = Fx::Function.new(
|
|
7
|
+
"name" => "name_a",
|
|
8
|
+
"definition" => "some definition",
|
|
9
|
+
"arguments" => ""
|
|
10
|
+
)
|
|
11
|
+
function_b = Fx::Function.new(
|
|
12
|
+
"name" => "name_b",
|
|
13
|
+
"definition" => "some definition",
|
|
14
|
+
"arguments" => ""
|
|
15
|
+
)
|
|
16
|
+
function_c = Fx::Function.new(
|
|
17
|
+
"name" => "name_c",
|
|
18
|
+
"definition" => "some definition",
|
|
19
|
+
"arguments" => ""
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
expect(function_b).to be_between(function_a, function_c)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "orders overloads by signature" do
|
|
26
|
+
add_int = Fx::Function.new(
|
|
27
|
+
"name" => "add",
|
|
28
|
+
"definition" => "some definition",
|
|
29
|
+
"arguments" => "integer, integer"
|
|
30
|
+
)
|
|
31
|
+
add_text = Fx::Function.new(
|
|
32
|
+
"name" => "add",
|
|
33
|
+
"definition" => "some definition",
|
|
34
|
+
"arguments" => "text, text"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
expect(add_int <=> add_text).to be < 0
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#==" do
|
|
42
|
+
it "compares `signature` and `definition`" do
|
|
43
|
+
function_a = Fx::Function.new(
|
|
44
|
+
"name" => "name_a",
|
|
45
|
+
"definition" => "some definition",
|
|
46
|
+
"arguments" => ""
|
|
47
|
+
)
|
|
48
|
+
function_b = Fx::Function.new(
|
|
49
|
+
"name" => "name_b",
|
|
50
|
+
"definition" => "some other definition",
|
|
51
|
+
"arguments" => ""
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
expect(function_a).not_to eq(function_b)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "distinguishes overloads with the same name" do
|
|
58
|
+
add_int = Fx::Function.new(
|
|
59
|
+
"name" => "add",
|
|
60
|
+
"definition" => "CREATE FUNCTION add(integer)",
|
|
61
|
+
"arguments" => "integer"
|
|
62
|
+
)
|
|
63
|
+
add_text = Fx::Function.new(
|
|
64
|
+
"name" => "add",
|
|
65
|
+
"definition" => "CREATE FUNCTION add(text)",
|
|
66
|
+
"arguments" => "text"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
expect(add_int).not_to eq(add_text)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "#signature" do
|
|
74
|
+
it "returns name with arguments when arguments are present" do
|
|
75
|
+
function = Fx::Function.new(
|
|
76
|
+
"name" => "inc",
|
|
77
|
+
"definition" => "some definition",
|
|
78
|
+
"arguments" => "integer"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
expect(function.signature).to eq("inc(integer)")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "returns name with multiple arguments" do
|
|
85
|
+
function = Fx::Function.new(
|
|
86
|
+
"name" => "add",
|
|
87
|
+
"definition" => "some definition",
|
|
88
|
+
"arguments" => "integer, integer"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
expect(function.signature).to eq("add(integer, integer)")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "returns name with empty parens for no-arg functions" do
|
|
95
|
+
function = Fx::Function.new(
|
|
96
|
+
"name" => "now_utc",
|
|
97
|
+
"definition" => "some definition",
|
|
98
|
+
"arguments" => ""
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
expect(function.signature).to eq("now_utc()")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "returns just the name when arguments key is missing" do
|
|
105
|
+
function = Fx::Function.new(
|
|
106
|
+
"name" => "now_utc",
|
|
107
|
+
"definition" => "some definition"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
expect(function.signature).to eq("now_utc")
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "#to_schema" do
|
|
115
|
+
it "returns a schema compatible version of the function" do
|
|
116
|
+
function = Fx::Function.new(
|
|
117
|
+
"name" => "uppercase_users_name",
|
|
118
|
+
"definition" => "CREATE OR REPLACE TRIGGER uppercase_users_name ...",
|
|
119
|
+
"arguments" => ""
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
expect(function.to_schema).to eq(<<-EOS)
|
|
123
|
+
create_function :uppercase_users_name, sql_definition: <<-'SQL'
|
|
124
|
+
CREATE OR REPLACE TRIGGER uppercase_users_name ...
|
|
125
|
+
SQL
|
|
126
|
+
EOS
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "maintains backslashes" do
|
|
130
|
+
function = Fx::Function.new(
|
|
131
|
+
"name" => "regex",
|
|
132
|
+
"definition" => "CREATE OR REPLACE FUNCTION regex \\1",
|
|
133
|
+
"arguments" => ""
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
expect(function.to_schema).to eq(<<-'EOS')
|
|
137
|
+
create_function :regex, sql_definition: <<-'SQL'
|
|
138
|
+
CREATE OR REPLACE FUNCTION regex \1
|
|
139
|
+
SQL
|
|
140
|
+
EOS
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|