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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e59bfc3e60354b89d0a572dc8639ecc1bec5146
4
- data.tar.gz: 05599e91b876f536edabd4f05163f769fbf2a2c5
3
+ metadata.gz: 0c2c319827b4fdab7a23880e83db01a22cbff37f
4
+ data.tar.gz: e4daed35214662b575b686607b825b29fed8aed7
5
5
  SHA512:
6
- metadata.gz: 7903d1a0966bc7428dce7de537418ba437e06e48ec95032c4fb21bcc513c8703552c28183be6e23b6271b2f5b921d8ebe5eb4e27500c005c3316590daa84f7a2
7
- data.tar.gz: 470a4c9d4d8df0a31f8d8c1275384dab4ba8c487266a6093ad44299ba42e12f61ea0b750e1c814a9b5c2e289204b1b110b83bf8aa5c93c204beb2d74cd3a21e4
6
+ metadata.gz: c0e524ba754bed238ccf5647f1711c357cf87a59fd558fb6fa69e06732c6570eb4486f87de36634f9488d79499db1b1e36acd86ebb3836e791684e35aa472f94
7
+ data.tar.gz: 78b1aa0ada81ef0c9369b46177a4dedf6db6a5fcd07c31151167544dac9bfe69bc0178eeb5b8ce35b525d90210f0b40d9569cba5acc6b36de235d794f984a004
@@ -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
- each_record.each_with_object({}) do |record, ret|
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 each_record
70
- return to_enum(__method__) unless block_given?
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.db.where(foreign_key.to_sym => id, locale: locale)
28
+ row = table.connection.where(
29
+ foreign_key.to_sym => id, locale: locale
30
+ )
29
31
 
30
32
  if row.empty?
31
- table.db << fields
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.db.columns.include?(:created_at)
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.db.columns.include?(:updated_at)
48
+ return {} unless table.connection.columns.include?(:updated_at)
47
49
  { updated_at: get_utc_time }
48
50
  end
49
51
 
@@ -25,16 +25,21 @@ module Txdb
25
25
  end
26
26
  end
27
27
 
28
- def db
29
- @db ||= Sequel.connect(connection_string, max_connections: pool)
28
+ def connection
29
+ @connection ||= Sequel.connect(connection_string, max_connections: pool)
30
30
  end
31
31
 
32
32
  def from(*args, &block)
33
- db.from(*args, &block)
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
@@ -3,8 +3,8 @@ require 'txgh'
3
3
  module Txdb
4
4
  class Downloader
5
5
  class << self
6
- def download(database)
7
- new(database).download
6
+ def download(database, locale)
7
+ new(database).download(locale)
8
8
  end
9
9
  end
10
10
 
@@ -0,0 +1,6 @@
1
+ module Txdb
2
+ module Iterators
3
+ autoload :AutoIncrementIterator, 'txdb/iterators/auto_increment_iterator'
4
+ autoload :GlobalizeIterator, 'txdb/iterators/globalize_iterator'
5
+ end
6
+ end
@@ -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
@@ -0,0 +1,13 @@
1
+ module Txdb
2
+ module Iterators
3
+ class GlobalizeIterator < AutoIncrementIterator
4
+ private
5
+
6
+ include Backends::Globalize::Helpers
7
+
8
+ def table_name
9
+ origin_table_name(table.name)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -12,8 +12,8 @@ module Txdb
12
12
  @source_lang = options.fetch(:source_lang)
13
13
  end
14
14
 
15
- def db
16
- database.db.from(name)
15
+ def connection
16
+ database.connection.from(name)
17
17
  end
18
18
 
19
19
  def read_content
@@ -1,3 +1,3 @@
1
1
  module Txdb
2
- VERSION = '1.1.0'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
2
+ require 'spec_helpers/test_configurator'
3
3
 
4
4
  include Txdb::Backends
5
5
 
6
- describe Globalize::Helpers, test_db: true do
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) { TestDb.database }
21
- let(:table) { database.tables.first }
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/globalize_db'
2
+ require 'spec_helpers/globalize_configurator'
3
3
  require 'yaml'
4
4
 
5
5
  include Txdb::Backends
6
6
 
7
- describe Globalize::Reader, globalize_db: true do
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(widget_translations_table)
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(widget_translations_table.name)
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(widget_translations_table))
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/globalize_db'
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, globalize_db: true do
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(widget_translations_table)
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
- GlobalizeDb.db.alter_table(:widget_translations) do
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(widget_translations_table)
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
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
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(TestDb.raw_config)}") do
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(TestDb.raw_config))
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
- expect(Txdb::Config.each_table).to be_a(Enumerator)
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: [
@@ -1,18 +1,20 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
2
+ require 'spec_helpers/test_configurator'
3
3
 
4
4
  include Txdb
5
5
 
6
- describe Database, test_db: true do
7
- let(:database) { TestDb.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.db).to be_a(Sequel::SQLite::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.db.pool.max_size).to eq(database.pool)
17
+ expect(database.connection.pool.max_size).to eq(database.pool)
16
18
  end
17
19
  end
18
20
 
@@ -1,11 +1,18 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
2
+ require 'spec_helpers/test_configurator'
3
3
  require 'spec_helpers/test_backend'
4
4
 
5
5
  include Txdb
6
6
 
7
- describe Downloader, test_db: true do
8
- let(:database) { TestDb.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/test_db'
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) { TestDb.database }
14
- let(:table) { database.tables.first }
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/test_db'
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) { TestDb.database }
13
- let(:table) { database.tables.first }
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/test_db'
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) { TestDb.database }
13
- let(:table) { database.tables.first }
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
@@ -1,17 +1,24 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
2
+ require 'spec_helpers/test_configurator'
3
3
  require 'yaml'
4
4
 
5
5
  include Txdb
6
6
 
7
- describe Table, test_db: true do
8
- let(:database) { TestDb.database }
9
- let(:table) { database.tables.first }
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 '#db' do
18
+ describe '#connection' do
12
19
  it 'returns a dataset primed to select from the table' do
13
- expect(table.db).to be_a(Sequel::Dataset)
14
- expect(table.db.sql).to eq('SELECT * FROM `my_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
 
Binary file
@@ -1,10 +1,13 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
2
+ require 'spec_helpers/test_configurator'
3
3
 
4
4
  include Txdb
5
5
 
6
- describe TransifexProject, test_db: true do
7
- let(:database) { TestDb.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
@@ -1,11 +1,18 @@
1
1
  require 'spec_helper'
2
- require 'spec_helpers/test_db'
2
+ require 'spec_helpers/test_configurator'
3
3
  require 'spec_helpers/test_backend'
4
4
 
5
5
  include Txdb
6
6
 
7
- describe Uploader, test_db: true do
8
- let(:database) { TestDb.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.1.0
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-05-27 00:00:00.000000000 Z
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/globalize_db.rb
108
+ - spec/spec_helpers/globalize_configurator.rb
104
109
  - spec/spec_helpers/test_backend.rb
105
- - spec/spec_helpers/test_db.rb
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