data_verifier 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de8e7ec5961659d85a8c7fa92ae6e460ac62acddcf2699962f594cb6a3815014
4
- data.tar.gz: 13d7a34878d79d2abb31b94112c266c8cae8f96ed40c2c8fe05d25cc003a73a3
3
+ metadata.gz: 0f8aaa56a85ac1b493591067a74994a348f336b20b541149951d1fb61abcb5bf
4
+ data.tar.gz: ee108239cb4359371ba74eb6b7ad0bf3a29ee353e65cc718578da49ab9e32da0
5
5
  SHA512:
6
- metadata.gz: 7e50ce971d0c01a5ebc1661cd09a3a35e057bfa3472c8d2e154fbb51bac431e745ddcde3b6e21c50de484fbc11cc568963ab4e60354b16bbc687ca45294e7786
7
- data.tar.gz: 7f346802c64d4e0682a8fabf8530ee83cb1a1c920ec0f0c32cae50ff554405d98d250a8c0b439c17b87e603e24be5a179916835e4b5acbb5fc79115688d2d432
6
+ metadata.gz: f96afe9be08894e1a399f157e0481d4de1ae6e0ef37b6f104b8e664d7c9344a37195fe70e930bfe37043360eff83afec3f18231f5017f9b67f7879088acd214f
7
+ data.tar.gz: 576a9b67c836258bde3b18de79333f4d0adc22d0deb123100af5cf77b663a17613faf818fcf59218bb4d45b5c5e99197dcb9bd54da758b0caf0e25c37d361516
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Ajit Singh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # data_verifier
2
+
3
+ There are times when we change the approach of modifying data and want to verify
4
+ that the data modified by the new approach is same as the old approach.
5
+ This gem is build for such verifications.
6
+
7
+ ## Motivation
8
+
9
+ In my project, we replicate the data from other systems. There was a requirement where we changed the source of the data
10
+ and code to replicate the data to our system. In testing phase we wanted to create a validation sheet,
11
+ which can show the difference b/w the data in our system before and after the new source.
12
+
13
+ ## Installation
14
+ Add this line to your application's Gemfile:
15
+ ```ruby
16
+ gem 'data_verifier'
17
+ ```
18
+
19
+ ## Usage
20
+ This gem has to be used in two phases:
21
+
22
+ 1. Build Phase: Use this phase to build the baseline of the data before changing the code/approach
23
+ 2. Verification Phase: Use this phase to verify the new data against the baseline data
24
+
25
+ #### Config:
26
+
27
+ ```ruby
28
+ require 'data_verifier'
29
+
30
+ QUERIES = {
31
+ users_table: "select * from users where id=100",
32
+ phones_table: "select * from phones where user_id=100",
33
+ addresses_table: "select * from addresses where user_id=100",
34
+ }
35
+
36
+ config = DataVerifier::Config.new do |c|
37
+ c.db_adapter = :oracle
38
+ c.db_user = 'my_db_user'
39
+ c.db_password = 'my_pass'
40
+ c.db_host = 'localhost'
41
+ c.db_name = 'test_db'
42
+ c.db_port = '1521'
43
+ c.data_identifier = 'user_id_100'
44
+ c.queries = QUERIES
45
+ end
46
+ ```
47
+
48
+ #### Building Baseline Data:
49
+
50
+ The below code will execute all the queries and store their result in json files.
51
+
52
+ ```ruby
53
+ DataVerifier::BaselineBuilder.new(config).build
54
+ ```
55
+
56
+ #### Verification:
57
+
58
+ Below code will again execute the queries and will compare it with the baseline data.
59
+ After comparision it will create an excel file of the result.
60
+
61
+ ```ruby
62
+ DataVerifier::Validator.new(config).generate_validation_file
63
+ ```
64
+
65
+ #### Result:
66
+
67
+ <img src="https://github.com/ajitsing/ScreenShots/blob/master/data_verifier/data_verifier_result.png"/>
68
+
69
+ ## License
70
+ ```license
71
+ MIT License
72
+
73
+ Copyright (c) 2019 Ajit Singh
74
+
75
+ Permission is hereby granted, free of charge, to any person obtaining a copy
76
+ of this software and associated documentation files (the "Software"), to deal
77
+ in the Software without restriction, including without limitation the rights
78
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79
+ copies of the Software, and to permit persons to whom the Software is
80
+ furnished to do so, subject to the following conditions:
81
+
82
+ The above copyright notice and this permission notice shall be included in all
83
+ copies or substantial portions of the Software.
84
+
85
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
86
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
87
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
88
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
89
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
90
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
91
+ SOFTWARE.
92
+ ```
@@ -3,32 +3,44 @@ require 'sequel'
3
3
 
4
4
  module DataVerifier
5
5
  class BaselineBuilder
6
- def initialize(config)
7
- @config = config
8
- @db = Sequel.connect(adapter: @config.db_adapter,
9
- user: @config.db_user,
10
- password: @config.db_password,
11
- host: @config.db_host,
12
- port: @config.db_port,
13
- database: @config.db_name,
14
- max_connections: @config.db_max_connections)
6
+ def initialize
7
+ @configs = []
8
+ end
9
+
10
+ def with(config)
11
+ @configs << config
12
+ self
15
13
  end
16
14
 
17
15
  def build
18
- @config.queries.each do |tag, query|
19
- puts "Executing => #{query}\n"
20
- data = @db.fetch(query)
16
+ @configs.each do |config|
17
+ db = create_db_connection(config)
18
+
19
+ config.queries.each do |tag, query|
20
+ puts "Executing => #{query}\n"
21
+ data = db.fetch(query)
21
22
 
22
- File.open(data_file_name(tag), 'w') do |file|
23
- file.write JSON.dump(data.all)
23
+ File.open(data_file_name(config, tag), 'w') do |file|
24
+ file.write JSON.dump(data.all)
25
+ end
24
26
  end
25
27
  end
26
28
  end
27
29
 
28
30
  private
29
- def data_file_name(tag)
30
- identifier = @config.data_identifier.nil? ? '' : "#{@config.data_identifier}_"
31
+ def data_file_name(config, tag)
32
+ identifier = config.data_identifier.nil? ? '' : "#{config.data_identifier}_"
31
33
  "#{identifier}#{tag}.json"
32
34
  end
35
+
36
+ def create_db_connection(config)
37
+ Sequel.connect(adapter: config.db_adapter,
38
+ user: config.db_user,
39
+ password: config.db_password,
40
+ host: config.db_host,
41
+ port: config.db_port,
42
+ database: config.db_name,
43
+ max_connections: config.db_max_connections)
44
+ end
33
45
  end
34
46
  end
@@ -4,71 +4,99 @@ require 'axlsx'
4
4
 
5
5
  module DataVerifier
6
6
  class Validator
7
- def initialize(config)
8
- @config = config
9
- @db = Sequel.connect(adapter: @config.db_adapter,
10
- user: @config.db_user,
11
- password: @config.db_password,
12
- host: @config.db_host,
13
- port: @config.db_port,
14
- database: @config.db_name,
15
- max_connections: @config.db_max_connections)
7
+ def initialize(report_name = 'data_verifier')
8
+ @report_name = report_name
9
+ @excel = Axlsx::Package.new
16
10
  end
17
11
 
18
- def generate_validation_file
19
- excel = Axlsx::Package.new
12
+ def validate_using(config)
13
+ db = create_db_connection(config)
20
14
 
21
- @config.queries.each do |tag, query|
15
+ config.queries.each do |tag, query|
22
16
  puts "Executing => #{query}\n"
23
- data = @db.fetch(query)
24
- update_excel(excel, tag, data)
17
+
18
+ new_data = db.fetch(query)
19
+ old_data = JSON.parse(File.read(data_file_name(config, tag)))
20
+
21
+ update_excel(tag, new_data, old_data)
25
22
  end
26
23
 
27
- excel.serialize("#{identifier}data_verifier_result.xlsx")
24
+ self
28
25
  end
29
26
 
30
- private
31
- def data_file_name(tag)
32
- "#{identifier}#{tag}.json"
27
+ def generate_report
28
+ @excel.serialize("#{@report_name}.xlsx")
33
29
  end
34
30
 
35
- def identifier
36
- @config.data_identifier.nil? ? '' : "#{@config.data_identifier}_"
31
+ private
32
+ def create_db_connection(config)
33
+ Sequel.connect(adapter: config.db_adapter,
34
+ user: config.db_user,
35
+ password: config.db_password,
36
+ host: config.db_host,
37
+ port: config.db_port,
38
+ database: config.db_name,
39
+ max_connections: config.db_max_connections)
37
40
  end
38
41
 
39
- def update_excel(excel, sheet_name, data)
40
- data_before_replication = JSON.parse(File.read(data_file_name(sheet_name)))
41
-
42
- excel.workbook.add_worksheet(name: sheet_name.to_s) do |s|
43
- red_color = Axlsx::Color.new
44
- red_color.rgb = 'C40101'
42
+ def update_excel(sheet_name, new_data, old_data)
43
+ header_color = "43B275"
44
+ header = %w(Field Before After)
45
45
 
46
- white_color = Axlsx::Color.new
47
- white_color.rgb = 'FFFFFF'
46
+ header_style_opts = {bg_color: header_color, b: true, sz: 16, alignment: {horizontal: :center}, color: white_color}
47
+ data_style_opts = {sz: 13, alignment: {horizontal: :left}}
48
+ error_style_opts = {sz: 12, alignment: {horizontal: :left}, color: red_color, b: true}
48
49
 
49
- header_style = s.styles.add_style bg_color: "43B275", b: true, sz: 16, alignment: {horizontal: :center}, color: white_color
50
- data_style = s.styles.add_style sz: 13, alignment: {:horizontal => :left}
51
- error_data_style = s.styles.add_style sz: 12, alignment: {:horizontal => :left}, color: red_color, b: true
50
+ @excel.workbook.add_worksheet(name: sheet_name.to_s) do |s|
51
+ header_style = s.styles.add_style header_style_opts
52
+ data_style = s.styles.add_style data_style_opts
53
+ error_data_style = s.styles.add_style error_style_opts
52
54
 
53
- s.add_row ["Field", "Before", "After"], style: header_style
55
+ s.add_row header, style: header_style
54
56
  s.row_style(0, header_style)
55
57
 
56
- data.each_with_index do |db_row, index|
57
- stored_result = data_before_replication[index]
58
+ new_data.each_with_index do |db_row, index|
59
+ baseline_row = old_data[index]
58
60
 
59
- db_row.each do |column, value|
60
- value_not_eql = stored_result[column.to_s].to_s != value.to_s
61
- data = [column.to_s.upcase, stored_result[column.to_s].to_s, value.to_s]
61
+ db_row.each do |db_field, new_value|
62
+ field = db_field.to_s.upcase
63
+ old_value = baseline_row.nil? ? "" : baseline_row[db_field.to_s].to_s
64
+ cell_style = old_value == new_value.to_s ? data_style : error_data_style
62
65
 
63
- conditional_formatting = value_not_eql ? error_data_style : data_style
64
- s.add_row data, style: [conditional_formatting, data_style, data_style]
66
+ s.add_row [field, old_value, new_value.to_s], style: [cell_style, cell_style, cell_style]
65
67
  end
66
68
 
67
- s.add_row ["", "", ""]
68
- s.add_row ["", "", ""], style: [header_style, header_style, header_style]
69
- s.add_row ["", "", ""]
69
+ s.add_row empty_row
70
+ s.add_row empty_row, style: [header_style, header_style, header_style]
71
+ s.add_row empty_row
70
72
  end
71
73
  end
72
74
  end
75
+
76
+ def data_file_name(config, tag)
77
+ "#{identifier(config)}#{tag}.json"
78
+ end
79
+
80
+ def identifier(config)
81
+ config.data_identifier.nil? ? '' : "#{config.data_identifier}_"
82
+ end
83
+
84
+ def empty_row
85
+ ["", "", ""]
86
+ end
87
+
88
+ def red_color
89
+ red_color = Axlsx::Color.new
90
+ red_color.rgb = 'C40101'
91
+
92
+ red_color
93
+ end
94
+
95
+ def white_color
96
+ white_color = Axlsx::Color.new
97
+ white_color.rgb = 'FFFFFF'
98
+
99
+ white_color
100
+ end
73
101
  end
74
102
  end
@@ -1,3 +1,3 @@
1
1
  module DataVerifier
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -0,0 +1,50 @@
1
+ require 'data_verifier'
2
+
3
+ describe DataVerifier::BaselineBuilder do
4
+ describe '#build' do
5
+ let(:db) {double(:db)}
6
+
7
+ before(:each) do
8
+ expect(Sequel).to receive(:connect).and_return(db)
9
+ end
10
+
11
+ it 'should execute queries and store result in json files' do
12
+ queries = {
13
+ users_table: 'select * from users where id=100',
14
+ addresses_table: 'select * from addresses where user_id=100'
15
+ }
16
+
17
+ config = DataVerifier::Config.new do |c|
18
+ c.data_identifier = '100'
19
+ c.queries = queries
20
+ end
21
+
22
+ builder = DataVerifier::BaselineBuilder.new
23
+
24
+ expect(db).to receive(:fetch).with(queries[:users_table]).and_return(double(:users))
25
+ expect(db).to receive(:fetch).with(queries[:addresses_table]).and_return(double(:addresses))
26
+
27
+ expect(File).to receive(:open).with('100_users_table.json', 'w')
28
+ expect(File).to receive(:open).with('100_addresses_table.json', 'w')
29
+
30
+ builder.with(config).build
31
+ end
32
+
33
+ it 'should not add prefix to json files when identifier is not given' do
34
+ queries = {
35
+ users_table: 'select * from users where id=100'
36
+ }
37
+
38
+ config = DataVerifier::Config.new do |c|
39
+ c.queries = queries
40
+ end
41
+
42
+ builder = DataVerifier::BaselineBuilder.new
43
+
44
+ expect(db).to receive(:fetch).with(queries[:users_table]).and_return(double(:users))
45
+ expect(File).to receive(:open).with('users_table.json', 'w')
46
+
47
+ builder.with(config).build
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,44 @@
1
+ require 'data_verifier'
2
+
3
+ describe DataVerifier::Validator do
4
+ describe '#generate_validation_file' do
5
+ let(:db) {double(:db)}
6
+
7
+ before(:each) do
8
+ expect(Sequel).to receive(:connect).and_return(db)
9
+ end
10
+
11
+ it 'should create result excel file' do
12
+ queries = {
13
+ users_table: 'select * from users where id=100',
14
+ addresses_table: 'select * from addresses where user_id=100'
15
+ }
16
+
17
+ config = DataVerifier::Config.new do |c|
18
+ c.data_identifier = '100'
19
+ c.queries = queries
20
+ end
21
+
22
+ excel = double(:excel)
23
+ expect(Axlsx::Package).to receive(:new).and_return(excel)
24
+
25
+ validator = DataVerifier::Validator.new('test_result')
26
+
27
+ expect(db).to receive(:fetch).with(queries[:users_table]).and_return(double(:users))
28
+ expect(db).to receive(:fetch).with(queries[:addresses_table]).and_return(double(:addresses))
29
+
30
+ expect(File).to receive(:read).with('100_users_table.json').and_return("{}")
31
+ expect(File).to receive(:read).with('100_addresses_table.json').and_return("{}")
32
+
33
+ work_book = double(:workbook)
34
+ expect(excel).to receive(:workbook).and_return(work_book).twice
35
+
36
+ expect(work_book).to receive(:add_worksheet).with(name: 'users_table')
37
+ expect(work_book).to receive(:add_worksheet).with(name: 'addresses_table')
38
+
39
+ expect(excel).to receive(:serialize).with('test_result.xlsx')
40
+
41
+ validator.validate_using(config).generate_report
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_verifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajit Singh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-16 00:00:00.000000000 Z
11
+ date: 2019-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: axlsx
@@ -75,12 +75,16 @@ files:
75
75
  - ".gitignore"
76
76
  - Gemfile
77
77
  - Gemfile.lock
78
+ - LICENSE
79
+ - README.md
78
80
  - data_verifier.gemspec
79
81
  - lib/data_verifier.rb
80
82
  - lib/data_verifier/baseline_builder.rb
81
83
  - lib/data_verifier/config.rb
82
84
  - lib/data_verifier/validator.rb
83
85
  - lib/data_verifier/version.rb
86
+ - spec/lib/data_verifier/baseline_builder_spec.rb
87
+ - spec/lib/data_verifier/validator_spec.rb
84
88
  homepage: https://github.com/ajitsing/data_verifier
85
89
  licenses:
86
90
  - MIT
@@ -105,4 +109,6 @@ rubygems_version: 2.7.6
105
109
  signing_key:
106
110
  specification_version: 4
107
111
  summary: Verify data after performing series of operations
108
- test_files: []
112
+ test_files:
113
+ - spec/lib/data_verifier/baseline_builder_spec.rb
114
+ - spec/lib/data_verifier/validator_spec.rb