synchronisable 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46c5332c053921eb44021c59a846a1451eede185
4
- data.tar.gz: d33c7cdb48f1266ebb3737a20c7a6c4b3688b12c
3
+ metadata.gz: 5e53ab569c0106db0a2e1f17b9446111c8dde193
4
+ data.tar.gz: caebb67d58390fddd864b91a8e8901904f5094bf
5
5
  SHA512:
6
- metadata.gz: a42307f344f720d63a7519969481e94fffcc9a9010510cf39791ea43b93ad5e64304c80074aa1b5f5133d720fc16cbaf829650dfeb3da50d814efe3608eb72a4
7
- data.tar.gz: 7b35e861d0ea8c002d4215b2965713c2c2ebb30f509f24e652f687f95e0237bb69be0dee671aa66fc944f4a714e417a9a4c85f59c1862f6d8f727879b0cff6f9
6
+ metadata.gz: 209cee6e20cf9f5edd9b52e105e1c6a9db92beb0fd66a91e1a5841c10594ac41195b2708c6ab8f04776a431b03253c606f6a2185503c8e43b8ff9dd1db74525b
7
+ data.tar.gz: bd26bb9a7a7377ff5c3778b9ae3cce6525b99fccee41c4a113680dce94dcadd2bbeb5822141478ee33ca85250a4c2e570c3e26caa59dc9f6b6d5a02111565a6d
data/Guardfile CHANGED
@@ -6,9 +6,3 @@ guard :rspec, :all_on_start => false, :all_after_pass => false do
6
6
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
7
  watch('spec/spec_helper.rb') { "spec" }
8
8
  end
9
-
10
-
11
- guard 'spork' do
12
- watch('Gemfile.lock')
13
- watch('spec/spec_helper.rb') { :rspec }
14
- end
data/TODO.md CHANGED
@@ -17,6 +17,7 @@ Primary objectives
17
17
  - [x] sync with ids array
18
18
  - [ ] handle case when association type is a :hash
19
19
  - [ ] sync method for collection proxy (Model.where(condition).sync)
20
+ - [ ] better specs for cases when we should fetch/find using complex params
20
21
 
21
22
  Think about
22
23
  ======================================
@@ -27,7 +28,7 @@ Secondary objectives
27
28
  ======================================
28
29
  - [x] option for verbose logging
29
30
  - [x] colorized STDOUT
30
- - [ ] actualize docs
31
+ - [x] actualize docs
31
32
 
32
33
 
33
34
  The desired interface:
@@ -38,7 +39,7 @@ The desired interface:
38
39
  ```
39
40
 
40
41
  ```
41
- Match.sync(:include => {
42
+ + Match.sync(:include => {
42
43
  :match_players => :player
43
44
  })
44
45
  + Model.sync([id1, ..., idn])
@@ -0,0 +1,11 @@
1
+ require 'i18n'
2
+
3
+ locale_paths = File.join(File.dirname(__FILE__),
4
+ '..', 'locale', '*.yml')
5
+
6
+ Dir[locale_paths].each { |path| I18n.load_path << path }
7
+ I18n.backend.load_translations unless defined?(Rails)
8
+
9
+ I18n.config.enforce_available_locales = true
10
+ I18n.default_locale = :en
11
+ I18n.available_locales = [:en, :ru]
File without changes
@@ -2,7 +2,7 @@ require 'colorize'
2
2
 
3
3
  require 'synchronisable/error_handler'
4
4
  require 'synchronisable/context'
5
- require 'synchronisable/input_parser'
5
+ require 'synchronisable/input/parser'
6
6
  require 'synchronisable/source'
7
7
  require 'synchronisable/models/import'
8
8
  require 'synchronisable/helper/logging'
@@ -77,7 +77,7 @@ module Synchronisable
77
77
  #
78
78
  # @return [Synchronisable::Context] synchronization context
79
79
  #
80
- # @see Synchronisable::InputParser
80
+ # @see Synchronisable::Input::Parser
81
81
  def call(data)
82
82
  sync do |context|
83
83
  error_handler = ErrorHandler.new(logger, context)
@@ -116,7 +116,7 @@ module Synchronisable
116
116
  @includes = options[:includes]
117
117
  @parent = options[:parent]
118
118
 
119
- @input = InputParser.new(@model, @synchronizer)
119
+ @input = Input::Parser.new(@model, @synchronizer)
120
120
  end
121
121
 
122
122
  def sync
@@ -1,7 +1,5 @@
1
1
  module Synchronisable
2
2
  class Gateway
3
- attr_reader :synchronizer
4
-
5
3
  def fetch(params = {})
6
4
  not_implemented :fetch
7
5
  end
@@ -0,0 +1,54 @@
1
+ module Synchronisable
2
+ module Input
3
+ # Provides a set of helper methods
4
+ # to describe user input.
5
+ #
6
+ # @api private
7
+ #
8
+ # @see Synchronisable::Input::Descriptor
9
+ class Descriptor
10
+ attr_reader :data
11
+
12
+ def initialize(data)
13
+ @data = data
14
+ end
15
+
16
+ def empty?
17
+ @data.blank?
18
+ end
19
+
20
+ def params?
21
+ @data.is_a?(Hash)
22
+ end
23
+
24
+ def remote_id?
25
+ @data.is_a?(String)
26
+ end
27
+
28
+ def local_id?
29
+ @data.is_a?(Integer)
30
+ end
31
+
32
+ def array_of_ids?
33
+ enumerable? && (
34
+ first_element.is_a?(String) ||
35
+ first_element.is_a?(Integer)
36
+ )
37
+ end
38
+
39
+ def element_class
40
+ first_element.try(:class)
41
+ end
42
+
43
+ private
44
+
45
+ def first_element
46
+ @data.try(:first)
47
+ end
48
+
49
+ def enumerable?
50
+ @data.is_a?(Enumerable)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,70 @@
1
+ require 'synchronisable/input/descriptor'
2
+
3
+ module Synchronisable
4
+ module Input
5
+ # Responsible for guessing the user input format.
6
+ #
7
+ # @api private
8
+ #
9
+ # @see Synchronisable::Input::Parser
10
+ class Parser
11
+ def initialize(model, synchronizer)
12
+ @model = model
13
+ @synchronizer = synchronizer
14
+ end
15
+
16
+ # Parses the user input.
17
+ #
18
+ # @param data [Array<Hash>, Array<String>, Array<Integer>, String, Integer]
19
+ # synchronization data to handle.
20
+ #
21
+ # @return [Array<Hash>] array of hashes with remote attributes
22
+ def parse(data)
23
+ input = Descriptor.new(data)
24
+
25
+ result = case
26
+ when input.empty?
27
+ @synchronizer.fetch
28
+ when input.params?
29
+ find_or_fetch_by_params(input.data)
30
+ when input.remote_id?
31
+ @synchronizer.find(data)
32
+ when input.local_id?
33
+ find_by_local_id(data)
34
+ when input.array_of_ids?
35
+ find_by_array_of_ids(input)
36
+ else
37
+ result = data.dup
38
+ end
39
+
40
+ [result].flatten.compact
41
+ end
42
+
43
+ private
44
+
45
+ def find_or_fetch_by_params(params)
46
+ sync_method = params.key?(:id) ? :find : :fetch
47
+ @synchronizer.send(sync_method, params)
48
+ end
49
+
50
+ def find_by_array_of_ids(input)
51
+ records = find_imports(input.element_class.name, input.data)
52
+ records.map { |r| @synchronizer.find(r.remote_id) }
53
+ end
54
+
55
+ def find_by_local_id(id)
56
+ import = @model.find_by(id: id).try(:import)
57
+ import ? @synchronizer.find(import.remote_id) : nil
58
+ end
59
+
60
+ def find_imports(class_name, ids)
61
+ case class_name
62
+ when 'Fixnum'
63
+ ids.map { |id| @model.find_by(id: id).try(&:import) }
64
+ when 'String'
65
+ ids.map { |id| Import.find_by(id: id) }
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -2,7 +2,7 @@ module Synchronisable
2
2
  module VERSION
3
3
  MAJOR = 1
4
4
  MINOR = 1
5
- PATCH = 3
5
+ PATCH = 4
6
6
  SUFFIX = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, SUFFIX].compact.join('.')
@@ -8,7 +8,7 @@ require 'active_support/core_ext/string/inflections'
8
8
  require 'active_support/configurable'
9
9
  require 'active_support/concern'
10
10
 
11
- require 'i18n'
11
+ require 'synchronisable/bootstrap/i18n'
12
12
 
13
13
  require 'synchronisable/version'
14
14
  require 'synchronisable/models/import'
@@ -16,15 +16,6 @@ require 'synchronisable/synchronizer'
16
16
  require 'synchronisable/model'
17
17
  require 'synchronisable/gateway'
18
18
 
19
- locale_paths = File.join(File.dirname(__FILE__),
20
- 'synchronisable', 'locale', '*.yml')
21
-
22
- Dir[locale_paths].each { |path| I18n.load_path << path }
23
- I18n.backend.load_translations unless defined?(Rails)
24
-
25
- I18n.config.enforce_available_locales = true
26
- I18n.default_locale = :en
27
- I18n.available_locales = [:en, :ru]
28
19
 
29
20
  module Synchronisable
30
21
  include ActiveSupport::Configurable
@@ -1,8 +1,4 @@
1
1
  class StageGateway < GatewayBase
2
- def id_key
3
- :stage_id
4
- end
5
-
6
2
  def source
7
3
  @source ||= [
8
4
  FactoryGirl.build(:remote_stage,
@@ -15,4 +11,26 @@ class StageGateway < GatewayBase
15
11
  )
16
12
  ]
17
13
  end
14
+
15
+ def fetch(params)
16
+ tournament_id = params[:tournament_id]
17
+
18
+ raise "missed parameter 'tournament_id'" unless tournament_id
19
+
20
+ source.select do |attrs|
21
+ attrs[:tour_id] = tournament_id
22
+ end
23
+ end
24
+
25
+ def find(params)
26
+ tournament_id, id = params[:tournament_id], params[:id]
27
+
28
+ raise "missed parameter 'tournament_id'" unless tournament_id
29
+ raise "missed parameter 'id'" unless id
30
+
31
+ source.find do |attrs|
32
+ attrs[:tour_id] = tournament_id &&
33
+ attrs[:stage_id] = id
34
+ end
35
+ end
18
36
  end
@@ -8,7 +8,16 @@ class TournamentGateway < GatewayBase
8
8
  FactoryGirl.build(:remote_tournament,
9
9
  :tour_id => 'tournament_0',
10
10
  :is_current => true,
11
- :stages_ids => %w(stage_0 stage_1)
11
+ :stages_ids => [
12
+ {
13
+ id: 'stage_0',
14
+ tournament_id: 'tournament_0'
15
+ },
16
+ {
17
+ id: 'stage_1',
18
+ tournament_id: 'tournament_0'
19
+ }
20
+ ]
12
21
  )
13
22
  ]
14
23
  end
@@ -11,10 +11,12 @@ describe Stage do
11
11
  end
12
12
 
13
13
  describe 'skipping with before_sync hook' do
14
- subject { -> { Stage.sync(remote_attrs, :includes => {}) } }
14
+ let!(:context) { Stage.sync(remote_attrs, :includes => {}) }
15
15
 
16
- it { is_expected.to change { Stage.count }.by(2) }
17
- it { is_expected.to change { Synchronisable::Import.count }.by(2) }
16
+ it 'skips hashes where name is "ignored"' do
17
+ expect(Stage.count).to eq(2)
18
+ expect(Synchronisable::Import.count).to eq(2)
19
+ end
18
20
  end
19
21
  end
20
22
  end
@@ -121,7 +121,7 @@ describe Team do
121
121
  end
122
122
 
123
123
  context 'when remote id is not specified in attributes hash' do
124
- it "return synchronization result that contains 1 error" do
124
+ it 'return synchronization result that contains 1 error' do
125
125
  result = Team.sync([remote_attrs.last])
126
126
  expect(result.errors.count).to eq(1)
127
127
  end
data/spec/spec_helper.rb CHANGED
@@ -6,7 +6,6 @@ ENV['RAILS_ENV'] ||= 'test'
6
6
  require 'database_cleaner'
7
7
  require 'factory_girl'
8
8
  require 'factory_girl_sequences'
9
- require 'spork'
10
9
 
11
10
  if ENV['COVERAGE']
12
11
  require 'simplecov'
@@ -34,41 +33,36 @@ Dir[support_pattern].each { |file| require file }
34
33
 
35
34
  ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
36
35
 
37
- Spork.prefork do
38
- RSpec.configure do |config|
39
- config.run_all_when_everything_filtered = true
40
- config.filter_run focus: true
41
- config.order = 'random'
42
- config.include FactoryGirl::Syntax::Methods
43
-
44
- config.before(:suite) do
45
- begin
46
- FactoryGirl.lint
47
- ensure
48
- DatabaseCleaner.clean_with(:truncation)
49
- end
50
- end
51
-
52
- config.before(:each) { DatabaseCleaner.strategy = :transaction }
53
-
54
- config.before(:each, js: true) do
55
- DatabaseCleaner.strategy = :truncation
36
+ RSpec.configure do |config|
37
+ config.run_all_when_everything_filtered = true
38
+ config.filter_run focus: true
39
+ config.order = 'random'
40
+ config.include FactoryGirl::Syntax::Methods
41
+
42
+ config.before(:suite) do
43
+ begin
44
+ FactoryGirl.lint
45
+ ensure
46
+ DatabaseCleaner.clean_with(:truncation)
56
47
  end
48
+ end
57
49
 
58
- config.before(:each) { DatabaseCleaner.start }
59
- config.after(:each) { DatabaseCleaner.clean }
50
+ config.before(:each) { DatabaseCleaner.strategy = :transaction }
60
51
 
61
- if ENV['RUN_SLOW_TESTS'] != 'true'
62
- config.filter_run_excluding slow: true
63
- end
52
+ config.before(:each, js: true) do
53
+ DatabaseCleaner.strategy = :truncation
64
54
  end
65
55
 
66
- FactoryGirl.define do
67
- %w(remote match team player match_player stage tournament).each do |prefix|
68
- sequence(:"#{prefix}_id") { |n| "#{prefix}_#{n}" }
69
- end
56
+ config.before(:each) { DatabaseCleaner.start }
57
+ config.after(:each) { DatabaseCleaner.clean }
58
+
59
+ if ENV['RUN_SLOW_TESTS'] != 'true'
60
+ config.filter_run_excluding slow: true
70
61
  end
71
62
  end
72
63
 
73
- Spork.each_run do
64
+ FactoryGirl.define do
65
+ %w(remote match team player match_player stage tournament).each do |prefix|
66
+ sequence(:"#{prefix}_id") { |n| "#{prefix}_#{n}" }
67
+ end
74
68
  end
@@ -23,7 +23,7 @@ describe Synchronisable do
23
23
  context 'all' do
24
24
  before :all do
25
25
  Synchronisable.models = %w(
26
- Stage Tournament Team
26
+ Tournament Team
27
27
  Match MatchPlayer Player
28
28
  )
29
29
  end
@@ -38,21 +38,25 @@ describe Synchronisable do
38
38
  it { is_expected.to change { Synchronisable::Import.count }.by(14) }
39
39
  end
40
40
 
41
- # context 'when models setting is overriden in method call' do
42
- # before :all do
43
- # Synchronisable.models = %w(Team Match)
44
- # end
41
+ context 'when models setting is overriden in method call' do
42
+ before :all do
43
+ Synchronisable.models = %w(Team Match)
44
+ end
45
45
 
46
- # subject do
47
- # -> { Synchronisable.sync(Match, Player) }
48
- # end
46
+ subject do
47
+ -> { Synchronisable.sync(Match, Player) }
48
+ end
49
+
50
+ it { is_expected.to change { Match.count }.by(1) }
51
+ it { is_expected.to change { Team.count }.by(2) }
52
+ it { is_expected.to change { Player.count }.by(4) }
53
+ it { is_expected.to change { MatchPlayer.count }.by(4) }
49
54
 
50
- # it { is_expected.to change { Match.count }.by(1) }
51
- # it { is_expected.to change { Player.count }.by(22) }
52
- # it { is_expected.not_to change { Team.count }.by(2) }
55
+ it { is_expected.not_to change { Stage.count } }
56
+ it { is_expected.not_to change { Tournament.count } }
53
57
 
54
- # it { is_expected.to change { Synchronisable::Import.count }.by(5) }
55
- # end
58
+ it { is_expected.to change { Synchronisable::Import.count }.by(11) }
59
+ end
56
60
  end
57
61
  end
58
62
  end
@@ -35,7 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency "database_cleaner"
36
36
  spec.add_development_dependency "mutant"
37
37
  spec.add_development_dependency "mutant-rspec"
38
- spec.add_development_dependency "guard-spork"
39
38
  spec.add_development_dependency "guard-rspec"
40
39
  spec.add_development_dependency "simplecov"
41
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synchronisable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasiliy Yorkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-07 00:00:00.000000000 Z
11
+ date: 2014-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -234,20 +234,6 @@ dependencies:
234
234
  - - ">="
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
- - !ruby/object:Gem::Dependency
238
- name: guard-spork
239
- requirement: !ruby/object:Gem::Requirement
240
- requirements:
241
- - - ">="
242
- - !ruby/object:Gem::Version
243
- version: '0'
244
- type: :development
245
- prerelease: false
246
- version_requirements: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - ">="
249
- - !ruby/object:Gem::Version
250
- version: '0'
251
237
  - !ruby/object:Gem::Dependency
252
238
  name: guard-rspec
253
239
  requirement: !ruby/object:Gem::Requirement
@@ -301,6 +287,8 @@ files:
301
287
  - lib/generators/synchronisable/templates/initializer.rb
302
288
  - lib/synchronisable.rb
303
289
  - lib/synchronisable/attribute_mapper.rb
290
+ - lib/synchronisable/bootstrap/i18n.rb
291
+ - lib/synchronisable/configuration.rb
304
292
  - lib/synchronisable/context.rb
305
293
  - lib/synchronisable/controller.rb
306
294
  - lib/synchronisable/dsl/associations.rb
@@ -316,8 +304,8 @@ files:
316
304
  - lib/synchronisable/exceptions.rb
317
305
  - lib/synchronisable/gateway.rb
318
306
  - lib/synchronisable/helper/logging.rb
319
- - lib/synchronisable/input_descriptor.rb
320
- - lib/synchronisable/input_parser.rb
307
+ - lib/synchronisable/input/descriptor.rb
308
+ - lib/synchronisable/input/parser.rb
321
309
  - lib/synchronisable/locale/en.yml
322
310
  - lib/synchronisable/locale/ru.yml
323
311
  - lib/synchronisable/model.rb
@@ -451,7 +439,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
451
439
  version: '0'
452
440
  requirements: []
453
441
  rubyforge_project:
454
- rubygems_version: 2.2.0
442
+ rubygems_version: 2.2.2
455
443
  signing_key:
456
444
  specification_version: 4
457
445
  summary: Provides base fuctionality (models, DSL) for AR synchronization with external
@@ -1,52 +0,0 @@
1
- module Synchronisable
2
- # Provides a set of helper methods
3
- # to describe user input.
4
- #
5
- # @api private
6
- #
7
- # @see Synchronisable::InputParser
8
- class InputDescriptor
9
- attr_reader :data
10
-
11
- def initialize(data)
12
- @data = data
13
- end
14
-
15
- def empty?
16
- @data.blank?
17
- end
18
-
19
- def params?
20
- @data.is_a?(Hash)
21
- end
22
-
23
- def remote_id?
24
- @data.is_a?(String)
25
- end
26
-
27
- def local_id?
28
- @data.is_a?(Integer)
29
- end
30
-
31
- def array_of_ids?
32
- enumerable? && (
33
- first_element.is_a?(String) ||
34
- first_element.is_a?(Integer)
35
- )
36
- end
37
-
38
- def element_class
39
- first_element.try(:class)
40
- end
41
-
42
- private
43
-
44
- def first_element
45
- @data.try(:first)
46
- end
47
-
48
- def enumerable?
49
- @data.is_a?(Enumerable)
50
- end
51
- end
52
- end
@@ -1,68 +0,0 @@
1
- require 'synchronisable/input_descriptor'
2
-
3
- module Synchronisable
4
- # Responsible for guessing the user input format.
5
- #
6
- # @api private
7
- #
8
- # @see Synchronisable::InputDescriptor
9
- class InputParser
10
- def initialize(model, synchronizer)
11
- @model = model
12
- @synchronizer = synchronizer
13
- end
14
-
15
- # Parses the user input.
16
- #
17
- # @param data [Array<Hash>, Array<String>, Array<Integer>, String, Integer]
18
- # synchronization data to handle.
19
- #
20
- # @return [Array<Hash>] array of hashes with remote attributes
21
- def parse(data)
22
- input = InputDescriptor.new(data)
23
-
24
- result = case
25
- when input.empty?
26
- @synchronizer.fetch
27
- when input.params?
28
- find_or_fetch_by_params(input.data)
29
- when input.remote_id?
30
- @synchronizer.find(data)
31
- when input.local_id?
32
- find_by_local_id(data)
33
- when input.array_of_ids?
34
- find_by_array_of_ids(input)
35
- else
36
- result = data.dup
37
- end
38
-
39
- [result].flatten.compact
40
- end
41
-
42
- private
43
-
44
- def find_or_fetch_by_params(params)
45
- sync_method = params.key?(:id) ? :find : :fetch
46
- @synchronizer.send(sync_method, params)
47
- end
48
-
49
- def find_by_array_of_ids(input)
50
- records = find_imports(input.element_class.name, input.data)
51
- records.map { |r| @synchronizer.find(r.remote_id) }
52
- end
53
-
54
- def find_by_local_id(id)
55
- import = @model.find_by(id: id).try(:import)
56
- import ? @synchronizer.find(import.remote_id) : nil
57
- end
58
-
59
- def find_imports(class_name, ids)
60
- case class_name
61
- when 'Fixnum'
62
- ids.map { |id| @model.find_by(id: id).try(&:import) }
63
- when 'String'
64
- ids.map { |id| Import.find_by(id: id) }
65
- end
66
- end
67
- end
68
- end