startback-websocket 0.14.0 → 0.14.1

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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -2
  3. data/README.md +64 -9
  4. data/lib/startback/ext/context.rb +6 -0
  5. data/lib/startback/ext.rb +1 -2
  6. data/lib/startback/websocket/app.rb +82 -0
  7. data/lib/startback/websocket/hub/app.rb +28 -0
  8. data/lib/startback/websocket/hub/builder.rb +55 -0
  9. data/lib/startback/websocket/hub/errors.rb +9 -0
  10. data/lib/startback/websocket/hub/message.rb +29 -0
  11. data/lib/startback/websocket/hub/middleware/command_handler.rb +34 -0
  12. data/lib/startback/websocket/hub/middleware/room_handler.rb +30 -0
  13. data/lib/startback/websocket/hub/middleware.rb +12 -0
  14. data/lib/startback/websocket/hub/participant.rb +16 -0
  15. data/lib/startback/websocket/hub/room.rb +46 -0
  16. data/lib/startback/websocket/hub.rb +15 -0
  17. data/lib/startback/websocket.rb +8 -0
  18. data/spec/spec_helper.rb +21 -32
  19. data/spec/unit/hub/test_builder.rb +141 -0
  20. data/spec/unit/hub/test_room.rb +27 -0
  21. data/spec/unit/test_app.rb +35 -0
  22. data/tasks/test.rake +0 -1
  23. metadata +20 -91
  24. data/lib/startback/audit/prometheus.rb +0 -87
  25. data/lib/startback/audit/shared.rb +0 -17
  26. data/lib/startback/audit/trailer.rb +0 -129
  27. data/lib/startback/audit.rb +0 -3
  28. data/lib/startback/caching/entity_cache.rb +0 -157
  29. data/lib/startback/caching/no_store.rb +0 -28
  30. data/lib/startback/caching/store.rb +0 -34
  31. data/lib/startback/context/h_factory.rb +0 -43
  32. data/lib/startback/context/middleware.rb +0 -53
  33. data/lib/startback/context.rb +0 -122
  34. data/lib/startback/errors.rb +0 -197
  35. data/lib/startback/event/agent.rb +0 -84
  36. data/lib/startback/event/bus/bunny/async.rb +0 -162
  37. data/lib/startback/event/bus/bunny.rb +0 -1
  38. data/lib/startback/event/bus/memory/async.rb +0 -45
  39. data/lib/startback/event/bus/memory/sync.rb +0 -35
  40. data/lib/startback/event/bus/memory.rb +0 -2
  41. data/lib/startback/event/bus.rb +0 -100
  42. data/lib/startback/event/engine.rb +0 -94
  43. data/lib/startback/event/ext/context.rb +0 -5
  44. data/lib/startback/event/ext/operation.rb +0 -13
  45. data/lib/startback/event.rb +0 -47
  46. data/lib/startback/ext/date_time.rb +0 -9
  47. data/lib/startback/ext/time.rb +0 -9
  48. data/lib/startback/model.rb +0 -6
  49. data/lib/startback/operation/error_operation.rb +0 -19
  50. data/lib/startback/operation/multi_operation.rb +0 -28
  51. data/lib/startback/operation.rb +0 -78
  52. data/lib/startback/services.rb +0 -11
  53. data/lib/startback/support/data_object.rb +0 -71
  54. data/lib/startback/support/env.rb +0 -41
  55. data/lib/startback/support/fake_logger.rb +0 -18
  56. data/lib/startback/support/hooks.rb +0 -48
  57. data/lib/startback/support/log_formatter.rb +0 -34
  58. data/lib/startback/support/logger.rb +0 -34
  59. data/lib/startback/support/operation_runner.rb +0 -150
  60. data/lib/startback/support/robustness.rb +0 -157
  61. data/lib/startback/support/transaction_manager.rb +0 -25
  62. data/lib/startback/support/transaction_policy.rb +0 -33
  63. data/lib/startback/support/world.rb +0 -54
  64. data/lib/startback/support.rb +0 -26
  65. data/lib/startback/version.rb +0 -8
  66. data/lib/startback/web/api.rb +0 -99
  67. data/lib/startback/web/auto_caching.rb +0 -85
  68. data/lib/startback/web/catch_all.rb +0 -52
  69. data/lib/startback/web/cors_headers.rb +0 -80
  70. data/lib/startback/web/health_check.rb +0 -49
  71. data/lib/startback/web/magic_assets/ng_html_transformer.rb +0 -80
  72. data/lib/startback/web/magic_assets/rake_tasks.rb +0 -64
  73. data/lib/startback/web/magic_assets.rb +0 -98
  74. data/lib/startback/web/middleware.rb +0 -13
  75. data/lib/startback/web/prometheus.rb +0 -16
  76. data/lib/startback/web/shield.rb +0 -58
  77. data/lib/startback.rb +0 -43
  78. data/spec/unit/audit/test_prometheus.rb +0 -72
  79. data/spec/unit/audit/test_trailer.rb +0 -105
  80. data/spec/unit/caching/test_entity_cache.rb +0 -136
  81. data/spec/unit/context/test_abstraction_factory.rb +0 -64
  82. data/spec/unit/context/test_dup.rb +0 -42
  83. data/spec/unit/context/test_fork.rb +0 -37
  84. data/spec/unit/context/test_h_factory.rb +0 -31
  85. data/spec/unit/context/test_middleware.rb +0 -45
  86. data/spec/unit/context/test_with_world.rb +0 -20
  87. data/spec/unit/context/test_world.rb +0 -17
  88. data/spec/unit/event/bus/memory/test_async.rb +0 -43
  89. data/spec/unit/event/bus/memory/test_sync.rb +0 -43
  90. data/spec/unit/support/hooks/test_after_hook.rb +0 -54
  91. data/spec/unit/support/hooks/test_before_hook.rb +0 -54
  92. data/spec/unit/support/operation_runner/test_around_run.rb +0 -156
  93. data/spec/unit/support/operation_runner/test_before_after_call.rb +0 -48
  94. data/spec/unit/support/test_data_object.rb +0 -156
  95. data/spec/unit/support/test_env.rb +0 -75
  96. data/spec/unit/support/test_robusteness.rb +0 -229
  97. data/spec/unit/support/test_transaction_manager.rb +0 -64
  98. data/spec/unit/support/test_world.rb +0 -72
  99. data/spec/unit/test_event.rb +0 -62
  100. data/spec/unit/test_operation.rb +0 -55
  101. data/spec/unit/test_support.rb +0 -40
  102. data/spec/unit/web/fixtures/assets/app/hello.es6 +0 -4
  103. data/spec/unit/web/fixtures/assets/app/hello.html +0 -1
  104. data/spec/unit/web/fixtures/assets/index.es6 +0 -1
  105. data/spec/unit/web/test_api.rb +0 -82
  106. data/spec/unit/web/test_auto_caching.rb +0 -81
  107. data/spec/unit/web/test_catch_all.rb +0 -77
  108. data/spec/unit/web/test_cors_headers.rb +0 -88
  109. data/spec/unit/web/test_healthcheck.rb +0 -59
  110. data/spec/unit/web/test_magic_assets.rb +0 -82
@@ -1,98 +0,0 @@
1
- require 'sprockets'
2
- module Startback
3
- module Web
4
- #
5
- # Rack application & middleware that can be used to simplify javascript
6
- # and css assets management, using Sprockets.
7
- #
8
- # Example:
9
- #
10
- # # Used as rack app, typically under a path
11
- # Rack::Builder.new do
12
- # map '/assets' do
13
- # run Startback::Web::MagicAssets.new({
14
- # folder: "/path/to/assets/src"
15
- # })
16
- # end
17
- # run MyApp
18
- # end
19
- #
20
- # # Used as a rack middleware, e.g. in a Sinatra application
21
- # use Startback::Web::MagicAssets, {
22
- # folder: "/path/to/assets/src",
23
- # path: "/assets"
24
- # }
25
- #
26
- # Sprocket configuration can be done through the `:sprocket` option:
27
- #
28
- # use Startback::Web::MagicAssets, {
29
- # sprockets: {
30
- # :css_compressor => :scss
31
- # }
32
- # }
33
- #
34
- class MagicAssets
35
-
36
- DEFAULT_OPTIONS = {
37
- sprockets: {},
38
- plugins: {}
39
- }
40
-
41
- def initialize(app, options = {})
42
- app, options = nil, app if app.is_a?(Hash)
43
- @app = app
44
- @options = DEFAULT_OPTIONS.merge(options)
45
- @sprockets = build_sprockets
46
- end
47
- attr_reader :sprockets
48
-
49
- def call(env)
50
- if new_env = is_match?(env)
51
- @sprockets.call(new_env)
52
- else
53
- @app.call(env)
54
- end
55
- end
56
-
57
- def [](*args, &bl)
58
- @sprockets.[](*args, &bl)
59
- end
60
-
61
- private
62
-
63
- def path
64
- @options[:path]
65
- end
66
-
67
- def is_match?(env)
68
- if @app.nil?
69
- # Not used as a middleware, use this env and match
70
- env
71
- elsif env['PATH_INFO'].start_with?(path)
72
- # Used as a middleware, and PATH_INFO starts with the
73
- # assets path => strip it for sprockets
74
- env.merge("PATH_INFO" => env["PATH_INFO"].sub(path, ""))
75
- else
76
- # No match, let @app execute with the untouched environment
77
- nil
78
- end
79
- end
80
-
81
- def build_sprockets
82
- Sprockets::Environment.new.tap{|s|
83
- Array(@options[:folder]).each do |folder|
84
- s.append_path(folder)
85
- end
86
- @options[:sprockets].each_pair do |k,v|
87
- s.public_send(:"#{k}=", v)
88
- end
89
- @options[:plugins].each do |p|
90
- p.install(s)
91
- end
92
- }
93
- end
94
-
95
- end # class MagicAssets
96
- end # module Web
97
- end # module Startback
98
- require_relative 'magic_assets/rake_tasks'
@@ -1,13 +0,0 @@
1
- module Startback
2
- module Web
3
- module Middleware
4
-
5
- protected
6
-
7
- def context(env = @env)
8
- ::Startback::Context::Middleware.context(env) || Errors.server_error!("Unable to find context!!")
9
- end
10
-
11
- end # module Middleware
12
- end # module Web
13
- end # module Startback
@@ -1,16 +0,0 @@
1
- require 'prometheus/middleware/exporter'
2
- module Startback
3
- module Web
4
- #
5
- # Can be used to expose the prometheus metrics inside a Startback
6
- # application.
7
- #
8
- # Example:
9
- #
10
- # use Startback::Web::Prometheus
11
- #
12
- class Prometheus < Prometheus::Middleware::Exporter
13
-
14
- end # class Prometheus
15
- end # module Web
16
- end # module Startback
@@ -1,58 +0,0 @@
1
- module Startback
2
- module Web
3
- #
4
- # This Rack middleware catches all known exceptions raised by sublayers
5
- # in the Rack chain. Those exceptions are converted to proper HTTP error
6
- # codes and friendly error messages encoded in json.
7
- #
8
- # Please check the Errors module about status codes used for each Startback
9
- # error.
10
- #
11
- # This class aims at being used as top level of a Rack chain.
12
- #
13
- # Examples:
14
- #
15
- # Rack::Builder.new do
16
- # use Startback::Web::Shield
17
- # end
18
- #
19
- class Shield < Rack::Robustness
20
- include Errors
21
-
22
- self.no_catch_all
23
- self.content_type 'application/json'
24
-
25
- # Decoding errors from json and csv are considered user's fault
26
- self.on(Finitio::TypeError){ 400 }
27
- self.on(::NotImplementedError){ 501 }
28
-
29
- # Various other codes for the framework specific error classes
30
- self.on(Startback::Errors::Error) {|ex|
31
- ex.class.status
32
- }
33
-
34
- # A bit of logic to choose the best error message for the user
35
- # according to the error class
36
- self.body{|ex|
37
- body_for(ex).to_json
38
- }
39
-
40
- def body_for(ex)
41
- ex = ex.root_cause if ex.is_a?(Finitio::TypeError)
42
- body = { code: ex.class.name, description: ex.message }
43
- return body unless ex.is_a?(Startback::Errors::Error)
44
- return body unless ex.has_causes?
45
-
46
- body[:causes] = ex.causes
47
- .filter{|cause|
48
- cause.is_a?(Startback::Errors::Error)
49
- }
50
- .map{|cause|
51
- body_for(cause)
52
- }
53
- body
54
- end
55
-
56
- end # class Shield
57
- end # module Web
58
- end # module Startback
data/lib/startback.rb DELETED
@@ -1,43 +0,0 @@
1
- require 'sinatra'
2
- require 'rack/robustness'
3
- require 'finitio'
4
- require 'logger'
5
- require 'path'
6
- require 'ostruct'
7
- require 'benchmark'
8
-
9
- # Provides a reusable backend framework for backend components written
10
- # in ruby.
11
- #
12
- # The framework installs conventions regarding:
13
- #
14
- # - The exposition of web service APIs (Framework::Api, on top of Sinatra)
15
- # - Operations (Framework::Operation)
16
- # - Error handling (Framework::Errors) and their handling in web APIs
17
- # (based on Rack::Robustness)
18
- # - General code support (Framework::Support modules & classes).
19
- #
20
- # Please refer to the documentation of those main abstractions for details.
21
- #
22
- module Startback
23
-
24
- # Simply checks that a path exists of raise an error
25
- def self._!(path)
26
- Path(path).tap do |p|
27
- raise "Missing #{p.basename}." unless p.exists?
28
- end
29
- end
30
-
31
- require_relative 'startback/version'
32
- require_relative 'startback/ext'
33
- require_relative 'startback/errors'
34
- require_relative 'startback/support'
35
- require_relative 'startback/model'
36
- require_relative 'startback/context'
37
- require_relative 'startback/operation'
38
- require_relative 'startback/services'
39
-
40
- # Logger instance to use for the application
41
- LOGGER = ::Startback::Support::Logger.new
42
-
43
- end # module Startback
@@ -1,72 +0,0 @@
1
- require 'spec_helper'
2
- require 'startback/audit'
3
- module Startback
4
- module Audit
5
- describe Prometheus do
6
-
7
- EXPORTER = Prometheus.new({
8
- prefix: "hello",
9
- labels: {
10
- app_version: "1.0"
11
- }
12
- })
13
-
14
- class Runner
15
- include Startback::Support::OperationRunner
16
-
17
- class IdealOp < Startback::Operation
18
- def call
19
- 42
20
- end
21
- end
22
-
23
- class ExceptionalOp < Startback::Operation
24
- def call
25
- raise "Oops"
26
- end
27
- end
28
-
29
- around_run(EXPORTER)
30
- def test
31
- run IdealOp.new
32
- end
33
- def test_exp
34
- run ExceptionalOp.new
35
- end
36
- end
37
-
38
- describe 'The ideal case' do
39
- before do
40
- expect(EXPORTER.calls).to receive(:observe).with(
41
- kind_of(Numeric),
42
- hash_including(labels: {
43
- operation: "Startback::Audit::Runner::IdealOp",
44
- startback_version: Startback::VERSION,
45
- app_version: "1.0"
46
- }))
47
- expect(EXPORTER.errors).not_to receive(:increment)
48
- end
49
- it 'runs the operation' do
50
- expect(Runner.new.test).to eql(42)
51
- end
52
- end
53
-
54
- describe 'The exceptional case' do
55
- before do
56
- expect(EXPORTER.errors).to receive(:increment).with(
57
- hash_including(labels: {
58
- operation: "Startback::Audit::Runner::ExceptionalOp",
59
- startback_version: Startback::VERSION,
60
- app_version: "1.0"
61
- })
62
- )
63
- expect(EXPORTER.calls).not_to receive(:observe)
64
- end
65
- it 'let errors bubble up' do
66
- expect { Runner.new.test_exp }.to raise_error(/Oops/)
67
- end
68
- end
69
-
70
- end
71
- end
72
- end
@@ -1,105 +0,0 @@
1
- require 'spec_helper'
2
- require 'startback/audit'
3
- module Startback
4
- module Audit
5
- describe Trailer do
6
-
7
- let(:trailer) {
8
- Trailer.new("/tmp/trail.log")
9
- }
10
-
11
- describe "op_name" do
12
-
13
- def op_name(op, trailer = self.trailer)
14
- trailer.send(:op_name, op)
15
- end
16
-
17
- it 'uses op_name in priority if provided' do
18
- op = OpenStruct.new(op_name: "foo")
19
- expect(op_name(op)).to eql("foo")
20
- end
21
- end
22
-
23
- describe "op_data" do
24
-
25
- def op_data(op, trailer = self.trailer)
26
- trailer.send(:op_data, op)
27
- end
28
-
29
- it 'uses op_data in priority if provided' do
30
- op = OpenStruct.new(op_data: { foo: "bar" }, input: 12, request: 13)
31
- expect(op_data(op)).to eql({ foo: "bar" })
32
- end
33
-
34
- it 'uses to_trail then' do
35
- op = OpenStruct.new(to_trail: { foo: "bar" }, input: 12, request: 13)
36
- expect(op_data(op)).to eql({ foo: "bar" })
37
- end
38
-
39
- it 'uses input then' do
40
- op = OpenStruct.new(input: { foo: "bar" }, request: 13)
41
- expect(op_data(op)).to eql({ foo: "bar" })
42
- end
43
-
44
- it 'uses request then' do
45
- op = OpenStruct.new(request: { foo: "bar" })
46
- expect(op_data(op)).to eql({ foo: "bar" })
47
- end
48
-
49
- it 'applies default blacklists for security reasons' do
50
- op = OpenStruct.new(input: {
51
- token: "will not be dumped",
52
- a_token: "will not be dumped",
53
- AToken: "will not be dumped",
54
- password: "will not be dumped",
55
- secret: "will not be dumped",
56
- credentials: "will not be dumped",
57
- foo: "bar"
58
- })
59
- expect(op_data(op)).to eql({
60
- foo: "bar"
61
- })
62
- end
63
-
64
- it 'applies default blacklists to data arrays too' do
65
- op = OpenStruct.new(input: [{
66
- token: "will not be dumped",
67
- a_token: "will not be dumped",
68
- AToken: "will not be dumped",
69
- password: "will not be dumped",
70
- secret: "will not be dumped",
71
- credentials: "will not be dumped",
72
- foo: "bar"
73
- }])
74
- expect(op_data(op)).to eql([{
75
- foo: "bar"
76
- }])
77
- end
78
-
79
- it 'uses the stop words provided at construction' do
80
- t = Trailer.new("/tmp/trail.log", blacklist: "hello and world")
81
- op = OpenStruct.new(request: { Hello: "bar", World: "foo", foo: "bar" })
82
- expect(op_data(op, t)).to eql({ foo: "bar" })
83
- end
84
-
85
- end
86
-
87
- describe "op_context" do
88
-
89
- def op_context(op, trailer = self.trailer)
90
- trailer.send(:op_context, op)
91
- end
92
-
93
- it 'applies default blacklists for security reasons' do
94
- op = OpenStruct.new(context: {
95
- token: "will not be dumped",
96
- foo: "bar"
97
- })
98
- expect(op_context(op)).to eql({ foo: "bar" })
99
- end
100
-
101
- end
102
-
103
- end
104
- end
105
- end
@@ -1,136 +0,0 @@
1
- require 'spec_helper'
2
- require 'startback/caching/entity_cache'
3
- require 'startback/caching/store'
4
- module Startback
5
- module Caching
6
- describe EntityCache do
7
-
8
- class BaseCache < EntityCache
9
-
10
- def initialize(context = nil)
11
- super(Store.new, context)
12
- @called = 0
13
- @last_key = nil
14
- end
15
- attr_reader :called, :last_key
16
-
17
- protected
18
-
19
- def primary_key(ckey)
20
- case ckey
21
- when Integer then "a key"
22
- when String then ckey
23
- else
24
- raise "Invalid key `#{ckey}`"
25
- end
26
- end
27
-
28
- # We use the deprecated methods below to test
29
- # backward compatibility with 0.5.0.
30
-
31
- def full_key(key)
32
- { k: key }
33
- end
34
-
35
- def load_raw_data(key)
36
- @called += 1
37
- @last_key = key
38
- "a value"
39
- end
40
-
41
- end
42
-
43
- class ShortCache < BaseCache
44
- self.default_ttl = 1
45
- end
46
-
47
- class InvalidatingCache < BaseCache
48
-
49
- protected
50
-
51
- def valid?(key, value)
52
- false
53
- end
54
-
55
- end
56
-
57
- let(:cache) {
58
- BaseCache.new
59
- }
60
-
61
- describe "default_ttl" do
62
-
63
- it 'has a default ttl of one hour' do
64
- expect(BaseCache.default_ttl).to eql(3600)
65
- end
66
-
67
- it 'allows overriding it' do
68
- expect(ShortCache.default_ttl).to eql(1)
69
- end
70
-
71
- it 'is accessible as default_caching_options on the instance' do
72
- expect(cache.send(:default_caching_options)).to eql({ttl: 3600})
73
- end
74
-
75
- end
76
-
77
- describe "get" do
78
-
79
- subject{
80
- cache.get("a key")
81
- }
82
-
83
- it 'yields to load_raw_data only once with the short key' do
84
- expect(subject).to eql("a value")
85
- expect(subject).to eql("a value")
86
- expect(cache.called).to eql(1)
87
- expect(cache.last_key).to eql("a key")
88
- end
89
-
90
- end
91
-
92
- describe "primary_key" do
93
-
94
- subject{
95
- cache.get(12)
96
- }
97
-
98
- it 'allows using candidate keys' do
99
- expect(subject).to eql("a value")
100
- expect(subject).to eql("a value")
101
- expect(cache.called).to eql(1)
102
- expect(cache.last_key).to eql("a key")
103
- end
104
-
105
- end
106
-
107
- describe "invalidate" do
108
-
109
- it 'strips the key on the store, yielding a cache miss' do
110
- expect(cache.get("a key")).to eql("a value")
111
- cache.invalidate("a key")
112
- expect(cache.get("a key")).to eql("a value")
113
- expect(cache.called).to eql(2)
114
- expect(cache.last_key).to eql("a key")
115
- end
116
-
117
- end
118
-
119
- describe "valid? override" do
120
-
121
- let(:cache) {
122
- InvalidatingCache.new
123
- }
124
-
125
- it 'yields to load_raw_data only once with the extend key' do
126
- expect(cache.get("a key")).to eql("a value")
127
- expect(cache.get("a key")).to eql("a value")
128
- expect(cache.called).to eql(2)
129
- expect(cache.last_key).to eql("a key")
130
- end
131
-
132
- end
133
-
134
- end
135
- end
136
- end
@@ -1,64 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Startback
4
- describe Context, "factor" do
5
-
6
- let(:context) {
7
- Context.new
8
- }
9
-
10
- class ContextRelatedAbstraction
11
-
12
- def initialize(context)
13
- @context = context
14
- end
15
- attr_reader :context
16
-
17
- end
18
-
19
- class ContextRelatedAbstractionWithArgs
20
-
21
- def initialize(arg1, arg2, context)
22
- @arg1 = arg1
23
- @arg2 = arg2
24
- @context = context
25
- end
26
- attr_reader :arg1, :arg2, :context
27
-
28
- end
29
-
30
- it 'is a factory for other context-related abstractions' do
31
- got = context.factor(ContextRelatedAbstraction)
32
- expect(got).to be_a(ContextRelatedAbstraction)
33
- expect(got.context).to be(context)
34
-
35
- got2 = context.factor(ContextRelatedAbstraction)
36
- expect(got2).to be(got)
37
- end
38
-
39
- it 'is takes cares of abstraction arguments' do
40
- got = context.factor(ContextRelatedAbstractionWithArgs, 12, 14)
41
- expect(got).to be_a(ContextRelatedAbstractionWithArgs)
42
- expect(got.context).to be(context)
43
- expect(got.arg1).to eql(12)
44
- expect(got.arg2).to eql(14)
45
- end
46
-
47
- it 'is caches even in presence ofabstraction arguments' do
48
- got = context.factor(ContextRelatedAbstractionWithArgs, 12, 14)
49
- expect(got).to be_a(ContextRelatedAbstractionWithArgs)
50
-
51
- got2 = context.factor(ContextRelatedAbstractionWithArgs, 12, 14)
52
- expect(got2).to be(got)
53
- end
54
-
55
- it 'is distinguishes different abstraction arguments' do
56
- got = context.factor(ContextRelatedAbstractionWithArgs, 12, 14)
57
- expect(got).to be_a(ContextRelatedAbstractionWithArgs)
58
-
59
- got2 = context.factor(ContextRelatedAbstractionWithArgs, 17, 14)
60
- expect(got2).not_to be(got)
61
- end
62
-
63
- end
64
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Startback
4
- describe Context, "dup" do
5
-
6
- let(:context) {
7
- SubContext.new.tap{|s| s.foo = "bar" }
8
- }
9
-
10
- class ContextRelatedAbstraction
11
-
12
- def initialize(context)
13
- @context = context
14
- end
15
- attr_reader :context
16
-
17
- end
18
-
19
- it 'yields a dup of the original context' do
20
- seen = false
21
- got = context.dup{|x|
22
- seen = x
23
- expect(x).not_to be(context)
24
- }
25
- expect(seen).to be(got)
26
- expect(got).to be_a(SubContext)
27
- expect(got).not_to be(context)
28
- expect(got.foo).to eql("bar")
29
- end
30
-
31
- it 'cleans all factored cache' do
32
- cra = context.factor(ContextRelatedAbstraction)
33
- expect(cra).to be_a(ContextRelatedAbstraction)
34
- cra2 = context.factor(ContextRelatedAbstraction)
35
- expect(cra2).to be(cra)
36
- cra3 = context.dup.factor(ContextRelatedAbstraction)
37
- expect(cra3).not_to be(cra)
38
- expect(cra3).not_to be(cra2)
39
- end
40
-
41
- end
42
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Startback
4
- describe Context, "fork" do
5
-
6
- it 'is a simple dup without args' do
7
- context = SubContext.new
8
- context.foo = ['hello']
9
-
10
- forked = context.fork
11
- expect(forked).not_to be(context)
12
- expect(forked.foo).to eql(['hello'])
13
- expect(forked.foo).to be(context.foo)
14
- end
15
-
16
- it 'yields the context if a block is provided' do
17
- context = SubContext.new
18
-
19
- seen = false
20
- context.fork({ 'foo' => 'hello' }) do |forked|
21
- expect(forked).not_to be(context)
22
- expect(forked.foo).to eql('hello')
23
- seen = true
24
- end
25
- expect(seen).to eql(true)
26
- end
27
-
28
- it 'uses the factory on the hash provided' do
29
- context = SubContext.new
30
-
31
- forked = context.fork({ 'foo' => 'hello' })
32
- expect(forked).not_to be(context)
33
- expect(forked.foo).to eql('hello')
34
- end
35
-
36
- end
37
- end