startback 0.12.2 → 0.14.0

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
  SHA256:
3
- metadata.gz: 7f4770d1267ad944224e11f6c10ddaae3f2c3666860ef31c05ea3323282dda34
4
- data.tar.gz: ec1a61367ab0947be2088dae981c6956359a26bc2517282a464e44e6449331b4
3
+ metadata.gz: 3d5d880b8e9dfdeecdd68e78400468a2765dffbcf39866860daef9ac86a8096d
4
+ data.tar.gz: 6bf01ece248ca741ed4a590ab5458c8f94bda465c315951cfb0797fa49ae4fe9
5
5
  SHA512:
6
- metadata.gz: 19813029ac9f81b1aed96f69a8e6ddd45e509d87e5b3bd05859f0b9155c16c5a05035cf2a28ff7df2df28f467a368702fa83180c24a62caf498337c3dde6d7da
7
- data.tar.gz: 57abc7390c595f5c024276ed07ccb3580312d2de76a6a622e0a3284afefb38244b000b26e9f005d4516de67f3afccdc4789988466ffbb220f106cce3514f83b4
6
+ metadata.gz: 7f21d629f5733aea63bdfd21199aae51208d16751e398a373cef0a72cf4fcbceb083046c7f1ec61f9ed4791c2e4621a787229f438622a35a28a9ca2591ec5f90
7
+ data.tar.gz: c77c9f93fc437a8c803782d226bd6f9c30497f1eb238a6244526262fd5c24e148b322d01d46ed8bd81d907b9851a9789e1774abaec5dccd63fefc8a0da50eeb1
@@ -0,0 +1,43 @@
1
+ module Startback
2
+ class Context
3
+ module HFactory
4
+
5
+ def h(hash)
6
+ h_factor!(self.new, hash)
7
+ end
8
+
9
+ def h_factor!(context, hash)
10
+ h_factories.each do |f|
11
+ f.call(context, hash)
12
+ end
13
+ context
14
+ end
15
+
16
+ def h_factories
17
+ @h_factories ||= []
18
+ end
19
+
20
+ def h_factory(&factory)
21
+ h_factories << factory
22
+ end
23
+
24
+ ###
25
+
26
+ def h_dump!(context, hash = {})
27
+ h_dumpers.each do |d|
28
+ context.instance_exec(hash, &d)
29
+ end
30
+ hash
31
+ end
32
+
33
+ def h_dumpers
34
+ @h_dumpers ||= []
35
+ end
36
+
37
+ def h_dump(&dumper)
38
+ h_dumpers << dumper
39
+ end
40
+
41
+ end # module HFactory
42
+ end # class Context
43
+ end # module Startback
@@ -1,7 +1,8 @@
1
1
  module Startback
2
2
  #
3
3
  # Defines an execution context for Startback applications, and provides
4
- # a cached factory for related abstractions (see `factor`).
4
+ # a cached factory for related abstractions (see `factor`), and an
5
+ # extensible world, statically and dynamically.
5
6
  #
6
7
  # In web application, an instance of a context can be set on the Rack
7
8
  # environment, using Context::Middleware.
@@ -48,46 +49,36 @@ module Startback
48
49
  # convert them to wathever log format is necessary.
49
50
  attr_accessor :logger
50
51
 
51
- # Implementation of the `h` information contract
52
- class << self
52
+ require_relative 'context/h_factory'
53
+ extend(Context::HFactory)
53
54
 
54
- def h(hash)
55
- h_factor!(self.new, hash)
56
- end
57
-
58
- def h_factor!(context, hash)
59
- h_factories.each do |f|
60
- f.call(context, hash)
61
- end
62
- context
63
- end
64
-
65
- def h_factories
66
- @h_factories ||= []
67
- end
55
+ def initialize
56
+ super
57
+ yield(self) if block_given?
58
+ end
68
59
 
69
- def h_factory(&factory)
70
- h_factories << factory
71
- end
60
+ attr_writer :_world
61
+ protected :_world=
72
62
 
73
- ###
63
+ def self.world(who, &block)
64
+ @_world ||= Support::World.new
65
+ @_world = @_world.factory(who, &block)
66
+ end
74
67
 
75
- def h_dump!(context, hash = {})
76
- h_dumpers.each do |d|
77
- context.instance_exec(hash, &d)
78
- end
79
- hash
80
- end
68
+ def self.factor_world(context)
69
+ @_world ||= Support::World.new
70
+ @_world.with_scope(context)
71
+ end
81
72
 
82
- def h_dumpers
83
- @h_dumpers ||= []
84
- end
73
+ def world
74
+ @_world ||= self.class.factor_world(self)
75
+ end
85
76
 
86
- def h_dump(&dumper)
87
- h_dumpers << dumper
77
+ def with_world(world)
78
+ dup do |ctx|
79
+ ctx._world = self.world.with(world)
88
80
  end
89
-
90
- end # class << self
81
+ end
91
82
 
92
83
  # Factors an instance of `clazz`, which must be a Context-related
93
84
  # abstraction (i.e. its constructor takes the context as last parameters).
@@ -76,7 +76,7 @@ module Startback
76
76
  end
77
77
 
78
78
  def operation_world(op)
79
- super(op).merge(context: ctx)
79
+ super(op).merge(context: context)
80
80
  end
81
81
 
82
82
  end # class Agent
@@ -1,18 +1,14 @@
1
1
  require 'rack'
2
- require 'webrick'
3
2
  require 'startback'
4
3
  module Startback
5
4
  class Event
6
5
  #
7
6
  # This class is the starting point of event handling in
8
7
  # Startback. It holds a Bus instance to which emitters
9
- # and listeners can connect, and the possibility for the
10
- # the listening part to start an infinite loop (ServerEngine).
8
+ # and listeners can connect.
11
9
  #
12
- # The Engine automatically runs a Webrick small webapp
13
- # with a /healthcheck webservice. The class can be extended
14
- # and method `on_health_check` overriden to run specific
15
- # checks.
10
+ # The Engine exposes a rack app (.rack_app) with a /healthcheck webservice.
11
+ # It is supposed to be mounted to a webserver such as puma.
16
12
  #
17
13
  # This class goes hand in hand with the `startback:engine`
18
14
  # docker image. It can be extended by subclasses to override
@@ -22,15 +18,13 @@ module Startback
22
18
  # - on_health_check to check specific health conditions
23
19
  # - create_agents to instantiate all listening agents
24
20
  # (unless auto_create_agents is used)
21
+ # - rack_app if you want to customize the API running
25
22
  #
26
23
  class Engine
27
24
  include Support::Robustness
28
25
 
29
26
  DEFAULT_OPTIONS = {
30
27
 
31
- # To be passed to ServerEngine
32
- server_engine: {}
33
-
34
28
  }
35
29
 
36
30
  def initialize(options = {}, context = Context.new)
@@ -60,7 +54,7 @@ module Startback
60
54
  end
61
55
 
62
56
  def bus
63
- ::Startback::Event::Bus.new
57
+ @bus ||= ::Startback::Event::Bus.new
64
58
  end
65
59
 
66
60
  def connect
@@ -68,20 +62,12 @@ module Startback
68
62
  bus.connect
69
63
  end
70
64
 
71
- def run(options = {})
72
- connect
73
-
74
- log(:info, self, "Running agents and server engine!")
75
- create_agents
76
- Runner.new(self, options[:server_engine] || {}).run
77
- end
78
-
79
65
  def create_agents
80
66
  return unless parent = self.class.auto_create_agents
81
67
 
82
68
  ObjectSpace
83
69
  .each_object(Class)
84
- .select { |klass| klass < parent }
70
+ .select { |klass| klass <= parent }
85
71
  .each { |klass| klass.new(self) }
86
72
  end
87
73
 
@@ -89,88 +75,20 @@ module Startback
89
75
  Event.json(event_data, context)
90
76
  end
91
77
 
92
- class Runner
93
-
94
- DEFAULT_SERVER_ENGINE_OPTIONS = {
95
- daemonize: false,
96
- worker_type: 'process',
97
- workers: 1
98
- }
99
-
100
- def initialize(engine, options = {})
101
- raise ArgumentError if engine.nil?
102
-
103
- @engine = engine
104
- @options = DEFAULT_SERVER_ENGINE_OPTIONS.merge(options)
105
- require 'serverengine'
106
- end
107
- attr_reader :engine, :options
108
-
109
- def run(options = {})
110
- health = self.class.build_health_check(engine)
111
- worker = self.class.build_worker(engine, health)
112
- se = ServerEngine.create(nil, worker, options)
113
- se.run
114
- se
115
- end
116
-
117
- class << self
118
- def run(*args, &bl)
119
- new.run(*args, &bl)
120
- end
78
+ def rack_app
79
+ engine = self
80
+ Rack::Builder.new do
81
+ use Startback::Web::CatchAll
121
82
 
122
- def build_health_check(engine)
123
- Rack::Builder.new do
124
- map '/health-check' do
125
- health = Startback::Web::HealthCheck.new {
126
- engine.on_health_check
127
- }
128
- run(health)
129
- end
130
- end
83
+ map '/health-check' do
84
+ health = Startback::Web::HealthCheck.new {
85
+ engine.on_health_check
86
+ }
87
+ run(health)
131
88
  end
89
+ end
90
+ end
132
91
 
133
- def build_worker(engine, health)
134
- Module.new do
135
- include Support::Env
136
-
137
- def initialize
138
- @stop_flag = ServerEngine::BlockingFlag.new
139
- end
140
-
141
- define_method(:health) do
142
- health
143
- end
144
-
145
- define_method(:engine) do
146
- engine
147
- end
148
-
149
- def run
150
- ran = false
151
- until @stop_flag.set?
152
- if ran
153
- engine.send(:log, :warn, engine, "Restarting internal loop")
154
- else
155
- engine.send(:log, :info, engine, "Starting internal loop")
156
- end
157
- Rack::Handler::WEBrick.run(health, {
158
- :Port => env('STARTBACK_ENGINE_PORT', '3000').to_i,
159
- :Host => env('STARTBACK_ENGINE_LISTEN', '0.0.0.0')
160
- })
161
- ran = true
162
- end
163
- end
164
-
165
- def stop
166
- engine.send(:log, :info, engine, "Stopping internal loop")
167
- @stop_flag.set!
168
- Rack::Handler::WEBrick.shutdown
169
- end
170
- end
171
- end
172
- end # class << self
173
- end # class Runner
174
92
  end # class Engine
175
93
  end # class Event
176
94
  end # module Startback
@@ -21,6 +21,8 @@ module Startback
21
21
  attr_reader :context, :type, :data
22
22
 
23
23
  def self.json(src, context)
24
+ return src if src.is_a?(Event)
25
+
24
26
  parsed = JSON.parse(src)
25
27
  klass = Kernel.const_get(parsed['type'])
26
28
  context = context.fork(parsed['context']) if context
@@ -0,0 +1,6 @@
1
+ module Startback
2
+ class Model
3
+ include Support::DataObject
4
+
5
+ end # class Model
6
+ end # module Startback
@@ -37,6 +37,11 @@ module Startback
37
37
  attr_accessor :world
38
38
  protected :world=
39
39
 
40
+ def initialize(input = {})
41
+ @input = input
42
+ end
43
+ attr_reader :input
44
+
40
45
  def bind(world)
41
46
  return self unless world
42
47
  self.world = world
@@ -0,0 +1,11 @@
1
+ module Startback
2
+ class Services
3
+ include Startback::Errors
4
+
5
+ def initialize(context)
6
+ @context = context
7
+ end
8
+ attr_reader :context
9
+
10
+ end # class Services
11
+ end # module Startback
@@ -0,0 +1,71 @@
1
+ module Startback
2
+ module Support
3
+ module DataObject
4
+
5
+ def initialize(data = {})
6
+ @_data = data.dup.freeze
7
+ end
8
+
9
+ attr_writer :_data
10
+ protected :_data=
11
+
12
+ def method_missing(name, *args, &bl)
13
+ return super unless args.empty? && bl.nil?
14
+ return super unless pair = _data_key_for(name)
15
+
16
+ pair.last ? !!@_data[pair.first] : @_data[pair.first]
17
+ end
18
+
19
+ def [](name)
20
+ return nil unless pair = _data_key_for(name, false, false)
21
+
22
+ @_data[pair.first]
23
+ end
24
+
25
+ def respond_to?(name)
26
+ super || !_data_key_for(name).nil?
27
+ end
28
+
29
+ def to_data
30
+ @_data
31
+ end
32
+ alias :to_h :to_data
33
+
34
+ def to_json(*args, &bl)
35
+ to_data.to_json(*args, &bl)
36
+ end
37
+
38
+ private
39
+
40
+ def _data_key_for(key, try_camelize = _data_allow_camelize, try_query = _data_allow_query)
41
+ if @_data.key?(key)
42
+ [key, false]
43
+ elsif @_data.key?(key.to_s)
44
+ [key.to_s, false]
45
+ elsif key.is_a?(String) && @_data.key?(key.to_sym)
46
+ [key.to_sym, false]
47
+ elsif try_camelize
48
+ cam = key.to_s.gsub(/_([a-z])/){ $1.upcase }.to_sym
49
+ _data_key_for(cam, false, true)
50
+ elsif try_query && key.to_s =~ /\?$/
51
+ got = _data_key_for(key[0...-1].to_sym, false, false)
52
+ got ? [got.first, true] : _data_key_not_found(key)
53
+ else
54
+ _data_key_not_found(key)
55
+ end
56
+ end
57
+
58
+ def _data_allow_camelize
59
+ true
60
+ end
61
+
62
+ def _data_allow_query
63
+ true
64
+ end
65
+
66
+ def _data_key_not_found(key)
67
+ nil
68
+ end
69
+ end # module DataObject
70
+ end # module Support
71
+ end # module Startback
@@ -0,0 +1,54 @@
1
+ module Startback
2
+ module Support
3
+ class World
4
+ include DataObject
5
+
6
+ attr_accessor :_factory
7
+ protected :_factory=
8
+
9
+ def factory(who, &block)
10
+ dup.tap do |x|
11
+ x._factory = (self._factory || {}).merge(who => block)
12
+ end
13
+ end
14
+
15
+ attr_accessor :_scope
16
+ protected :_scope=
17
+
18
+ def with_scope(scope)
19
+ dup.tap do |x|
20
+ x._scope = scope
21
+ end
22
+ end
23
+
24
+ def with(hash)
25
+ dup.tap do |x|
26
+ x._data = to_data.merge(hash)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def _data_allow_camelize
33
+ false
34
+ end
35
+
36
+ def _data_allow_query
37
+ false
38
+ end
39
+
40
+ def _data_key_not_found(key)
41
+ raise Startback::Error, "Scope must be defined" unless s = _scope
42
+
43
+ block = (_factory || {})[key]
44
+ if block
45
+ factored = s.instance_exec(&block)
46
+ @_data = @_data.dup.merge(key => factored).freeze
47
+ [key, false]
48
+ else
49
+ nil
50
+ end
51
+ end
52
+ end # class World
53
+ end # module Support
54
+ end # module Startback
@@ -22,3 +22,5 @@ require_relative 'support/hooks'
22
22
  require_relative 'support/operation_runner'
23
23
  require_relative 'support/transaction_policy'
24
24
  require_relative 'support/transaction_manager'
25
+ require_relative 'support/data_object'
26
+ require_relative 'support/world'
@@ -1,8 +1,8 @@
1
1
  module Startback
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 12
5
- TINY = 2
4
+ MINOR = 14
5
+ TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
data/lib/startback.rb CHANGED
@@ -32,8 +32,10 @@ module Startback
32
32
  require_relative 'startback/ext'
33
33
  require_relative 'startback/errors'
34
34
  require_relative 'startback/support'
35
+ require_relative 'startback/model'
35
36
  require_relative 'startback/context'
36
37
  require_relative 'startback/operation'
38
+ require_relative 'startback/services'
37
39
 
38
40
  # Logger instance to use for the application
39
41
  LOGGER = ::Startback::Support::Logger.new
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,8 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
1
  require 'startback'
3
2
  require 'startback/event'
4
3
  require 'startback/support/fake_logger'
5
4
  require 'rack/test'
5
+ require 'ostruct'
6
6
 
7
7
  module SpecHelpers
8
8
  end
@@ -12,23 +12,35 @@ RSpec.configure do |c|
12
12
  end
13
13
 
14
14
  class SubContext < Startback::Context
15
+
15
16
  attr_accessor :foo
17
+
16
18
  h_factory do |c,h|
17
19
  c.foo = h["foo"]
18
20
  end
21
+
19
22
  h_dump do |h|
20
23
  h.merge!("foo" => foo)
21
24
  end
25
+
26
+ world(:partner) do
27
+ Object.new
28
+ end
29
+
22
30
  end
23
31
 
24
32
  class SubContext
33
+
25
34
  attr_accessor :bar
35
+
26
36
  h_factory do |c,h|
27
37
  c.bar = h["bar"]
28
38
  end
39
+
29
40
  h_dump do |h|
30
41
  h.merge!("bar" => bar)
31
42
  end
43
+
32
44
  end
33
45
 
34
46
  class User
@@ -8,8 +8,7 @@ module Startback
8
8
  context.foo = ['hello']
9
9
 
10
10
  forked = context.fork
11
- puts "Forked: #{forked.inspect}"
12
- expect(fork).not_to be(context)
11
+ expect(forked).not_to be(context)
13
12
  expect(forked.foo).to eql(['hello'])
14
13
  expect(forked.foo).to be(context.foo)
15
14
  end
@@ -19,7 +18,7 @@ module Startback
19
18
 
20
19
  seen = false
21
20
  context.fork({ 'foo' => 'hello' }) do |forked|
22
- expect(fork).not_to be(context)
21
+ expect(forked).not_to be(context)
23
22
  expect(forked.foo).to eql('hello')
24
23
  seen = true
25
24
  end
@@ -30,7 +29,7 @@ module Startback
30
29
  context = SubContext.new
31
30
 
32
31
  forked = context.fork({ 'foo' => 'hello' })
33
- expect(fork).not_to be(context)
32
+ expect(forked).not_to be(context)
34
33
  expect(forked.foo).to eql('hello')
35
34
  end
36
35
 
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ describe Context, "with_world" do
5
+
6
+ let(:who) do
7
+ Object.new
8
+ end
9
+
10
+ let(:context) do
11
+ SubContext.new.with_world(hello: who)
12
+ end
13
+
14
+ it 'works as expected' do
15
+ got = context.world.hello
16
+ expect(got).to be(who)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ describe Context, "world" do
5
+
6
+ let(:context) do
7
+ SubContext.new
8
+ end
9
+
10
+ it 'works as expected' do
11
+ got = context.world.partner
12
+ expect(got).not_to be_nil
13
+ expect(context.world.partner).to be(got)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ module Support
5
+ describe DataObject do
6
+
7
+ class FooDataObject
8
+ include DataObject
9
+ end
10
+
11
+ let(:data) do
12
+ {
13
+ :foo => 'bar',
14
+ 'bar' => 'baz'
15
+ }
16
+ end
17
+
18
+ subject do
19
+ FooDataObject.new(data)
20
+ end
21
+
22
+ it 'lets create an instance with providing data' do
23
+ expect(subject).to be_a(FooDataObject)
24
+ end
25
+
26
+ it 'lets get the data back' do
27
+ expect(subject.to_data).to eql(data)
28
+ expect(subject.to_data).not_to be(data)
29
+ end
30
+
31
+ it 'lets to_json it' do
32
+ expect(subject.to_json).to eql(%Q{{"foo":"bar","bar":"baz"}})
33
+ end
34
+
35
+ describe "data helpers" do
36
+ it 'lets access data through methods' do
37
+ expect(subject.foo).to eql('bar')
38
+ end
39
+
40
+ it 'is indifferent to symbol vs. string' do
41
+ expect(subject.bar).to eql('baz')
42
+ end
43
+
44
+ it 'is indifferent to camel casing' do
45
+ expect(subject.bar).to eql('baz')
46
+ end
47
+
48
+ it 'raises a NoMethodError when not known' do
49
+ expect {
50
+ subject.no_such_one
51
+ }.to raise_error(NoMethodError)
52
+ end
53
+
54
+ it 'implements respond_to? correctly' do
55
+ expect(subject.respond_to?(:foo)).to eql(true)
56
+ expect(subject.respond_to?(:bar)).to eql(true)
57
+ expect(subject.respond_to?(:no_such_one)).to eql(false)
58
+ end
59
+ end # data helpers
60
+
61
+ describe "? helpers" do
62
+ let(:data) do
63
+ {
64
+ 'some' => 'thing',
65
+ 'ready' => false,
66
+ 'unready' => true,
67
+ 'nothing' => nil
68
+ }
69
+ end
70
+
71
+ it 'works as expected' do
72
+ expect(subject.some?).to eql(true)
73
+ expect(subject.ready?).to eql(false)
74
+ expect(subject.unready?).to eql(true)
75
+ expect(subject.nothing?).to eql(false)
76
+ end
77
+
78
+ it 'implements respond_to? correctly' do
79
+ expect(subject.respond_to?(:some?)).to eql(true)
80
+ expect(subject.respond_to?(:ready?)).to eql(true)
81
+ expect(subject.respond_to?(:unready?)).to eql(true)
82
+ expect(subject.respond_to?(:nothing?)).to eql(true)
83
+ end
84
+
85
+ it 'stays conservative' do
86
+ expect {
87
+ subject.no_such_one?
88
+ }.to raise_error(NoMethodError)
89
+ expect(subject.respond_to?(:no_such_one?)).to eql(false)
90
+ end
91
+ end
92
+
93
+ describe "case helpers" do
94
+ let(:data) do
95
+ {
96
+ 'camelCase' => 'snake_case'
97
+ }
98
+ end
99
+
100
+ it 'lets use camelCase' do
101
+ expect(subject.camelCase).to eql('snake_case')
102
+ end
103
+
104
+ it 'lets use camel_case' do
105
+ expect(subject.camel_case).to eql('snake_case')
106
+ end
107
+
108
+ it 'implements respond_to? correctly' do
109
+ expect(subject.respond_to?(:camelCase)).to eql(true)
110
+ expect(subject.respond_to?(:camel_case)).to eql(true)
111
+ end
112
+
113
+ it 'is compatible with ? helpers' do
114
+ expect(subject.camelCase?).to eql(true)
115
+ expect(subject.camel_case?).to eql(true)
116
+ end
117
+
118
+ it 'stays conservative' do
119
+ expect {
120
+ subject.no_such_one
121
+ }.to raise_error(NoMethodError)
122
+ expect(subject.respond_to?(:no_such_one)).to eql(false)
123
+ expect(subject.respond_to?(:no_such_one?)).to eql(false)
124
+ end
125
+ end
126
+
127
+ describe '[]' do
128
+ let(:data) do
129
+ {
130
+ :foo => 'bar',
131
+ 'bar' => 'baz',
132
+ 'camelCase' => 'snake_case'
133
+ }
134
+ end
135
+
136
+ it 'lets access data' do
137
+ expect(subject[:foo]).to eql('bar')
138
+ expect(subject['bar']).to eql('baz')
139
+ expect(subject['camelCase']).to eql('snake_case')
140
+ end
141
+
142
+ it 'uses indifferent access' do
143
+ expect(subject['foo']).to eql('bar')
144
+ expect(subject[:bar]).to eql('baz')
145
+ expect(subject[:camelCase]).to eql('snake_case')
146
+ end
147
+
148
+ it 'has no other magic and returns nil in all other cases' do
149
+ expect(subject[:foo?]).to be_nil
150
+ expect(subject[:camel_case]).to be_nil
151
+ expect(subject[:camel_case?]).to be_nil
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ module Support
5
+ describe World do
6
+
7
+ let(:world) do
8
+ World.new
9
+ end
10
+
11
+ describe 'with' do
12
+ subject do
13
+ world.with(foo: :bar, bar: :baz)
14
+ end
15
+
16
+ it 'returns a new world instance' do
17
+ expect(subject).to be_a(World)
18
+ expect(subject).not_to be(world)
19
+ end
20
+
21
+ it 'gives access to those variables' do
22
+ expect(subject.foo).to eql(:bar)
23
+ expect(subject[:bar]).to eql(:baz)
24
+ end
25
+ end
26
+
27
+ describe 'dup' do
28
+ let(:world) do
29
+ World.new(foo: :bar)
30
+ end
31
+
32
+ subject do
33
+ world.dup
34
+ end
35
+
36
+ it 'returns another instance' do
37
+ expect(subject).to be_a(World)
38
+ expect(subject).not_to be(world)
39
+ end
40
+
41
+ it 'keeps variables' do
42
+ expect(subject.foo).to eql(:bar)
43
+ end
44
+ end
45
+
46
+ describe 'class factory' do
47
+ subject do
48
+ world.factory(:foo) do
49
+ hello
50
+ end
51
+ end
52
+
53
+ def hello
54
+ OpenStruct.new(bar: 12)
55
+ end
56
+
57
+ it 'returns a world instance' do
58
+ expect(subject).to be_a(World)
59
+ expect(subject).not_to be(world)
60
+ end
61
+
62
+ it 'installs the factory' do
63
+ bound = subject.with_scope(self)
64
+ got = bound.foo
65
+ expect(got).to be_a(OpenStruct)
66
+ expect(got.bar).to eql(12)
67
+ expect(bound.foo).to be(got)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
data/tasks/test.rake CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rspec/core/rake_task'
2
+ require 'path'
2
3
 
3
4
  namespace :test do
4
5
 
@@ -8,14 +9,6 @@ namespace :test do
8
9
  t.rspec_opts = %{-Ilib -Ispec --color --backtrace --format progress --format RspecJunitFormatter --out spec/rspec-unit.xml}
9
10
  end
10
11
 
11
- desc "Run the tests in the examples folder"
12
- task :example do
13
- Bundler.with_original_env do
14
- system("cd example && bundle exec rake")
15
- abort("Example tests failed") unless $?.exitstatus == 0
16
- end
17
- end
18
-
19
- task :all => [:unit, :example]
12
+ task :all => [:unit]
20
13
  end
21
14
  task :test => :'test:all'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: startback
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-20 00:00:00.000000000 Z
11
+ date: 2022-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -270,20 +270,20 @@ dependencies:
270
270
  requirements:
271
271
  - - ">="
272
272
  - !ruby/object:Gem::Version
273
- version: 0.19.0
273
+ version: 0.20.0
274
274
  - - "<"
275
275
  - !ruby/object:Gem::Version
276
- version: 0.20.0
276
+ version: 0.21.0
277
277
  type: :runtime
278
278
  prerelease: false
279
279
  version_requirements: !ruby/object:Gem::Requirement
280
280
  requirements:
281
281
  - - ">="
282
282
  - !ruby/object:Gem::Version
283
- version: 0.19.0
283
+ version: 0.20.0
284
284
  - - "<"
285
285
  - !ruby/object:Gem::Version
286
- version: 0.20.0
286
+ version: 0.21.0
287
287
  - !ruby/object:Gem::Dependency
288
288
  name: tzinfo
289
289
  requirement: !ruby/object:Gem::Requirement
@@ -389,6 +389,7 @@ files:
389
389
  - lib/startback/caching/no_store.rb
390
390
  - lib/startback/caching/store.rb
391
391
  - lib/startback/context.rb
392
+ - lib/startback/context/h_factory.rb
392
393
  - lib/startback/context/middleware.rb
393
394
  - lib/startback/errors.rb
394
395
  - lib/startback/event.rb
@@ -405,10 +406,13 @@ files:
405
406
  - lib/startback/ext.rb
406
407
  - lib/startback/ext/date_time.rb
407
408
  - lib/startback/ext/time.rb
409
+ - lib/startback/model.rb
408
410
  - lib/startback/operation.rb
409
411
  - lib/startback/operation/error_operation.rb
410
412
  - lib/startback/operation/multi_operation.rb
413
+ - lib/startback/services.rb
411
414
  - lib/startback/support.rb
415
+ - lib/startback/support/data_object.rb
412
416
  - lib/startback/support/env.rb
413
417
  - lib/startback/support/fake_logger.rb
414
418
  - lib/startback/support/hooks.rb
@@ -418,6 +422,7 @@ files:
418
422
  - lib/startback/support/robustness.rb
419
423
  - lib/startback/support/transaction_manager.rb
420
424
  - lib/startback/support/transaction_policy.rb
425
+ - lib/startback/support/world.rb
421
426
  - lib/startback/version.rb
422
427
  - lib/startback/web/api.rb
423
428
  - lib/startback/web/auto_caching.rb
@@ -439,15 +444,19 @@ files:
439
444
  - spec/unit/context/test_fork.rb
440
445
  - spec/unit/context/test_h_factory.rb
441
446
  - spec/unit/context/test_middleware.rb
447
+ - spec/unit/context/test_with_world.rb
448
+ - spec/unit/context/test_world.rb
442
449
  - spec/unit/event/bus/memory/test_async.rb
443
450
  - spec/unit/event/bus/memory/test_sync.rb
444
451
  - spec/unit/support/hooks/test_after_hook.rb
445
452
  - spec/unit/support/hooks/test_before_hook.rb
446
453
  - spec/unit/support/operation_runner/test_around_run.rb
447
454
  - spec/unit/support/operation_runner/test_before_after_call.rb
455
+ - spec/unit/support/test_data_object.rb
448
456
  - spec/unit/support/test_env.rb
449
457
  - spec/unit/support/test_robusteness.rb
450
458
  - spec/unit/support/test_transaction_manager.rb
459
+ - spec/unit/support/test_world.rb
451
460
  - spec/unit/test_event.rb
452
461
  - spec/unit/test_operation.rb
453
462
  - spec/unit/test_support.rb
@@ -461,7 +470,7 @@ files:
461
470
  - spec/unit/web/test_healthcheck.rb
462
471
  - spec/unit/web/test_magic_assets.rb
463
472
  - tasks/test.rake
464
- homepage: http://www.enspirit.be
473
+ homepage: https://www.enspirit.be
465
474
  licenses:
466
475
  - MIT
467
476
  metadata: {}
@@ -480,7 +489,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
480
489
  - !ruby/object:Gem::Version
481
490
  version: '0'
482
491
  requirements: []
483
- rubygems_version: 3.3.7
492
+ rubygems_version: 3.1.2
484
493
  signing_key:
485
494
  specification_version: 4
486
495
  summary: Got Your Ruby Back