txdb 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/txdb.rb +1 -0
- data/lib/txdb/backends/globalize/reader.rb +4 -24
- data/lib/txdb/backends/globalize/writer.rb +6 -4
- data/lib/txdb/database.rb +8 -3
- data/lib/txdb/downloader.rb +2 -2
- data/lib/txdb/iterators.rb +6 -0
- data/lib/txdb/iterators/auto_increment_iterator.rb +61 -0
- data/lib/txdb/iterators/globalize_iterator.rb +13 -0
- data/lib/txdb/table.rb +2 -2
- data/lib/txdb/version.rb +1 -1
- data/spec/backends/globalize/helpers_spec.rb +11 -4
- data/spec/backends/globalize/reader_spec.rb +9 -9
- data/spec/backends/globalize/writer_spec.rb +15 -15
- data/spec/config_spec.rb +20 -6
- data/spec/database_spec.rb +7 -5
- data/spec/downloader_spec.rb +10 -3
- data/spec/handlers/hook_handler_spec.rb +11 -4
- data/spec/handlers/triggers/pull_handler_spec.rb +11 -4
- data/spec/handlers/triggers/push_handler_spec.rb +11 -4
- data/spec/iterators/auto_increment_iterator_spec.rb +34 -0
- data/spec/iterators/globalize_iterator_spec.rb +43 -0
- data/spec/spec_helpers/globalize_configurator.rb +41 -0
- data/spec/spec_helpers/test_configurator.rb +156 -0
- data/spec/table_spec.rb +14 -7
- data/spec/test.sqlite3 +0 -0
- data/spec/transifex_project_spec.rb +6 -3
- data/spec/uploader_spec.rb +10 -3
- metadata +9 -4
- data/spec/spec_helpers/globalize_db.rb +0 -60
- data/spec/spec_helpers/test_db.rb +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c2c319827b4fdab7a23880e83db01a22cbff37f
|
4
|
+
data.tar.gz: e4daed35214662b575b686607b825b29fed8aed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0e524ba754bed238ccf5647f1711c357cf87a59fd558fb6fa69e06732c6570eb4486f87de36634f9488d79499db1b1e36acd86ebb3836e791684e35aa472f94
|
7
|
+
data.tar.gz: 78b1aa0ada81ef0c9369b46177a4dedf6db6a5fcd07c31151167544dac9bfe69bc0178eeb5b8ce35b525d90210f0b40d9569cba5acc6b36de235d794f984a004
|
data/lib/txdb.rb
CHANGED
@@ -9,6 +9,7 @@ module Txdb
|
|
9
9
|
autoload :Downloader, 'txdb/downloader'
|
10
10
|
autoload :Handlers, 'txdb/handlers'
|
11
11
|
autoload :Hooks, 'txdb/app'
|
12
|
+
autoload :Iterators, 'txdb/iterators'
|
12
13
|
autoload :Response, 'txdb/response'
|
13
14
|
autoload :ResponseHelpers, 'txdb/response_helpers'
|
14
15
|
autoload :Table, 'txdb/table'
|
@@ -51,7 +51,7 @@ module Txdb
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def content_for_records
|
54
|
-
|
54
|
+
iterator.each_with_object({}) do |record, ret|
|
55
55
|
ret[record[:id]] = content_for_record(record)
|
56
56
|
end
|
57
57
|
end
|
@@ -61,33 +61,13 @@ module Txdb
|
|
61
61
|
value = record[col.to_sym]
|
62
62
|
|
63
63
|
unless value.to_s.strip.empty?
|
64
|
-
ret[col] = value
|
64
|
+
ret[col.to_s] = value
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
counter = 0
|
73
|
-
last_id = nil
|
74
|
-
|
75
|
-
loop do
|
76
|
-
records = table.db
|
77
|
-
.from(origin_table_name(table.name))
|
78
|
-
.where { id >= counter }
|
79
|
-
.order(:id)
|
80
|
-
.limit(50)
|
81
|
-
|
82
|
-
break if records.count == 0
|
83
|
-
|
84
|
-
records.each do |record|
|
85
|
-
yield record
|
86
|
-
last_id = record[:id]
|
87
|
-
end
|
88
|
-
|
89
|
-
counter = last_id + 1
|
90
|
-
end
|
69
|
+
def iterator
|
70
|
+
@iterator ||= Iterators::GlobalizeIterator.new(table)
|
91
71
|
end
|
92
72
|
end
|
93
73
|
|
@@ -25,10 +25,12 @@ module Txdb
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def update_row(id, fields, locale)
|
28
|
-
row = table.
|
28
|
+
row = table.connection.where(
|
29
|
+
foreign_key.to_sym => id, locale: locale
|
30
|
+
)
|
29
31
|
|
30
32
|
if row.empty?
|
31
|
-
table.
|
33
|
+
table.connection << fields
|
32
34
|
.merge(foreign_key.to_sym => id, locale: locale)
|
33
35
|
.merge(created_at)
|
34
36
|
.merge(updated_at)
|
@@ -38,12 +40,12 @@ module Txdb
|
|
38
40
|
end
|
39
41
|
|
40
42
|
def created_at
|
41
|
-
return {} unless table.
|
43
|
+
return {} unless table.connection.columns.include?(:created_at)
|
42
44
|
{ created_at: get_utc_time }
|
43
45
|
end
|
44
46
|
|
45
47
|
def updated_at
|
46
|
-
return {} unless table.
|
48
|
+
return {} unless table.connection.columns.include?(:updated_at)
|
47
49
|
{ updated_at: get_utc_time }
|
48
50
|
end
|
49
51
|
|
data/lib/txdb/database.rb
CHANGED
@@ -25,16 +25,21 @@ module Txdb
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
@
|
28
|
+
def connection
|
29
|
+
@connection ||= Sequel.connect(connection_string, max_connections: pool)
|
30
30
|
end
|
31
31
|
|
32
32
|
def from(*args, &block)
|
33
|
-
|
33
|
+
connection.from(*args, &block)
|
34
34
|
end
|
35
35
|
|
36
36
|
def transifex_api
|
37
37
|
transifex_project.api
|
38
38
|
end
|
39
|
+
|
40
|
+
def find_table(name)
|
41
|
+
name = name.to_s
|
42
|
+
tables.find { |table| table.name == name }
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
data/lib/txdb/downloader.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
module Txdb
|
2
|
+
module Iterators
|
3
|
+
class AutoIncrementIterator
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
DEFAULT_BATCH_SIZE = 50
|
7
|
+
DEFAULT_COLUMN = :id
|
8
|
+
|
9
|
+
attr_reader :table, :batch_size, :column
|
10
|
+
|
11
|
+
def initialize(table, options = {})
|
12
|
+
@table = table
|
13
|
+
@batch_size = options.fetch(:batch_size, DEFAULT_BATCH_SIZE)
|
14
|
+
@column = options.fetch(:column, DEFAULT_COLUMN)
|
15
|
+
end
|
16
|
+
|
17
|
+
def each
|
18
|
+
return to_enum(__method__) unless block_given?
|
19
|
+
|
20
|
+
counter = 0
|
21
|
+
last_value = nil
|
22
|
+
sql_column = Sequel.expr(column)
|
23
|
+
|
24
|
+
loop do
|
25
|
+
records = table.connection
|
26
|
+
.from(table_name)
|
27
|
+
.where { sql_column >= counter }
|
28
|
+
.order(column)
|
29
|
+
.limit(batch_size)
|
30
|
+
|
31
|
+
break if records.count == 0
|
32
|
+
|
33
|
+
records.each do |record|
|
34
|
+
yield record
|
35
|
+
last_value = record[column]
|
36
|
+
end
|
37
|
+
|
38
|
+
counter = last_value + 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :each_record, :each
|
43
|
+
|
44
|
+
def compact_map
|
45
|
+
return to_enum(__method__) unless block_given?
|
46
|
+
|
47
|
+
each_with_object([]) do |elem, ret|
|
48
|
+
if val = yield(elem)
|
49
|
+
ret << val
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def table_name
|
57
|
+
table.name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/txdb/table.rb
CHANGED
data/lib/txdb/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
|
4
4
|
include Txdb::Backends
|
5
5
|
|
6
|
-
describe Globalize::Helpers,
|
6
|
+
describe Globalize::Helpers, test_config: true do
|
7
7
|
describe '.origin_table_name' do
|
8
8
|
it 'pluralizes and removes the translations suffix' do
|
9
9
|
origin = Globalize::Helpers.origin_table_name('widget_translations')
|
@@ -17,8 +17,15 @@ describe Globalize::Helpers, test_db: true do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
describe '#resource_slug_for' do
|
20
|
-
let(:database)
|
21
|
-
|
20
|
+
let(:database) do
|
21
|
+
Txdb::TestConfigurator.setup do
|
22
|
+
create_table(:my_table) do
|
23
|
+
primary_key :id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:table) { database.find_table(:my_table) }
|
22
29
|
|
23
30
|
it 'constructs a slug from the database and table names' do
|
24
31
|
expect(Globalize::Helpers.resource_slug_for(table)).to eq(
|
@@ -1,28 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/globalize_configurator'
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
include Txdb::Backends
|
6
6
|
|
7
|
-
describe Globalize::Reader,
|
7
|
+
describe Globalize::Reader, globalize_config: true do
|
8
8
|
include_context :globalize
|
9
9
|
|
10
10
|
describe '#read_content' do
|
11
11
|
it 'reads data from the given table and returns an array of resources' do
|
12
|
-
sprocket_id = widgets.insert(name: 'sprocket')
|
13
|
-
flange_id = widgets.insert(name: 'flange')
|
14
|
-
widget_translations.insert(widget_id: sprocket_id, locale: 'es', name: 'sproqueta')
|
15
|
-
widget_translations.insert(widget_id: flange_id, locale: 'es', name: 'flango')
|
12
|
+
sprocket_id = widgets.connection.insert(name: 'sprocket')
|
13
|
+
flange_id = widgets.connection.insert(name: 'flange')
|
14
|
+
widget_translations.connection.insert(widget_id: sprocket_id, locale: 'es', name: 'sproqueta')
|
15
|
+
widget_translations.connection.insert(widget_id: flange_id, locale: 'es', name: 'flango')
|
16
16
|
|
17
|
-
reader = Globalize::Reader.new(
|
17
|
+
reader = Globalize::Reader.new(widget_translations)
|
18
18
|
resources = reader.read_content
|
19
19
|
expect(resources.size).to eq(1)
|
20
20
|
resource = resources.first
|
21
21
|
|
22
|
-
expect(resource.source_file).to eq(
|
22
|
+
expect(resource.source_file).to eq(widget_translations.name)
|
23
23
|
expect(resource.project_slug).to eq(database.transifex_project.project_slug)
|
24
24
|
expect(resource.resource_slug).to(
|
25
|
-
eq(Globalize::Helpers.resource_slug_for(
|
25
|
+
eq(Globalize::Helpers.resource_slug_for(widget_translations))
|
26
26
|
)
|
27
27
|
|
28
28
|
expect(resource.content).to eq(
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'active_support/core_ext/numeric/time'
|
2
2
|
require 'spec_helper'
|
3
|
-
require 'spec_helpers/
|
3
|
+
require 'spec_helpers/globalize_configurator'
|
4
4
|
require 'timecop'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
7
|
include Txdb::Backends
|
8
8
|
|
9
|
-
describe Globalize::Writer,
|
9
|
+
describe Globalize::Writer, globalize_config: true do
|
10
10
|
include_context :globalize
|
11
11
|
|
12
12
|
describe '#write_content' do
|
@@ -21,8 +21,8 @@ describe Globalize::Writer, globalize_db: true do
|
|
21
21
|
|
22
22
|
context 'with some content' do
|
23
23
|
before(:each) do
|
24
|
-
@sprocket_id = widgets.insert(name: 'sprocket')
|
25
|
-
@writer = Globalize::Writer.new(
|
24
|
+
@sprocket_id = widgets.connection.insert(name: 'sprocket')
|
25
|
+
@writer = Globalize::Writer.new(widget_translations)
|
26
26
|
|
27
27
|
@content = YAML.dump(
|
28
28
|
'widgets' => {
|
@@ -35,10 +35,10 @@ describe Globalize::Writer, globalize_db: true do
|
|
35
35
|
|
36
36
|
it 'inserts the translations into the database' do
|
37
37
|
expect { @writer.write_content(@resource, 'es') }.to(
|
38
|
-
change { widget_translations.count }.from(0).to(1)
|
38
|
+
change { widget_translations.connection.count }.from(0).to(1)
|
39
39
|
)
|
40
40
|
|
41
|
-
translation = widget_translations.first
|
41
|
+
translation = widget_translations.connection.first
|
42
42
|
|
43
43
|
expect(translation).to include(
|
44
44
|
widget_id: @sprocket_id, name: 'sproqueta', locale: 'es'
|
@@ -47,7 +47,7 @@ describe Globalize::Writer, globalize_db: true do
|
|
47
47
|
|
48
48
|
context 'with created_at and updated_at columns' do
|
49
49
|
before(:each) do
|
50
|
-
|
50
|
+
database.connection.alter_table(:widget_translations) do
|
51
51
|
add_column :created_at, Time
|
52
52
|
add_column :updated_at, Time
|
53
53
|
end
|
@@ -56,7 +56,7 @@ describe Globalize::Writer, globalize_db: true do
|
|
56
56
|
it 'fills in the created_at and updated_at columns' do
|
57
57
|
Timecop.freeze(Time.now) do
|
58
58
|
@writer.write_content(@resource, 'es')
|
59
|
-
translation = widget_translations.first
|
59
|
+
translation = widget_translations.connection.first
|
60
60
|
expect(translation[:created_at].to_i).to eq(Time.now.utc.to_i)
|
61
61
|
expect(translation[:updated_at].to_i).to eq(Time.now.utc.to_i)
|
62
62
|
end
|
@@ -68,12 +68,12 @@ describe Globalize::Writer, globalize_db: true do
|
|
68
68
|
today = Time.now + 1.day # groundhog day
|
69
69
|
|
70
70
|
Timecop.freeze(today) do
|
71
|
-
translation = widget_translations.first
|
71
|
+
translation = widget_translations.connection.first
|
72
72
|
expect(translation[:updated_at].to_i).to_not eq(today.utc.to_i)
|
73
73
|
|
74
74
|
# record already exists, so should get updated with new timestamp
|
75
75
|
@writer.write_content(@resource, 'es')
|
76
|
-
translation = widget_translations.first
|
76
|
+
translation = widget_translations.connection.first
|
77
77
|
expect(translation[:updated_at].to_i).to eq(today.utc.to_i)
|
78
78
|
end
|
79
79
|
end
|
@@ -81,12 +81,12 @@ describe Globalize::Writer, globalize_db: true do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'updates the record if it already exists' do
|
84
|
-
sprocket_id = widgets.insert(name: 'sprocket')
|
85
|
-
sprocket_trans_id = widget_translations.insert(
|
84
|
+
sprocket_id = widgets.connection.insert(name: 'sprocket')
|
85
|
+
sprocket_trans_id = widget_translations.connection.insert(
|
86
86
|
widget_id: sprocket_id, locale: 'es', name: 'sproqueta'
|
87
87
|
)
|
88
88
|
|
89
|
-
writer = Globalize::Writer.new(
|
89
|
+
writer = Globalize::Writer.new(widget_translations)
|
90
90
|
|
91
91
|
content = YAML.dump(
|
92
92
|
'widgets' => {
|
@@ -97,10 +97,10 @@ describe Globalize::Writer, globalize_db: true do
|
|
97
97
|
resource = Txdb::TxResource.new(base_resource, content)
|
98
98
|
|
99
99
|
expect { writer.write_content(resource, 'es') }.to_not(
|
100
|
-
change { widget_translations.count }
|
100
|
+
change { widget_translations.connection.count }
|
101
101
|
)
|
102
102
|
|
103
|
-
translation = widget_translations.where(id: sprocket_trans_id).first
|
103
|
+
translation = widget_translations.connection.where(id: sprocket_trans_id).first
|
104
104
|
expect(translation).to include(name: 'sproqueta2')
|
105
105
|
end
|
106
106
|
end
|
data/spec/config_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
require 'tempfile'
|
4
4
|
require 'yaml'
|
5
5
|
|
@@ -10,9 +10,23 @@ describe Txdb::Config do
|
|
10
10
|
Txdb::Config.instance_variable_set(:@raw_config, nil)
|
11
11
|
end
|
12
12
|
|
13
|
+
let(:config) do
|
14
|
+
{
|
15
|
+
databases: [
|
16
|
+
Txdb::TestConfigurator.base_config.tap do |base_config|
|
17
|
+
base_config[:tables] << {
|
18
|
+
name: 'my_table',
|
19
|
+
source_lang: 'en',
|
20
|
+
columns: []
|
21
|
+
}
|
22
|
+
end
|
23
|
+
]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
13
27
|
describe '.databases' do
|
14
28
|
it 'loads config from a string' do
|
15
|
-
with_env('TXDB_CONFIG' => "raw://#{YAML.dump(
|
29
|
+
with_env('TXDB_CONFIG' => "raw://#{YAML.dump(config)}") do
|
16
30
|
expect(Txdb::Config.databases.size).to eq(1)
|
17
31
|
database = Txdb::Config.databases.first
|
18
32
|
|
@@ -25,7 +39,7 @@ describe Txdb::Config do
|
|
25
39
|
|
26
40
|
it 'loads config from a file' do
|
27
41
|
file = Tempfile.new('translations')
|
28
|
-
file.write(YAML.dump(
|
42
|
+
file.write(YAML.dump(config))
|
29
43
|
file.flush
|
30
44
|
|
31
45
|
with_env('TXDB_CONFIG' => "file://#{file.path}") do
|
@@ -45,14 +59,14 @@ describe Txdb::Config do
|
|
45
59
|
|
46
60
|
describe '.each_table' do
|
47
61
|
it 'returns an enumerator' do
|
48
|
-
|
62
|
+
with_env('TXDB_CONFIG' => "raw://#{YAML.dump(config)}") do
|
63
|
+
expect(Txdb::Config.each_table).to be_a(Enumerator)
|
64
|
+
end
|
49
65
|
end
|
50
66
|
|
51
67
|
it 'yields each table in each database' do
|
52
68
|
# set up another database with another table so we can make sure the
|
53
69
|
# method loops over more than one db, yielding tables from each
|
54
|
-
config = TestDb.raw_config.dup
|
55
|
-
config[:databases] = config[:databases].dup
|
56
70
|
config[:databases] << config[:databases].first.merge(
|
57
71
|
database: 'spec/test2.sqlite3',
|
58
72
|
tables: [
|
data/spec/database_spec.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
|
4
4
|
include Txdb
|
5
5
|
|
6
|
-
describe Database,
|
7
|
-
let(:database)
|
6
|
+
describe Database, test_config: true do
|
7
|
+
let(:database) do
|
8
|
+
TestConfigurator.setup
|
9
|
+
end
|
8
10
|
|
9
11
|
describe '#db' do
|
10
12
|
it 'provides access to the database connection' do
|
11
|
-
expect(database.
|
13
|
+
expect(database.connection).to be_a(Sequel::SQLite::Database)
|
12
14
|
end
|
13
15
|
|
14
16
|
it 'sets the max number of connections as specified in the config' do
|
15
|
-
expect(database.
|
17
|
+
expect(database.connection.pool.max_size).to eq(database.pool)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
data/spec/downloader_spec.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
require 'spec_helpers/test_backend'
|
4
4
|
|
5
5
|
include Txdb
|
6
6
|
|
7
|
-
describe Downloader,
|
8
|
-
let(:database)
|
7
|
+
describe Downloader, test_config: true do
|
8
|
+
let(:database) do
|
9
|
+
TestConfigurator.setup do
|
10
|
+
create_table(:foo) do
|
11
|
+
primary_key :id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
9
16
|
let(:downloader) { Downloader.new(database) }
|
10
17
|
let(:transifex_api) { double(:transifex_api) }
|
11
18
|
|
@@ -1,17 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'spec_helpers/test_backend'
|
3
|
-
require 'spec_helpers/
|
3
|
+
require 'spec_helpers/test_configurator'
|
4
4
|
require 'uri'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
7
|
include Txdb
|
8
8
|
include Txdb::Handlers
|
9
9
|
|
10
|
-
describe HookHandler do
|
10
|
+
describe HookHandler, test_config: true do
|
11
11
|
include Rack::Test::Methods
|
12
12
|
|
13
|
-
let(:database)
|
14
|
-
|
13
|
+
let(:database) do
|
14
|
+
TestConfigurator.setup do
|
15
|
+
create_table(:foo) do
|
16
|
+
primary_key :id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:table) { database.find_table(:foo) }
|
15
22
|
let(:project) { database.transifex_project }
|
16
23
|
let(:resource) { TestBackend.resource }
|
17
24
|
|
@@ -1,16 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'spec_helpers/test_backend'
|
3
|
-
require 'spec_helpers/
|
3
|
+
require 'spec_helpers/test_configurator'
|
4
4
|
require 'uri'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
7
|
include Txdb::Handlers::Triggers
|
8
8
|
|
9
|
-
describe PullHandler do
|
9
|
+
describe PullHandler, test_config: true do
|
10
10
|
include Rack::Test::Methods
|
11
11
|
|
12
|
-
let(:database)
|
13
|
-
|
12
|
+
let(:database) do
|
13
|
+
Txdb::TestConfigurator.setup do
|
14
|
+
create_table(:foo) do
|
15
|
+
primary_key :id
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:table) { database.find_table(:foo) }
|
14
21
|
let(:project) { database.transifex_project }
|
15
22
|
|
16
23
|
def app
|
@@ -1,16 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'spec_helpers/test_backend'
|
3
|
-
require 'spec_helpers/
|
3
|
+
require 'spec_helpers/test_configurator'
|
4
4
|
require 'uri'
|
5
5
|
require 'yaml'
|
6
6
|
|
7
7
|
include Txdb::Handlers::Triggers
|
8
8
|
|
9
|
-
describe PushHandler do
|
9
|
+
describe PushHandler, test_config: true do
|
10
10
|
include Rack::Test::Methods
|
11
11
|
|
12
|
-
let(:database)
|
13
|
-
|
12
|
+
let(:database) do
|
13
|
+
Txdb::TestConfigurator.setup do
|
14
|
+
create_table(:foo) do
|
15
|
+
primary_key :id
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:table) { database.find_table(:foo) }
|
14
21
|
let(:project) { database.transifex_project }
|
15
22
|
|
16
23
|
def app
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
|
+
|
4
|
+
include Txdb::Iterators
|
5
|
+
|
6
|
+
describe AutoIncrementIterator, test_config: true do
|
7
|
+
let(:database) do
|
8
|
+
Txdb::TestConfigurator.setup do
|
9
|
+
create_table(:teams) do
|
10
|
+
primary_key :id
|
11
|
+
string :name, translate: true
|
12
|
+
source_lang 'en'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:table) { database.tables.first }
|
18
|
+
let(:teams) { %w(seahawks warriors giants mariners sounders) }
|
19
|
+
|
20
|
+
let(:iterator) do
|
21
|
+
AutoIncrementIterator.new(table)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'iterates sequentially over every database entry' do
|
25
|
+
entries = teams.map { |team| { name: team } }
|
26
|
+
entries.each { |entry| table.connection << entry }
|
27
|
+
|
28
|
+
iterator.each do |db_entry|
|
29
|
+
entries.delete_if { |entry| db_entry[:name] == entry[:name] }
|
30
|
+
end
|
31
|
+
|
32
|
+
expect(entries).to be_empty
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
|
+
|
4
|
+
include Txdb::Iterators
|
5
|
+
|
6
|
+
describe GlobalizeIterator, test_config: true do
|
7
|
+
let(:database) do
|
8
|
+
Txdb::TestConfigurator.setup do
|
9
|
+
create_table(:teams) do
|
10
|
+
primary_key :id
|
11
|
+
string :name
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table(:team_translations) do
|
15
|
+
primary_key :id
|
16
|
+
string :name, translate: true
|
17
|
+
string :locale
|
18
|
+
source_lang 'en'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:teams_table) { database.find_table(:teams) }
|
24
|
+
let(:team_translations_table) { database.find_table(:team_translations) }
|
25
|
+
let(:teams) { %w(seahawks warriors giants mariners sounders) }
|
26
|
+
|
27
|
+
let(:iterator) do
|
28
|
+
GlobalizeIterator.new(team_translations_table)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'iterates over the items in the parent table' do
|
32
|
+
teams.each do |team|
|
33
|
+
teams_table.connection << { name: team }
|
34
|
+
team_translations_table.connection << { name: "#{team}-es", locale: 'es' }
|
35
|
+
end
|
36
|
+
|
37
|
+
entries = iterator.map { |entry| entry[:name] }
|
38
|
+
|
39
|
+
# should be equivalent to the English team names, since it should have
|
40
|
+
# iterated over entries in the parent table, not the translations table
|
41
|
+
expect(entries.sort).to eq(teams.sort)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helpers/test_configurator'
|
2
|
+
|
3
|
+
module Txdb
|
4
|
+
# The globalize configurator uses the functionality in the test configurator
|
5
|
+
# to create a couple of test tables for testing globalize-specific scenarios.
|
6
|
+
class GlobalizeConfigurator < TestConfigurator
|
7
|
+
class << self
|
8
|
+
def setup(&block)
|
9
|
+
super do
|
10
|
+
create_table(:widgets) do
|
11
|
+
primary_key :id
|
12
|
+
string :name
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table(:widget_translations) do
|
16
|
+
primary_key :id
|
17
|
+
integer :widget_id
|
18
|
+
string :locale
|
19
|
+
string :name, translate: true
|
20
|
+
source_lang 'en'
|
21
|
+
end
|
22
|
+
|
23
|
+
block.call if block
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
RSpec.shared_context(:globalize) do
|
31
|
+
let(:database) { Txdb::GlobalizeConfigurator.setup }
|
32
|
+
let(:widgets) { database.find_table(:widgets) }
|
33
|
+
let(:widget_translations) { database.find_table(:widget_translations) }
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec.configure do |config|
|
37
|
+
config.around(:each) do |example|
|
38
|
+
Txdb::GlobalizeConfigurator.reset_db if example.metadata[:globalize_config]
|
39
|
+
example.run
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'spec_helpers/env_helpers'
|
2
|
+
require 'spec_helpers/test_backend'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Txdb
|
6
|
+
# The test configurator is responsible for creating test databases and tables.
|
7
|
+
# It creates actual SQLite tables and the corresponding Table and Database
|
8
|
+
# config objects that are usually constructed from config.yml. The SQLite
|
9
|
+
# database is deleted and old instances of TestConfigurator are released to
|
10
|
+
# the garbage collector before each test run. Set the test_config: true tag on
|
11
|
+
# your top-level RSpec describe blocks to activate this cleanup behavior.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
#
|
15
|
+
# describe MyClass, test_config: true do
|
16
|
+
# let(:database) do
|
17
|
+
# TestConfigurator.setup do
|
18
|
+
# create_table :my_table do
|
19
|
+
# primary_key :id
|
20
|
+
# string :name, translate: true
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Any field marked with translate: true will be added to the list of columns
|
27
|
+
# to translate in the corresponding Table object.
|
28
|
+
#
|
29
|
+
# TestConfigurator.setup returns an instance of Database, which can be used
|
30
|
+
# anywhere a Database instance is required. For example, you can use the
|
31
|
+
# return value to create a downloader:
|
32
|
+
#
|
33
|
+
# it 'downloads some stuff' do
|
34
|
+
# Txdb::Downloader.new(database).download('ko')
|
35
|
+
# end
|
36
|
+
class TestConfigurator
|
37
|
+
class << self
|
38
|
+
def setup(&block)
|
39
|
+
test_config = new.tap do |test_config|
|
40
|
+
test_config.instance_eval(&block) if block
|
41
|
+
end
|
42
|
+
|
43
|
+
databases << test_config.database
|
44
|
+
databases.last
|
45
|
+
end
|
46
|
+
|
47
|
+
def reset_db
|
48
|
+
databases.clear
|
49
|
+
|
50
|
+
if File.exist?('spec/test.sqlite3')
|
51
|
+
File.unlink('spec/test.sqlite3')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def databases
|
56
|
+
@databases ||= []
|
57
|
+
end
|
58
|
+
|
59
|
+
def base_config
|
60
|
+
{
|
61
|
+
adapter: 'sqlite',
|
62
|
+
backend: 'test-backend',
|
63
|
+
username: 'username',
|
64
|
+
password: 'password',
|
65
|
+
database: 'spec/test.sqlite3',
|
66
|
+
transifex: {
|
67
|
+
organization: 'myorg',
|
68
|
+
project_slug: 'myproject',
|
69
|
+
username: 'username',
|
70
|
+
password: 'password',
|
71
|
+
webhook_secret: '123abc'
|
72
|
+
},
|
73
|
+
tables: []
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :database
|
79
|
+
|
80
|
+
def initialize
|
81
|
+
@database = Txdb::Database.new(self.class.base_config)
|
82
|
+
end
|
83
|
+
|
84
|
+
def connection
|
85
|
+
database.connection
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_table(name, &block)
|
89
|
+
# sequel won't create the table unless it has at least one column
|
90
|
+
connection.create_table(name) { integer :remove_me_blarg_blarg }
|
91
|
+
creator = TableCreator.new(name, database, &block)
|
92
|
+
database.tables << creator.table
|
93
|
+
connection.alter_table(name) { drop_column :remove_me_blarg_blarg }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class TableCreator
|
98
|
+
attr_reader :name, :database, :columns, :source_lang
|
99
|
+
|
100
|
+
def initialize(name, database, &block)
|
101
|
+
@name = name
|
102
|
+
@database = database
|
103
|
+
@columns = []
|
104
|
+
@first = true
|
105
|
+
instance_eval(&block)
|
106
|
+
end
|
107
|
+
|
108
|
+
def primary_key(column, *args)
|
109
|
+
connection.alter_table(name) { add_primary_key(column, *args) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def string(column, *args)
|
113
|
+
add_column(column, :string, *args)
|
114
|
+
end
|
115
|
+
|
116
|
+
def integer(column, *args)
|
117
|
+
add_column(column, :integer, *args)
|
118
|
+
end
|
119
|
+
|
120
|
+
def source_lang(lang)
|
121
|
+
@source_lang = lang
|
122
|
+
end
|
123
|
+
|
124
|
+
def table
|
125
|
+
Txdb::Table.new(
|
126
|
+
database, {
|
127
|
+
name: name.to_s, columns: columns, source_lang: @source_lang
|
128
|
+
}
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def add_column(column, type, *args)
|
135
|
+
columns << column if translate?(args)
|
136
|
+
connection.alter_table(name) { add_column(column, type, *args) }
|
137
|
+
end
|
138
|
+
|
139
|
+
def connection
|
140
|
+
database.connection
|
141
|
+
end
|
142
|
+
|
143
|
+
def translate?(args)
|
144
|
+
args.any? do |arg|
|
145
|
+
arg.is_a?(Hash) && arg[:translate]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
RSpec.configure do |config|
|
152
|
+
config.around(:each) do |example|
|
153
|
+
Txdb::TestConfigurator.reset_db if example.metadata[:test_config]
|
154
|
+
example.run
|
155
|
+
end
|
156
|
+
end
|
data/spec/table_spec.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
include Txdb
|
6
6
|
|
7
|
-
describe Table,
|
8
|
-
let(:database)
|
9
|
-
|
7
|
+
describe Table, test_config: true do
|
8
|
+
let(:database) do
|
9
|
+
TestConfigurator.setup do
|
10
|
+
create_table(:my_table) do
|
11
|
+
primary_key :id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:table) { database.find_table(:my_table) }
|
10
17
|
|
11
|
-
describe '#
|
18
|
+
describe '#connection' do
|
12
19
|
it 'returns a dataset primed to select from the table' do
|
13
|
-
expect(table.
|
14
|
-
expect(table.
|
20
|
+
expect(table.connection).to be_a(Sequel::Dataset)
|
21
|
+
expect(table.connection.sql).to eq('SELECT * FROM `my_table`')
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
data/spec/test.sqlite3
CHANGED
Binary file
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
|
4
4
|
include Txdb
|
5
5
|
|
6
|
-
describe TransifexProject,
|
7
|
-
let(:database)
|
6
|
+
describe TransifexProject, test_config: true do
|
7
|
+
let(:database) do
|
8
|
+
TestConfigurator.setup
|
9
|
+
end
|
10
|
+
|
8
11
|
let(:project) { database.transifex_project }
|
9
12
|
|
10
13
|
describe '#api' do
|
data/spec/uploader_spec.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'spec_helpers/
|
2
|
+
require 'spec_helpers/test_configurator'
|
3
3
|
require 'spec_helpers/test_backend'
|
4
4
|
|
5
5
|
include Txdb
|
6
6
|
|
7
|
-
describe Uploader,
|
8
|
-
let(:database)
|
7
|
+
describe Uploader, test_config: true do
|
8
|
+
let(:database) do
|
9
|
+
TestConfigurator.setup do
|
10
|
+
create_table(:foo) do
|
11
|
+
primary_key :id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
9
16
|
let(:uploader) { Uploader.new(database) }
|
10
17
|
let(:transifex_api) { double(:transifex_api) }
|
11
18
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: txdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Dutro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,6 +80,9 @@ files:
|
|
80
80
|
- lib/txdb/handlers/triggers/handler.rb
|
81
81
|
- lib/txdb/handlers/triggers/pull_handler.rb
|
82
82
|
- lib/txdb/handlers/triggers/push_handler.rb
|
83
|
+
- lib/txdb/iterators.rb
|
84
|
+
- lib/txdb/iterators/auto_increment_iterator.rb
|
85
|
+
- lib/txdb/iterators/globalize_iterator.rb
|
83
86
|
- lib/txdb/response.rb
|
84
87
|
- lib/txdb/response_helpers.rb
|
85
88
|
- lib/txdb/table.rb
|
@@ -98,11 +101,13 @@ files:
|
|
98
101
|
- spec/handlers/hook_handler_spec.rb
|
99
102
|
- spec/handlers/triggers/pull_handler_spec.rb
|
100
103
|
- spec/handlers/triggers/push_handler_spec.rb
|
104
|
+
- spec/iterators/auto_increment_iterator_spec.rb
|
105
|
+
- spec/iterators/globalize_iterator_spec.rb
|
101
106
|
- spec/spec_helper.rb
|
102
107
|
- spec/spec_helpers/env_helpers.rb
|
103
|
-
- spec/spec_helpers/
|
108
|
+
- spec/spec_helpers/globalize_configurator.rb
|
104
109
|
- spec/spec_helpers/test_backend.rb
|
105
|
-
- spec/spec_helpers/
|
110
|
+
- spec/spec_helpers/test_configurator.rb
|
106
111
|
- spec/table_spec.rb
|
107
112
|
- spec/test.sqlite3
|
108
113
|
- spec/transifex_project_spec.rb
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'spec_helpers/test_db'
|
2
|
-
|
3
|
-
class GlobalizeDb < TestDb
|
4
|
-
class << self
|
5
|
-
def database
|
6
|
-
@database ||= Txdb::Database.new(
|
7
|
-
raw_config[:databases].first.merge(
|
8
|
-
backend: Txdb::Backends.get('globalize'),
|
9
|
-
tables: [{
|
10
|
-
name: 'widget_translations',
|
11
|
-
source_lang: 'en',
|
12
|
-
columns: %w(name)
|
13
|
-
}]
|
14
|
-
)
|
15
|
-
)
|
16
|
-
end
|
17
|
-
|
18
|
-
def setup_db
|
19
|
-
db.create_table(:widgets) do
|
20
|
-
primary_key :id
|
21
|
-
string :name
|
22
|
-
end
|
23
|
-
|
24
|
-
db.create_table(:widget_translations) do
|
25
|
-
primary_key :id
|
26
|
-
integer :widget_id
|
27
|
-
string :locale
|
28
|
-
string :name
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def widgets
|
33
|
-
db[:widgets]
|
34
|
-
end
|
35
|
-
|
36
|
-
def widget_translations
|
37
|
-
db[:widget_translations]
|
38
|
-
end
|
39
|
-
|
40
|
-
def widget_translations_table
|
41
|
-
database.tables.find do |table|
|
42
|
-
table.name == 'widget_translations'
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
RSpec.shared_context(:globalize) do
|
49
|
-
let(:widgets) { GlobalizeDb.widgets }
|
50
|
-
let(:widget_translations) { GlobalizeDb.widget_translations }
|
51
|
-
let(:widget_translations_table) { GlobalizeDb.widget_translations_table }
|
52
|
-
let(:database) { GlobalizeDb.database }
|
53
|
-
end
|
54
|
-
|
55
|
-
RSpec.configure do |config|
|
56
|
-
config.around(:each) do |example|
|
57
|
-
GlobalizeDb.reset_db if example.metadata[:globalize_db]
|
58
|
-
example.run
|
59
|
-
end
|
60
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'spec_helpers/env_helpers'
|
2
|
-
require 'spec_helpers/test_backend'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
class TestDb
|
6
|
-
class << self
|
7
|
-
def db
|
8
|
-
@db ||= database.db
|
9
|
-
end
|
10
|
-
|
11
|
-
def database
|
12
|
-
@database ||= Txdb::Database.new(raw_config[:databases].first)
|
13
|
-
end
|
14
|
-
|
15
|
-
def db_path
|
16
|
-
File.join(File.dirname(__FILE__), '../test.sqlite3')
|
17
|
-
end
|
18
|
-
|
19
|
-
def raw_config
|
20
|
-
@config ||= deep_freeze({
|
21
|
-
databases: [{
|
22
|
-
adapter: 'sqlite',
|
23
|
-
backend: 'test-backend',
|
24
|
-
username: 'username',
|
25
|
-
password: 'password',
|
26
|
-
database: 'spec/test.sqlite3',
|
27
|
-
transifex: {
|
28
|
-
organization: 'myorg',
|
29
|
-
project_slug: 'myproject',
|
30
|
-
username: 'username',
|
31
|
-
password: 'password',
|
32
|
-
webhook_secret: '123abc'
|
33
|
-
},
|
34
|
-
tables: [{
|
35
|
-
name: 'my_table',
|
36
|
-
source_lang: 'en',
|
37
|
-
columns: %w(my_column)
|
38
|
-
}]
|
39
|
-
}]
|
40
|
-
})
|
41
|
-
end
|
42
|
-
|
43
|
-
def reset_db
|
44
|
-
db.tables.each { |t| db.drop_table(t) }
|
45
|
-
setup_db
|
46
|
-
end
|
47
|
-
|
48
|
-
def setup_db
|
49
|
-
# no-op
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def deep_freeze(obj)
|
55
|
-
case obj
|
56
|
-
when Hash
|
57
|
-
obj.each_with_object({}) do |(k, v), ret|
|
58
|
-
ret[k] = deep_freeze(v)
|
59
|
-
end.freeze
|
60
|
-
|
61
|
-
when Array
|
62
|
-
obj.map { |elem| deep_freeze(elem) }.freeze
|
63
|
-
|
64
|
-
else
|
65
|
-
obj
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
RSpec.configure do |config|
|
72
|
-
config.around(:each) do |example|
|
73
|
-
TestDb.reset_db if example.metadata[:test_db]
|
74
|
-
example.run
|
75
|
-
end
|
76
|
-
end
|