dbexpect 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +41 -0
  4. data/COPYING +674 -0
  5. data/Gemfile +20 -0
  6. data/Gemfile.lock +45 -0
  7. data/LICENSE.txt +2 -0
  8. data/README.md +106 -0
  9. data/Rakefile +65 -0
  10. data/VERSION +1 -0
  11. data/bin/dbexpect +33 -0
  12. data/bin/great-expectations +28 -0
  13. data/bin/ready-rig +27 -0
  14. data/database.yml +9 -0
  15. data/lib/dbexpect.rb +19 -0
  16. data/lib/dbexpect/command_runner.rb +21 -0
  17. data/lib/dbexpect/console_formatter.rb +40 -0
  18. data/lib/dbexpect/d_s_l_parser.rb +124 -0
  19. data/lib/dbexpect/database.rb +59 -0
  20. data/lib/dbexpect/db_null.rb +25 -0
  21. data/lib/dbexpect/db_sequence.rb +26 -0
  22. data/lib/dbexpect/db_string.rb +29 -0
  23. data/lib/dbexpect/dbexpect.rb +87 -0
  24. data/lib/dbexpect/defaulting_row_set.rb +68 -0
  25. data/lib/dbexpect/expectation_checker.rb +32 -0
  26. data/lib/dbexpect/expectation_tree_node.rb +67 -0
  27. data/lib/dbexpect/expectations/expectation.rb +45 -0
  28. data/lib/dbexpect/expectations/row_count_expectation.rb +32 -0
  29. data/lib/dbexpect/expectations/row_expectation.rb +32 -0
  30. data/lib/dbexpect/odbc_connection.rb +47 -0
  31. data/lib/dbexpect/row.rb +43 -0
  32. data/lib/dbexpect/table.rb +71 -0
  33. data/spec/dbexpect_integration_spec.rb +131 -0
  34. data/spec/defaulting_row_set_spec.rb +37 -0
  35. data/spec/expectation_checker_spec.rb +47 -0
  36. data/spec/expectations/row_expectation_spec.rb +51 -0
  37. data/spec/fixtures/basic_test_expected_inserts.sql +6 -0
  38. data/spec/fixtures/cleanup_db.sql +2 -0
  39. data/spec/fixtures/expected_output.txt +11 -0
  40. data/spec/fixtures/sample_db.sql +12 -0
  41. data/spec/fixtures/sample_project/database.yml +9 -0
  42. data/spec/fixtures/sample_project/defaults/defaults.rb +5 -0
  43. data/spec/fixtures/sample_project/tests/basic_test.rb +41 -0
  44. data/spec/fixtures/sample_project/tests/test2.rb +3 -0
  45. data/spec/spec_helper.rb +28 -0
  46. metadata +186 -0
@@ -0,0 +1,59 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ require_relative 'odbc_connection'
18
+
19
+ class Database
20
+ def self.from_connection(con)
21
+ new(con)
22
+ end
23
+
24
+ def self.hash_from_config
25
+ databases = {}
26
+ YAML.load_file('database.yml').each do |(dsn,config)|
27
+ databases[dsn.to_sym] = from_connection(OdbcConnection.new(dsn,config))
28
+ end
29
+
30
+ databases
31
+ end
32
+
33
+ def initialize(con)
34
+ @connection = con
35
+ end
36
+
37
+ def num_rows_match(schema,table,query)
38
+ @connection.run("select * from #{schema}.#{table} where (#{query})").count
39
+ end
40
+
41
+ def truncate_table(schema,name)
42
+ if @connection.type == 'db2'
43
+ @connection.run("truncate table #{schema}.#{name} immediate")
44
+ else
45
+ @connection.run("truncate table #{schema}.#{name}")
46
+ end
47
+ end
48
+
49
+ def insert_rows(insert_statements)
50
+ insert_statements.each do |stmt|
51
+ @connection.run(stmt)
52
+ end
53
+ end
54
+
55
+ def close
56
+ #@connection.close
57
+ end
58
+
59
+ end
@@ -0,0 +1,25 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ class DbNull
18
+ def db_str
19
+ 'NULL'
20
+ end
21
+
22
+ def equality_test
23
+ "is null"
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ class DbSequence
18
+ def initialize
19
+ @sequence = 0
20
+ end
21
+
22
+ def db_str
23
+ @sequence += 1
24
+ @sequence.to_s
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ class DbString
18
+ def initialize(str)
19
+ @string = str
20
+ end
21
+
22
+ def db_str
23
+ "'#{@string}'"
24
+ end
25
+
26
+ def equality_test
27
+ " = '#{@string}'"
28
+ end
29
+ end
@@ -0,0 +1,87 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ require_relative 'db_sequence'
18
+ require_relative 'db_null'
19
+ require_relative 'db_string'
20
+ require_relative 'table'
21
+ require_relative 'd_s_l_parser'
22
+ require_relative 'expectation_checker'
23
+ require_relative 'console_formatter'
24
+
25
+ class Dbexpect
26
+
27
+ def initialize(output = STDOUT)
28
+ @output = ConsoleFormatter.new(output)
29
+ end
30
+
31
+ def run_test(script,databases,command_runner)
32
+ setup_test(script,databases)
33
+ run_etl(script,command_runner)
34
+ great_expectations(script,databases)
35
+ end
36
+
37
+ def great_expectations(script, databases)
38
+ eval_script(script)
39
+
40
+ check_table_expectations(databases)
41
+
42
+ if validates_expectations?
43
+ @output.notify_passed
44
+ return 0
45
+ else
46
+ @output.notify_failed(failed_expectations)
47
+ return 1
48
+ end
49
+ end
50
+
51
+ def setup_test(script,databases)
52
+ eval_script(script)
53
+ @tables.each do |table|
54
+ table.set_up_for_test(databases)
55
+ end
56
+ return 0
57
+ end
58
+
59
+
60
+ protected
61
+ def run_etl(script,command_runner)
62
+ @commands_to_run.each {|c| command_runner.run(c) }
63
+ end
64
+
65
+ def eval_script(script)
66
+ parser = DSLParser.new
67
+ parser.parse(File.read(script))
68
+ @tables = parser.tables
69
+ @expectation_tree = parser.expectation_tree
70
+ @commands_to_run = parser.commands
71
+ end
72
+
73
+ def check_table_expectations(databases)
74
+ @expectation_checker = ExpectationChecker.new(databases)
75
+ @expectation_checker.check_expectations(@expectation_tree)
76
+ end
77
+
78
+ def failed_expectations
79
+ @expectation_checker.failed_expectations
80
+ end
81
+
82
+ def validates_expectations?
83
+ @expectation_checker.validates_expectations?
84
+ end
85
+
86
+ end
87
+
@@ -0,0 +1,68 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ require_relative 'row'
18
+ class DefaultingRowSet
19
+ attr_accessor :defaults
20
+ attr_accessor :columns_in_order
21
+ attr_accessor :rows
22
+
23
+ def initialize
24
+ @defaults = Hash.new
25
+ @rows = []
26
+
27
+ @columns_in_order = []
28
+ end
29
+
30
+ def set_default(column,value)
31
+ add_column(column)
32
+ @defaults[column] = value
33
+ end
34
+
35
+ def add_row(column_values)
36
+ column_values.keys.map {|col| add_column(col) }
37
+
38
+ defaulted_row = set_defaults_at_time_of_addition(column_values)
39
+ @rows << Row.new(defaulted_row,@columns_in_order & defaulted_row.keys)
40
+ @rows.last
41
+ end
42
+
43
+ def insert_statements(schema,name)
44
+ @rows.collect do |row|
45
+ row.insert_stmt(schema,name)
46
+ end
47
+ end
48
+
49
+ def where_clauses
50
+ @rows.map(&:where_clause)
51
+ end
52
+
53
+ def empty?
54
+ @rows.empty?
55
+ end
56
+
57
+ protected
58
+ def add_column(column)
59
+ @columns_in_order << column
60
+ @columns_in_order.uniq!
61
+ end
62
+
63
+ def set_defaults_at_time_of_addition(row)
64
+ @defaults.merge(row)
65
+ end
66
+
67
+
68
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ class ExpectationChecker
18
+ attr_accessor :failed_expectations
19
+ def initialize(databases)
20
+ @databases = databases
21
+ end
22
+
23
+ def check_expectations(expectations)
24
+ expectations.map {|e| e.validate_expectation(@databases) }
25
+
26
+ @failed_expectations = expectations.select {|e| e.failed_validation? }
27
+ end
28
+
29
+ def validates_expectations?
30
+ @failed_expectations.empty?
31
+ end
32
+ end
@@ -0,0 +1,67 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ class ExpectationTreeNode
18
+ include Enumerable
19
+
20
+ def initialize(desc,children = [], expectations = [])
21
+ @description = desc
22
+ @children = children
23
+ @expectations = expectations
24
+ end
25
+
26
+ def each(&block)
27
+ @expectations.map(&block)
28
+ @children.each {|c| c.each(&block) }
29
+ end
30
+
31
+ def select(&block)
32
+ matching_children = @children.collect {|c| c.select(&block) }.
33
+ reject {|node| node === EmptyTreeNode }
34
+
35
+ matching_expectations = @expectations.select(&block)
36
+
37
+ return EmptyTreeNode.new if matching_children.empty? && matching_expectations.empty?
38
+
39
+ ExpectationTreeNode.new(@description,matching_children,matching_expectations)
40
+ end
41
+
42
+ def create_child(desc)
43
+ @children << ExpectationTreeNode.new(desc)
44
+ @children.last
45
+ end
46
+
47
+ def add(expectations)
48
+ @expectations += expectations
49
+ end
50
+
51
+ def empty?
52
+ @expectations.empty? && @children.all?(&:empty?)
53
+ end
54
+
55
+ def traverse(depth = 0, &block)
56
+ block.call(depth,@description,@expectations)
57
+ @children.map {|c| c.traverse(depth + 1, &block) }
58
+ end
59
+
60
+ class EmptyTreeNode
61
+ include Enumerable
62
+ def each(&block); end
63
+ def empty?; true; end
64
+ def traverse(depth = 0, &block)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,45 @@
1
+ # Copyright 2012 C3 Business Solutions
2
+ #
3
+ # This file is part of dbexpect.
4
+ #
5
+ # dbexpect is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # dbexpect is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with dbexpect. If not, see <http://www.gnu.org/licenses/>.
17
+ class Expectation
18
+ def initialize(db_name,schema,table)
19
+ @schema = schema
20
+ @table = table
21
+ @db_name = db_name
22
+ end
23
+
24
+ def validate_expectation(databases)
25
+ database = databases[@db_name]
26
+ begin
27
+ num = database.num_rows_match(@schema,@table,where_clause)
28
+ rescue OdbcConnection::DatabaseException => e
29
+ @failure = expect_msg + "instead database raised error: #{e.message}"
30
+ return
31
+ end
32
+
33
+ if num != @count
34
+ @failure = expect_msg + "got #{num}"
35
+ end
36
+ end
37
+
38
+ def failed_validation?
39
+ @failure
40
+ end
41
+
42
+ def failure_message
43
+ @failure
44
+ end
45
+ end