startback-websocket 0.14.0 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
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