fx-jets 0.6.3s

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.hound.yml +2 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +648 -0
  6. data/.travis.yml +60 -0
  7. data/.yardopts +4 -0
  8. data/Appraisals +45 -0
  9. data/CONTRIBUTING.md +15 -0
  10. data/Gemfile +4 -0
  11. data/LICENSE +18 -0
  12. data/README.md +1 -0
  13. data/Rakefile +23 -0
  14. data/bin/appraisal +17 -0
  15. data/bin/console +14 -0
  16. data/bin/rake +17 -0
  17. data/bin/rspec +17 -0
  18. data/bin/setup +13 -0
  19. data/bin/yard +17 -0
  20. data/fx.gemspec +39 -0
  21. data/gemfiles/rails42.gemfile +10 -0
  22. data/gemfiles/rails50.gemfile +8 -0
  23. data/gemfiles/rails51.gemfile +8 -0
  24. data/gemfiles/rails52.gemfile +8 -0
  25. data/gemfiles/rails60.gemfile +8 -0
  26. data/gemfiles/rails61.gemfile +8 -0
  27. data/gemfiles/rails_edge.gemfile +8 -0
  28. data/lib/fx/adapters/postgres/connection.rb +16 -0
  29. data/lib/fx/adapters/postgres/functions.rb +59 -0
  30. data/lib/fx/adapters/postgres/triggers.rb +57 -0
  31. data/lib/fx/adapters/postgres.rb +167 -0
  32. data/lib/fx/command_recorder/arguments.rb +43 -0
  33. data/lib/fx/command_recorder/function.rb +30 -0
  34. data/lib/fx/command_recorder/trigger.rb +30 -0
  35. data/lib/fx/command_recorder.rb +24 -0
  36. data/lib/fx/configuration.rb +48 -0
  37. data/lib/fx/definition.rb +46 -0
  38. data/lib/fx/function.rb +26 -0
  39. data/lib/fx/railtie.rb +15 -0
  40. data/lib/fx/schema_dumper/function.rb +38 -0
  41. data/lib/fx/schema_dumper/trigger.rb +29 -0
  42. data/lib/fx/schema_dumper.rb +10 -0
  43. data/lib/fx/statements/function.rb +115 -0
  44. data/lib/fx/statements/trigger.rb +146 -0
  45. data/lib/fx/statements.rb +11 -0
  46. data/lib/fx/trigger.rb +26 -0
  47. data/lib/fx/version.rb +4 -0
  48. data/lib/fx.rb +43 -0
  49. data/lib/generators/fx/function/USAGE +11 -0
  50. data/lib/generators/fx/function/function_generator.rb +120 -0
  51. data/lib/generators/fx/function/templates/db/migrate/create_function.erb +5 -0
  52. data/lib/generators/fx/function/templates/db/migrate/update_function.erb +5 -0
  53. data/lib/generators/fx/trigger/USAGE +20 -0
  54. data/lib/generators/fx/trigger/templates/db/migrate/create_trigger.erb +5 -0
  55. data/lib/generators/fx/trigger/templates/db/migrate/update_trigger.erb +5 -0
  56. data/lib/generators/fx/trigger/trigger_generator.rb +130 -0
  57. data/lib/generators.rb +11 -0
  58. data/spec/acceptance/user_manages_functions_spec.rb +57 -0
  59. data/spec/acceptance/user_manages_triggers_spec.rb +51 -0
  60. data/spec/acceptance_helper.rb +62 -0
  61. data/spec/dummy/.gitignore +16 -0
  62. data/spec/dummy/Rakefile +13 -0
  63. data/spec/dummy/bin/bundle +3 -0
  64. data/spec/dummy/bin/rails +4 -0
  65. data/spec/dummy/bin/rake +4 -0
  66. data/spec/dummy/config/application.rb +15 -0
  67. data/spec/dummy/config/boot.rb +5 -0
  68. data/spec/dummy/config/database.yml +9 -0
  69. data/spec/dummy/config/environment.rb +5 -0
  70. data/spec/dummy/config.ru +4 -0
  71. data/spec/dummy/db/migrate/.keep +0 -0
  72. data/spec/features/functions/migrations_spec.rb +65 -0
  73. data/spec/features/functions/revert_spec.rb +75 -0
  74. data/spec/features/triggers/migrations_spec.rb +56 -0
  75. data/spec/features/triggers/revert_spec.rb +95 -0
  76. data/spec/fx/adapters/postgres/functions_spec.rb +37 -0
  77. data/spec/fx/adapters/postgres/triggers_spec.rb +45 -0
  78. data/spec/fx/adapters/postgres_spec.rb +146 -0
  79. data/spec/fx/command_recorder/arguments_spec.rb +41 -0
  80. data/spec/fx/command_recorder_spec.rb +171 -0
  81. data/spec/fx/configuration_spec.rb +21 -0
  82. data/spec/fx/definition_spec.rb +134 -0
  83. data/spec/fx/function_spec.rb +68 -0
  84. data/spec/fx/schema_dumper/function_spec.rb +80 -0
  85. data/spec/fx/schema_dumper/trigger_spec.rb +40 -0
  86. data/spec/fx/statements/function_spec.rb +103 -0
  87. data/spec/fx/statements/trigger_spec.rb +132 -0
  88. data/spec/fx/trigger_spec.rb +55 -0
  89. data/spec/generators/fx/function/function_generator_spec.rb +46 -0
  90. data/spec/generators/fx/trigger/trigger_generator_spec.rb +59 -0
  91. data/spec/spec_helper.rb +21 -0
  92. data/spec/support/definition_helpers.rb +37 -0
  93. data/spec/support/generator_setup.rb +11 -0
  94. data/spec/support/migration_helpers.rb +25 -0
  95. metadata +357 -0
@@ -0,0 +1,132 @@
1
+ require "spec_helper"
2
+ require "fx/statements/trigger"
3
+
4
+ describe Fx::Statements::Trigger, :db do
5
+ describe "#create_trigger" do
6
+ it "creates a trigger from a file" do
7
+ database = stubbed_database
8
+ definition = stubbed_definition
9
+
10
+ connection.create_trigger(:test)
11
+
12
+ expect(database).to have_received(:create_trigger).
13
+ with(definition.to_sql)
14
+ expect(Fx::Definition).to have_received(:new).
15
+ with(name: :test, version: 1, type: "trigger")
16
+ end
17
+
18
+ it "allows creating a trigger with a specific version" do
19
+ database = stubbed_database
20
+ definition = stubbed_definition
21
+
22
+ connection.create_trigger(:test, version: 2)
23
+
24
+ expect(database).to have_received(:create_trigger).
25
+ with(definition.to_sql)
26
+ expect(Fx::Definition).to have_received(:new).
27
+ with(name: :test, version: 2, type: "trigger")
28
+ end
29
+
30
+ it "raises an error if both arguments are set" do
31
+ stubbed_database
32
+
33
+ expect {
34
+ connection.create_trigger(
35
+ :whatever,
36
+ version: 1,
37
+ sql_definition: "a definition",
38
+ )
39
+ }.to raise_error(
40
+ ArgumentError,
41
+ /cannot both be set/,
42
+ )
43
+ end
44
+ end
45
+
46
+ describe "#drop_trigger" do
47
+ it "drops the trigger" do
48
+ database = stubbed_database
49
+
50
+ connection.drop_trigger(:test, on: :users)
51
+
52
+ expect(database).to have_received(:drop_trigger).
53
+ with(:test, on: :users)
54
+ end
55
+ end
56
+
57
+ describe "#update_trigger" do
58
+ it "updates the trigger" do
59
+ database = stubbed_database
60
+ definition = stubbed_definition
61
+
62
+ connection.update_trigger(:test, on: :users, version: 3)
63
+
64
+ expect(database).to have_received(:update_trigger).with(
65
+ :test,
66
+ on: :users,
67
+ sql_definition: definition.to_sql,
68
+ )
69
+ expect(Fx::Definition).to have_received(:new).with(
70
+ name: :test,
71
+ version: 3,
72
+ type: "trigger",
73
+ )
74
+ end
75
+
76
+ it "updates a trigger from a text definition" do
77
+ database = stubbed_database
78
+
79
+ connection.update_trigger(
80
+ :test,
81
+ on: :users,
82
+ sql_definition: "a definition",
83
+ )
84
+
85
+ expect(database).to have_received(:update_trigger).with(
86
+ :test,
87
+ on: :users,
88
+ sql_definition: "a definition",
89
+ )
90
+ end
91
+
92
+ it "raises an error if not supplied a version" do
93
+ expect {
94
+ connection.update_trigger(
95
+ :whatever,
96
+ version: nil,
97
+ sql_definition: nil,
98
+ )
99
+ }.to raise_error(
100
+ ArgumentError,
101
+ /version or sql_definition must be specified/,
102
+ )
103
+ end
104
+
105
+ it "raises an error if both arguments are set" do
106
+ stubbed_database
107
+
108
+ expect {
109
+ connection.update_trigger(
110
+ :whatever,
111
+ version: 1,
112
+ sql_definition: "a definition",
113
+ )
114
+ }.to raise_error(
115
+ ArgumentError,
116
+ /cannot both be set/,
117
+ )
118
+ end
119
+ end
120
+
121
+ def stubbed_database
122
+ instance_spy("StubbedDatabase").tap do |stubbed_database|
123
+ allow(Fx).to receive(:database).and_return(stubbed_database)
124
+ end
125
+ end
126
+
127
+ def stubbed_definition
128
+ instance_double("Fx::Definition", to_sql: nil).tap do |stubbed_definition|
129
+ allow(Fx::Definition).to receive(:new).and_return(stubbed_definition)
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+ require "fx/trigger"
3
+
4
+ module Fx
5
+ describe Trigger do
6
+ describe "#<=>" do
7
+ it "delegates to `name`" do
8
+ trigger_a = Trigger.new(
9
+ "name" => "name_a",
10
+ "definition" => "some defintion",
11
+ )
12
+ trigger_b = Trigger.new(
13
+ "name" => "name_b",
14
+ "definition" => "some defintion",
15
+ )
16
+ trigger_c = Trigger.new(
17
+ "name" => "name_c",
18
+ "definition" => "some defintion",
19
+ )
20
+
21
+ expect(trigger_b).to be_between(trigger_a, trigger_c)
22
+ end
23
+ end
24
+
25
+ describe "#==" do
26
+ it "compares `name` and `definition`" do
27
+ trigger_a = Trigger.new(
28
+ "name" => "name_a",
29
+ "definition" => "some defintion",
30
+ )
31
+ trigger_b = Trigger.new(
32
+ "name" => "name_b",
33
+ "definition" => "some other defintion",
34
+ )
35
+
36
+ expect(trigger_a).not_to eq(trigger_b)
37
+ end
38
+ end
39
+
40
+ describe "#to_schema" do
41
+ it "returns a schema compatible version of the trigger" do
42
+ trigger = Trigger.new(
43
+ "name" => "uppercase_users_name",
44
+ "definition" => "CREATE TRIGGER uppercase_users_name ...",
45
+ )
46
+
47
+ expect(trigger.to_schema).to eq <<-EOS
48
+ create_trigger :uppercase_users_name, sql_definition: <<-\SQL
49
+ CREATE TRIGGER uppercase_users_name ...
50
+ SQL
51
+ EOS
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+ require "generators/fx/function/function_generator"
3
+
4
+ describe Fx::Generators::FunctionGenerator, :generator do
5
+ it "creates a function definition file, and a migration" do
6
+ migration = file("db/migrate/create_function_test.rb")
7
+ function_definition = file("db/functions/test_v01.sql")
8
+
9
+ run_generator ["test"]
10
+
11
+ expect(function_definition).to exist
12
+ expect(migration).to be_a_migration
13
+ expect(migration_file(migration)).to contain "CreateFunctionTest"
14
+ end
15
+
16
+ context "when passed --no-migration" do
17
+ it "creates a only function definition file" do
18
+ migration = file("db/migrate/create_function_test.rb")
19
+ function_definition = file("db/functions/test_v01.sql")
20
+
21
+ run_generator ["test", "--no-migration"]
22
+
23
+ expect(function_definition).to exist
24
+ expect(migration_file(migration)).not_to exist
25
+ end
26
+ end
27
+
28
+ it "updates an existing function" do
29
+ with_function_definition(
30
+ name: "test",
31
+ version: 1,
32
+ sql_definition: "hello",
33
+ ) do
34
+ allow(Dir).to receive(:entries).and_return(["test_v01.sql"])
35
+ migration = file("db/migrate/update_function_test_to_version_2.rb")
36
+ function_definition = file("db/functions/test_v02.sql")
37
+
38
+ run_generator ["test"]
39
+
40
+ expect(function_definition).to exist
41
+ expect(migration).to be_a_migration
42
+ expect(migration_file(migration)).
43
+ to contain("UpdateFunctionTestToVersion2")
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,59 @@
1
+ require "spec_helper"
2
+ require "generators/fx/trigger/trigger_generator"
3
+
4
+ describe Fx::Generators::TriggerGenerator, :generator do
5
+ it "creates a trigger definition file, and a migration" do
6
+ migration = file("db/migrate/create_trigger_test.rb")
7
+ trigger_definition = file("db/triggers/test_v01.sql")
8
+
9
+ run_generator ["test", "table_name" => "some_table"]
10
+
11
+ expect(trigger_definition).to exist
12
+ expect(migration).to be_a_migration
13
+ expect(migration_file(migration)).to contain "CreateTriggerTest"
14
+ expect(migration_file(migration)).to contain "on: :some_table"
15
+ end
16
+
17
+ context "when passed --no-migration" do
18
+ it "creates a only trigger definition file" do
19
+ migration = file("db/migrate/create_trigger_test.rb")
20
+ trigger_definition = file("db/triggers/test_v01.sql")
21
+
22
+ run_generator ["test", {"table_name" => "some_table"}, "--no-migration"]
23
+
24
+ expect(trigger_definition).to exist
25
+ expect(migration_file(migration)).not_to exist
26
+ end
27
+ end
28
+
29
+ it "supports naming the table as `on` aswell as `table_name`" do
30
+ migration = file("db/migrate/create_trigger_test.rb")
31
+ trigger_definition = file("db/triggers/test_v01.sql")
32
+
33
+ run_generator ["test", "on" => "some_table"]
34
+
35
+ expect(trigger_definition).to exist
36
+ expect(migration).to be_a_migration
37
+ expect(migration_file(migration)).to contain "CreateTriggerTest"
38
+ expect(migration_file(migration)).to contain "on: :some_table"
39
+ end
40
+
41
+ it "requires `table_name` or `on` to be specified" do
42
+ expect {
43
+ run_generator ["test", "foo" => "some_table"]
44
+ }.to raise_error ArgumentError
45
+ end
46
+
47
+ it "updates an existing trigger" do
48
+ allow(Dir).to receive(:entries).and_return(["test_v01.sql"])
49
+ migration = file("db/migrate/update_trigger_test_to_version_2.rb")
50
+ trigger_definition = file("db/triggers/test_v02.sql")
51
+
52
+ run_generator ["test", "table_name" => "some_table"]
53
+
54
+ expect(trigger_definition).to exist
55
+ expect(migration).to be_a_migration
56
+ expect(migration_file(migration)).to contain "UpdateTriggerTestToVersion2"
57
+ expect(migration_file(migration)).to contain "on: :some_table"
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require "database_cleaner"
3
+
4
+ require File.expand_path("../dummy/config/environment", __FILE__)
5
+ Dir["spec/support/**/*.rb"].sort.each { |file| load file }
6
+
7
+ RSpec.configure do |config|
8
+ config.order = "random"
9
+ DatabaseCleaner.strategy = :transaction
10
+
11
+ config.around(:each, db: true) do |example|
12
+ DatabaseCleaner.start
13
+ example.run
14
+ DatabaseCleaner.clean
15
+ end
16
+
17
+ unless defined?(silence_stream)
18
+ require "active_support/testing/stream"
19
+ config.include ActiveSupport::Testing::Stream
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ module DefinitionHelpers
2
+ def with_function_definition(name:, sql_definition:, version: 1, &block)
3
+ definition = Fx::Definition.new(name: name, version: version)
4
+
5
+ with_definition(
6
+ definition: definition,
7
+ sql_definition: sql_definition,
8
+ block: block,
9
+ )
10
+ end
11
+
12
+ def with_trigger_definition(name:, sql_definition:, version: 1, &block)
13
+ definition = Fx::Definition.new(
14
+ name: name,
15
+ version: version,
16
+ type: "trigger",
17
+ )
18
+
19
+ with_definition(
20
+ definition: definition,
21
+ sql_definition: sql_definition,
22
+ block: block,
23
+ )
24
+ end
25
+
26
+ def with_definition(definition:, sql_definition:, block:)
27
+ FileUtils.mkdir_p(File.dirname(definition.full_path))
28
+ File.open(definition.full_path, "w") { |f| f.write(sql_definition) }
29
+ block.call
30
+ ensure
31
+ File.delete definition.full_path
32
+ end
33
+ end
34
+
35
+ RSpec.configure do |config|
36
+ config.include DefinitionHelpers
37
+ end
@@ -0,0 +1,11 @@
1
+ require "ammeter/init"
2
+
3
+ RSpec.configure do |config|
4
+ config.before(:each, :generator) do
5
+ fake_rails_root = File.expand_path("../../../tmp", __FILE__)
6
+ allow(Rails).to receive(:root).and_return(Pathname.new(fake_rails_root))
7
+
8
+ destination fake_rails_root
9
+ prepare_destination
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module MigrationsHelper
2
+ def run_migration(migration, directions)
3
+ silence_stream(STDOUT) do
4
+ Array.wrap(directions).each do |direction|
5
+ migration.migrate(direction)
6
+ end
7
+ end
8
+ end
9
+
10
+ def migration_class
11
+ if Rails::VERSION::MAJOR >= 5
12
+ ::ActiveRecord::Migration[5.0]
13
+ else
14
+ ::ActiveRecord::Migration
15
+ end
16
+ end
17
+
18
+ def connection
19
+ @_connection ||= ActiveRecord::Base.connection
20
+ end
21
+ end
22
+
23
+ RSpec.configure do |config|
24
+ config.include MigrationsHelper
25
+ end