test_track_rails_client 4.0.0.alpha29 → 4.0.0.alpha30

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
- SHA256:
3
- metadata.gz: bd9ebe9de44fd28a8881162160fc6bdaa0b4a5285599d124d71e7541589544b2
4
- data.tar.gz: 8fadbaec2b3fa4e3b16fb32e5b243cfc7eee49fd4d664feea0302f5d8ee92df8
2
+ SHA1:
3
+ metadata.gz: 42a893b89a20e0f59b3141ebd08fec53a25de95c
4
+ data.tar.gz: 3103bf47ccd21a2a7dd410e00f977ac1932630c0
5
5
  SHA512:
6
- metadata.gz: 6554293a72b601f5a7920d03629d40fcf877ea1a07d4de11d43658ca9eb7091ee34ff4d66b04e48cdf9bf5ed03eb949feb7689c9a4f5d0cbe238e1d28477d059
7
- data.tar.gz: 1908d9c4ab9dffb5cdb47885a7157794497f6d74c473e9219b2194395db096e700bbce8a5b9ebbe6961810e509f8c9cce52dbceea95f27c6fd89ec78a65969d6
6
+ metadata.gz: 9e68844c7733b072423bd9553c9ad3f16fdd6b4c85eacd98e3d2c191103a5dbf4f291af0b0cdb5e00cecf518d744f320919d43feb8b40a6468c4fdd110d2d4a4
7
+ data.tar.gz: 1ce1835c1399e0d0c263c544496e4f9ed2371d7e04dab2b2fc617a26d1c7581682cfc30bee6c286ce6cc62f2fa352c9bae9be5dd44455da7e2babb816c5c2cc7
data/README.md CHANGED
@@ -46,7 +46,7 @@ development.
46
46
 
47
47
  Set up ENV vars in every environment:
48
48
 
49
- * `MIXPANEL_TOKEN` - By default, TestTrack reports to Mixpanel. If you're using a [custom analytics provider](#custom-analytics) you can omit this.
49
+ * `MIXPANEL_TOKEN` - By default, TestTrack reports to Mixpanel. If you're using a [custom analytics provider](#analytics) you can omit this.
50
50
  * `TEST_TRACK_API_URL` - Set this to the URL of your TestTrack instance with your app credentials, e.g. `http://[myapp]:[your new app password]@[your-app-domain]/`
51
51
 
52
52
  [your-app-domain] can be
@@ -336,10 +336,10 @@ TestTrack does not offer built-in functionality for analyzing the results of spl
336
336
 
337
337
  ```ruby
338
338
  # config/initializers/test_track.rb
339
- TestTrack.analytics = MyCustomAnalyticsClient.new
339
+ TestTrack.analytics_class_name = 'MyCustomAnalyticsClient'
340
340
  ```
341
341
 
342
- Your client must implement the following methods:
342
+ Your client must be a singleton or require no initializer arguments, implement the following methods:
343
343
 
344
344
  ```ruby
345
345
  # Called when a new Split has been Assigned
@@ -375,10 +375,10 @@ TestTrack provides hooks to easily integrate with your preferred error catching
375
375
 
376
376
  ```ruby
377
377
  # config/initializers/test_track.rb
378
- TestTrack.misconfiguration_notifier = MyCustomMisconfigurationNotifier.new
378
+ TestTrack.misconfiguration_notifier_class_name = 'MyCustomMisconfigurationNotifier'
379
379
  ```
380
380
 
381
- Your client must implement the following methods:
381
+ Your client must be a singleton or require no initializer arguments, implement the following methods:
382
382
 
383
383
  ```ruby
384
384
  # Called when a Split misconfiguration is detected
@@ -22,7 +22,7 @@ module TestTrack::Controller
22
22
  private
23
23
 
24
24
  def test_track_session
25
- @test_track_session ||= TestTrack::Session.new(self)
25
+ @test_track_session ||= TestTrack::WebSession.new(self)
26
26
  end
27
27
 
28
28
  def test_track_visitor
@@ -30,7 +30,7 @@ module TestTrack::Controller
30
30
  end
31
31
 
32
32
  def manage_test_track_session
33
- RequestStore[:test_track_session] = test_track_session
33
+ RequestStore[:test_track_web_session] = test_track_session
34
34
  test_track_session.manage do
35
35
  yield
36
36
  end
@@ -1,15 +1,15 @@
1
1
  class TestTrack::ABConfiguration
2
2
  include TestTrack::RequiredOptions
3
3
 
4
- def initialize(opts)
4
+ def initialize(opts) # rubocop:disable Metrics/AbcSize
5
5
  @split_name = require_option!(opts, :split_name).to_s
6
6
  true_variant = require_option!(opts, :true_variant, allow_nil: true)
7
- @split_registry = require_option!(opts, :split_registry, allow_nil: true)
7
+ @split_registry = require_option!(opts, :split_registry)
8
8
  raise ArgumentError, "unknown opts: #{opts.keys.to_sentence}" if opts.present?
9
9
 
10
10
  @true_variant = true_variant.to_s if true_variant
11
11
 
12
- raise ArgumentError, unknown_split_error_message if @split_registry && !split
12
+ raise ArgumentError, unknown_split_error_message if @split_registry.loaded? && !split
13
13
  end
14
14
 
15
15
  def variants
@@ -42,11 +42,11 @@ class TestTrack::ABConfiguration
42
42
  end
43
43
 
44
44
  def split
45
- split_registry && split_registry['splits'][split_name] && split_registry['splits'][split_name]['weights']
45
+ @split ||= split_registry.weights_for(split_name)
46
46
  end
47
47
 
48
48
  def split_variants
49
- @split_variants ||= split.keys if split_registry
49
+ @split_variants ||= split.keys if split
50
50
  end
51
51
 
52
52
  def non_true_variants
@@ -21,13 +21,13 @@ class TestTrack::Fake::Visitor
21
21
  end
22
22
 
23
23
  def split_registry
24
- TestTrack::Fake::SplitRegistry.instance.to_h
24
+ TestTrack::SplitRegistry.new(TestTrack::Fake::SplitRegistry.instance.to_h)
25
25
  end
26
26
 
27
27
  private
28
28
 
29
29
  def _assignments
30
- split_registry['splits'].keys.map do |split_name|
30
+ split_registry.split_names.map do |split_name|
31
31
  variant = TestTrack::VariantCalculator.new(visitor: self, split_name: split_name).variant
32
32
  Assignment.new(split_name, variant, false, "the_context")
33
33
  end
@@ -5,11 +5,13 @@ class TestTrack::IdentitySessionLocator
5
5
  @identity = identity
6
6
  end
7
7
 
8
- def with_visitor
8
+ def with_visitor # rubocop:disable Metrics/AbcSize
9
9
  raise ArgumentError, "must provide block to `with_visitor`" unless block_given?
10
10
 
11
- if web_context?
12
- yield session.visitor_dsl_for(identity)
11
+ if web_session.present?
12
+ yield web_session.visitor_dsl_for(identity)
13
+ elsif job_session.present?
14
+ yield job_session.visitor_dsl_for(identity)
13
15
  else
14
16
  TestTrack::OfflineSession.with_visitor_for(identity.test_track_identifier_type, identity.test_track_identifier_value) do |v|
15
17
  yield v
@@ -20,20 +22,20 @@ class TestTrack::IdentitySessionLocator
20
22
  def with_session
21
23
  raise ArgumentError, "must provide block to `with_session`" unless block_given?
22
24
 
23
- if web_context?
24
- yield session
25
+ if web_session.present?
26
+ yield web_session
25
27
  else
26
- raise "#with_session called outside of web context"
28
+ raise "#with_session called outside of web session"
27
29
  end
28
30
  end
29
31
 
30
32
  private
31
33
 
32
- def web_context?
33
- session.present?
34
+ def web_session
35
+ @web_session ||= RequestStore[:test_track_web_session]
34
36
  end
35
37
 
36
- def session
37
- @session ||= RequestStore[:test_track_session]
38
+ def job_session
39
+ @job_session ||= RequestStore[:test_track_job_session]
38
40
  end
39
41
  end
@@ -0,0 +1,36 @@
1
+ class TestTrack::JobSession
2
+ def manage
3
+ raise ArgumentError, "must provide block to `manage`" unless block_given?
4
+ raise "already in use" unless RequestStore[:test_track_job_session].nil?
5
+
6
+ RequestStore[:test_track_job_session] = self
7
+ yield
8
+ ensure
9
+ notify_unsynced_assignments!
10
+ RequestStore[:test_track_job_session] = nil
11
+ end
12
+
13
+ def visitor_dsl_for(identity)
14
+ raise "must be called within `manage` block" if RequestStore[:test_track_job_session].nil?
15
+
16
+ TestTrack::VisitorDSL.new(for_identity(identity))
17
+ end
18
+
19
+ private
20
+
21
+ def for_identity(identity)
22
+ identity_visitor_map[identity] ||= TestTrack::LazyVisitorByIdentity.new(identity)
23
+ end
24
+
25
+ def notify_unsynced_assignments!
26
+ identity_visitor_map.each_value do |visitor|
27
+ if visitor.loaded? && visitor.unsynced_assignments.present?
28
+ TestTrack::ThreadedVisitorNotifier.new(visitor).notify
29
+ end
30
+ end
31
+ end
32
+
33
+ def identity_visitor_map
34
+ @identity_visitor_map ||= {}
35
+ end
36
+ end
@@ -44,11 +44,15 @@ class TestTrack::NotifyAssignmentJob
44
44
  experience_sampling_weight.zero?
45
45
  end
46
46
 
47
+ def sample_event?
48
+ Kernel.rand(experience_sampling_weight).zero?
49
+ end
50
+
47
51
  def experience_sampling_weight
48
- @experience_sampling_weight ||= TestTrack::Remote::SplitRegistry.experience_sampling_weight
52
+ @experience_sampling_weight ||= split_registry.experience_sampling_weight
49
53
  end
50
54
 
51
- def sample_event?
52
- Kernel.rand(experience_sampling_weight).zero?
55
+ def split_registry
56
+ @split_registry ||= TestTrack::SplitRegistry.from_remote
53
57
  end
54
58
  end
@@ -34,10 +34,6 @@ class TestTrack::Remote::SplitRegistry
34
34
  fetch_cache { nil } # cache the missing registry for 5 seconds if we can't get one
35
35
  end
36
36
 
37
- def experience_sampling_weight
38
- to_hash.fetch('experience_sampling_weight')
39
- end
40
-
41
37
  private
42
38
 
43
39
  def fetch_cache(&block)
@@ -0,0 +1,39 @@
1
+ class TestTrack::SplitRegistry
2
+ def self.from_remote
3
+ new(TestTrack::Remote::SplitRegistry.to_hash)
4
+ end
5
+
6
+ def initialize(registry_hash)
7
+ @registry_hash = registry_hash
8
+ end
9
+
10
+ def include?(split_name)
11
+ registry_hash['splits'].key?(split_name)
12
+ end
13
+
14
+ def loaded?
15
+ registry_hash.present?
16
+ end
17
+
18
+ def split_names
19
+ registry_hash['splits'].keys
20
+ end
21
+
22
+ def experience_sampling_weight
23
+ registry_hash.fetch('experience_sampling_weight')
24
+ end
25
+
26
+ def weights_for(split_name)
27
+ registry_hash && registry_hash['splits'][split_name] && registry_hash['splits'][split_name]['weights'].freeze
28
+ end
29
+
30
+ def to_v1_hash
31
+ registry_hash && registry_hash['splits'].each_with_object({}) do |(k, v), result|
32
+ result[k] = v['weights']
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :registry_hash
39
+ end
@@ -14,7 +14,7 @@ class TestTrack::VariantCalculator
14
14
  end
15
15
 
16
16
  def variant
17
- return nil unless split_registry
17
+ return nil unless split_registry.loaded?
18
18
  @variant ||= _variant || raise("Assignment bucket out of range. #{assignment_bucket} unmatched in #{split_name}: #{weighting}")
19
19
  end
20
20
 
@@ -31,7 +31,7 @@ class TestTrack::VariantCalculator
31
31
  end
32
32
 
33
33
  def weighting
34
- @weighting ||= (split_registry['splits'][split_name] && split_registry['splits'][split_name]['weights']) ||
34
+ @weighting ||= split_registry.weights_for(split_name) ||
35
35
  raise("TestTrack split '#{split_name}' not found. Need to write/run a migration?")
36
36
  end
37
37
 
@@ -7,10 +7,10 @@ class TestTrack::VaryDSL
7
7
  def initialize(opts = {})
8
8
  @assignment = require_option!(opts, :assignment)
9
9
  @context = require_option!(opts, :context)
10
- @split_registry = require_option!(opts, :split_registry, allow_nil: true)
10
+ @split_registry = require_option!(opts, :split_registry)
11
11
  raise ArgumentError, "unknown opts: #{opts.keys.to_sentence}" if opts.present?
12
12
 
13
- if @split_registry && !split
13
+ if @split_registry.loaded? && !split
14
14
  raise ArgumentError, "unknown split: #{split_name}." \
15
15
  "#{' You may need to run rake test_track:schema:load.' if Rails.env.development?}"
16
16
  end
@@ -34,11 +34,11 @@ class TestTrack::VaryDSL
34
34
  delegate :split_name, to: :assignment
35
35
 
36
36
  def split
37
- split_registry && split_registry['splits'][split_name] && split_registry['splits'][split_name]['weights']
37
+ @split ||= split_registry.weights_for(split_name)
38
38
  end
39
39
 
40
40
  def split_variants
41
- @split_variants ||= split.keys if split_registry
41
+ @split_variants ||= split.keys if split
42
42
  end
43
43
 
44
44
  def notify_because_vary(msg)
@@ -64,13 +64,7 @@ class TestTrack::Visitor
64
64
  end
65
65
 
66
66
  def split_registry
67
- @split_registry ||= TestTrack::Remote::SplitRegistry.to_hash
68
- end
69
-
70
- def v1_split_registry
71
- @v1_split_registry ||= split_registry && split_registry['splits'].each_with_object({}) do |(k, v), result|
72
- result[k] = v['weights']
73
- end
67
+ @split_registry ||= TestTrack::SplitRegistry.from_remote
74
68
  end
75
69
 
76
70
  def link_identity!(identity)
@@ -160,6 +154,6 @@ class TestTrack::Visitor
160
154
  app_name = URI.parse(TestTrack.private_url).user
161
155
  split_name = split_name.to_s
162
156
  prefixed = "#{app_name}.#{split_name}"
163
- split_registry['splits'].key?(prefixed) ? prefixed : split_name
157
+ split_registry.include?(prefixed) ? prefixed : split_name
164
158
  end
165
159
  end
@@ -1,7 +1,4 @@
1
- require 'delayed_job'
2
- require 'delayed_job_active_record'
3
-
4
- class TestTrack::Session
1
+ class TestTrack::WebSession
5
2
  COOKIE_LIFESPAN = 1.year # Used for visitor cookie
6
3
 
7
4
  def initialize(controller)
@@ -31,7 +28,7 @@ class TestTrack::Session
31
28
  url: TestTrack.url,
32
29
  cookieDomain: cookie_domain,
33
30
  cookieName: visitor_cookie_name,
34
- registry: current_visitor.v1_split_registry,
31
+ registry: current_visitor.split_registry.to_v1_hash,
35
32
  assignments: current_visitor.assignment_json
36
33
  }
37
34
  end
@@ -70,7 +67,7 @@ class TestTrack::Session
70
67
  end
71
68
 
72
69
  def visitors
73
- @visitors ||= TestTrack::SessionVisitorRepository.new(
70
+ @visitors ||= TestTrack::WebSessionVisitorRepository.new(
74
71
  current_identity: current_identity,
75
72
  unauthenticated_visitor_id: unauthenticated_visitor_id
76
73
  )
@@ -1,4 +1,4 @@
1
- class TestTrack::SessionVisitorRepository
1
+ class TestTrack::WebSessionVisitorRepository
2
2
  attr_reader :current_identity, :unauthenticated_visitor_id
3
3
 
4
4
  def initialize(current_identity:, unauthenticated_visitor_id:)
@@ -0,0 +1,15 @@
1
+ module Delayed
2
+ module Plugins
3
+ class JobSessionPlugin < Delayed::Plugin
4
+ callbacks do |lifecycle|
5
+ lifecycle.around(:invoke_job) do |job, *args, &block|
6
+ test_track_job_session = TestTrack::JobSession.new
7
+
8
+ test_track_job_session.manage do
9
+ block.call(job, *args)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/test_track.rb CHANGED
@@ -21,27 +21,53 @@ module TestTrack
21
21
 
22
22
  class << self
23
23
  def analytics
24
- @analytics ||= analytics_wrapper(mixpanel)
24
+ analytics_wrapper(analytics_instance || mixpanel)
25
25
  end
26
26
 
27
- def analytics=(client)
28
- @analytics = client.is_a?(TestTrack::Analytics::SafeWrapper) ? client : analytics_wrapper(client)
27
+ def analytics=(*_)
28
+ raise "`TestTrack.analytics=` is not longer supported. Please use `TestTrack.analytics_class_name=` instead."
29
+ end
30
+
31
+ def analytics_class_name=(client_class_name)
32
+ begin
33
+ client_class = client_class_name.constantize
34
+ client_class.respond_to?(:instance) || client_class.new
35
+ rescue StandardError
36
+ raise "analytics_class_name #{client_class_name} must be a class that can be instantiated without arguments"
37
+ end
38
+ @analytics_class_name = client_class_name
29
39
  end
30
40
 
31
41
  def misconfiguration_notifier
32
- @misconfiguration_notifier ||= TestTrack::MisconfigurationNotifier::Wrapper.new(default_notifier)
42
+ TestTrack::MisconfigurationNotifier::Wrapper.new(misconfiguration_notifier_instance || default_notifier)
33
43
  end
34
44
 
35
- def misconfiguration_notifier=(notifier)
36
- @misconfiguration_notifier = if notifier.is_a?(TestTrack::MisconfigurationNotifier::Wrapper)
37
- notifier
38
- else
39
- TestTrack::MisconfigurationNotifier::Wrapper.new(notifier)
40
- end
45
+ def misconfiguration_notifier_class_name=(notifier_class_name)
46
+ begin
47
+ notifier_class = notifier_class_name.constantize
48
+ notifier_class.respond_to?(:instance) || notifier_class.new
49
+ rescue StandardError
50
+ raise "misconfiguration_notifier_class_name #{notifier_class_name} must be a class that can be instantiated without arguments"
51
+ end
52
+ @misconfiguration_notifier_class_name = notifier_class_name
41
53
  end
42
54
 
43
55
  private
44
56
 
57
+ def analytics_instance
58
+ analytics_class = @analytics_class_name&.constantize
59
+ if analytics_class
60
+ analytics_class.respond_to?(:instance) ? analytics_class.instance : analytics_class.new
61
+ end
62
+ end
63
+
64
+ def misconfiguration_notifier_instance
65
+ notifier_class = @misconfiguration_notifier_class_name&.constantize
66
+ if notifier_class
67
+ notifier_class.respond_to?(:instance) ? notifier_class.instance : notifier_class.new
68
+ end
69
+ end
70
+
45
71
  def default_notifier
46
72
  if defined?(::Airbrake)
47
73
  TestTrack::MisconfigurationNotifier::Airbrake.new
@@ -1,3 +1,3 @@
1
1
  module TestTrackRailsClient
2
- VERSION = "4.0.0.alpha29" # rubocop:disable Style/MutableConstant
2
+ VERSION = "4.0.0.alpha30" # rubocop:disable Style/MutableConstant
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test_track_rails_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.alpha29
4
+ version: 4.0.0.alpha30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan O'Neill
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2019-07-22 00:00:00.000000000 Z
16
+ date: 2019-08-27 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: delayed_job
@@ -254,6 +254,7 @@ files:
254
254
  - app/models/test_track/fake/visitor_detail.rb
255
255
  - app/models/test_track/fake_server.rb
256
256
  - app/models/test_track/identity_session_locator.rb
257
+ - app/models/test_track/job_session.rb
257
258
  - app/models/test_track/lazy_visitor_by_identity.rb
258
259
  - app/models/test_track/misconfiguration_notifier.rb
259
260
  - app/models/test_track/notify_assignment_job.rb
@@ -269,14 +270,15 @@ files:
269
270
  - app/models/test_track/remote/split_registry.rb
270
271
  - app/models/test_track/remote/visitor.rb
271
272
  - app/models/test_track/remote/visitor_detail.rb
272
- - app/models/test_track/session.rb
273
- - app/models/test_track/session_visitor_repository.rb
273
+ - app/models/test_track/split_registry.rb
274
274
  - app/models/test_track/threaded_visitor_notifier.rb
275
275
  - app/models/test_track/unsynced_assignments_notifier.rb
276
276
  - app/models/test_track/variant_calculator.rb
277
277
  - app/models/test_track/vary_dsl.rb
278
278
  - app/models/test_track/visitor.rb
279
279
  - app/models/test_track/visitor_dsl.rb
280
+ - app/models/test_track/web_session.rb
281
+ - app/models/test_track/web_session_visitor_repository.rb
280
282
  - app/models/testtrack_cli.rb
281
283
  - app/views/tt/api/v1/identifier_visitors/show.json.jbuilder
282
284
  - app/views/tt/api/v1/identifiers/create.json.jbuilder
@@ -285,6 +287,7 @@ files:
285
287
  - app/views/tt/api/v1/visitors/show.json.jbuilder
286
288
  - config/initializers/test_track_api.rb
287
289
  - config/routes.rb
290
+ - lib/delayed/plugins/job_session_plugin.rb
288
291
  - lib/generators/test_track/migration_generator.rb
289
292
  - lib/tasks/test_track_rails_client_tasks.rake
290
293
  - lib/test_track.rb
@@ -295,14 +298,12 @@ files:
295
298
  - lib/test_track_rails_client/engine.rb
296
299
  - lib/test_track_rails_client/rspec_helpers.rb
297
300
  - lib/test_track_rails_client/version.rb
298
- - vendor/Gemfile.lock
299
301
  - vendor/bin/testtrack-cli/testtrack.darwin
300
302
  - vendor/bin/testtrack-cli/testtrack.linux
301
303
  - vendor/gems/fakeable_her/fakeable_her.gemspec
302
304
  - vendor/gems/fakeable_her/lib/fakeable_her.rb
303
305
  - vendor/gems/fakeable_her/lib/fakeable_her/model.rb
304
306
  - vendor/gems/fakeable_her/lib/fakeable_her/version.rb
305
- - vendor/gems/her/Gemfile.lock
306
307
  - vendor/gems/her/LICENSE
307
308
  - vendor/gems/her/her.gemspec
308
309
  - vendor/gems/her/lib/her.rb
@@ -355,7 +356,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
355
356
  - !ruby/object:Gem::Version
356
357
  version: 1.3.1
357
358
  requirements: []
358
- rubygems_version: 3.0.4
359
+ rubyforge_project:
360
+ rubygems_version: 2.5.1
359
361
  signing_key:
360
362
  specification_version: 4
361
363
  summary: Rails client for TestTrack
data/vendor/Gemfile.lock DELETED
@@ -1,82 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- her (0.8.6)
5
- activemodel (>= 3.0.0, <= 6.0.0)
6
- activesupport (>= 3.0.0, <= 6.0.0)
7
- faraday (>= 0.8, < 1.0)
8
- multi_json (~> 1.7)
9
-
10
- GEM
11
- remote: https://rubygems.org/
12
- specs:
13
- activemodel (5.1.2)
14
- activesupport (= 5.1.2)
15
- activesupport (5.1.2)
16
- concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (~> 0.7)
18
- minitest (~> 5.1)
19
- tzinfo (~> 1.1)
20
- appraisal (2.2.0)
21
- bundler
22
- rake
23
- thor (>= 0.14.0)
24
- coderay (1.1.2)
25
- concurrent-ruby (1.0.5)
26
- concurrent-ruby (1.0.5-java)
27
- diff-lcs (1.3)
28
- faraday (0.14.0)
29
- multipart-post (>= 1.2, < 3)
30
- ffi (1.9.23-java)
31
- i18n (0.8.6)
32
- json (1.8.6)
33
- json (1.8.6-java)
34
- method_source (0.9.0)
35
- minitest (5.10.3)
36
- multi_json (1.13.1)
37
- multipart-post (2.0.0)
38
- pry (0.11.3)
39
- coderay (~> 1.1.0)
40
- method_source (~> 0.9.0)
41
- pry (0.11.3-java)
42
- coderay (~> 1.1.0)
43
- method_source (~> 0.9.0)
44
- spoon (~> 0.0)
45
- rake (10.5.0)
46
- rspec (3.6.0)
47
- rspec-core (~> 3.6.0)
48
- rspec-expectations (~> 3.6.0)
49
- rspec-mocks (~> 3.6.0)
50
- rspec-core (3.6.0)
51
- rspec-support (~> 3.6.0)
52
- rspec-expectations (3.6.0)
53
- diff-lcs (>= 1.2.0, < 2.0)
54
- rspec-support (~> 3.6.0)
55
- rspec-mocks (3.6.0)
56
- diff-lcs (>= 1.2.0, < 2.0)
57
- rspec-support (~> 3.6.0)
58
- rspec-support (3.6.0)
59
- spoon (0.0.6)
60
- ffi
61
- thor (0.20.0)
62
- thread_safe (0.3.6)
63
- thread_safe (0.3.6-java)
64
- tzinfo (1.2.3)
65
- thread_safe (~> 0.1)
66
-
67
- PLATFORMS
68
- java
69
- ruby
70
-
71
- DEPENDENCIES
72
- activemodel (>= 3.2.0)
73
- activesupport (>= 3.2.0)
74
- appraisal (~> 2.2.0)
75
- her!
76
- json (~> 1.8)
77
- pry
78
- rake (~> 10.0)
79
- rspec (~> 3.5)
80
-
81
- BUNDLED WITH
82
- 1.16.1
@@ -1,81 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- her (1.0.3)
5
- activemodel (>= 4.2.1)
6
- faraday (>= 0.8, < 1.0)
7
- multi_json (~> 1.7)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- activemodel (5.2.1)
13
- activesupport (= 5.2.1)
14
- activesupport (5.2.1)
15
- concurrent-ruby (~> 1.0, >= 1.0.2)
16
- i18n (>= 0.7, < 2)
17
- minitest (~> 5.1)
18
- tzinfo (~> 1.1)
19
- ast (2.4.0)
20
- coderay (1.1.2)
21
- concurrent-ruby (1.0.5)
22
- diff-lcs (1.3)
23
- faraday (0.15.3)
24
- multipart-post (>= 1.2, < 3)
25
- i18n (1.1.1)
26
- concurrent-ruby (~> 1.0)
27
- json (1.8.6)
28
- method_source (0.9.0)
29
- minitest (5.11.3)
30
- multi_json (1.13.1)
31
- multipart-post (2.0.0)
32
- parallel (1.12.1)
33
- parser (2.5.3.0)
34
- ast (~> 2.4.0)
35
- powerpack (0.1.2)
36
- pry (0.11.3)
37
- coderay (~> 1.1.0)
38
- method_source (~> 0.9.0)
39
- rainbow (3.0.0)
40
- rake (10.5.0)
41
- rspec (3.8.0)
42
- rspec-core (~> 3.8.0)
43
- rspec-expectations (~> 3.8.0)
44
- rspec-mocks (~> 3.8.0)
45
- rspec-core (3.8.0)
46
- rspec-support (~> 3.8.0)
47
- rspec-expectations (3.8.2)
48
- diff-lcs (>= 1.2.0, < 2.0)
49
- rspec-support (~> 3.8.0)
50
- rspec-mocks (3.8.0)
51
- diff-lcs (>= 1.2.0, < 2.0)
52
- rspec-support (~> 3.8.0)
53
- rspec-support (3.8.0)
54
- rubocop (0.54.0)
55
- parallel (~> 1.10)
56
- parser (>= 2.5)
57
- powerpack (~> 0.1)
58
- rainbow (>= 2.2.2, < 4.0)
59
- ruby-progressbar (~> 1.7)
60
- unicode-display_width (~> 1.0, >= 1.0.1)
61
- ruby-progressbar (1.10.0)
62
- thread_safe (0.3.6)
63
- tzinfo (1.2.5)
64
- thread_safe (~> 0.1)
65
- unicode-display_width (1.4.0)
66
-
67
- PLATFORMS
68
- ruby
69
-
70
- DEPENDENCIES
71
- activemodel (>= 3.2.0)
72
- activesupport (>= 3.2.0)
73
- her!
74
- json (~> 1.8)
75
- pry
76
- rake (~> 10.0)
77
- rspec (~> 3.5)
78
- rubocop (= 0.54.0)
79
-
80
- BUNDLED WITH
81
- 1.17.1