pakyow-test 0.10.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 +7 -0
- data/pakyow-test/CHANGELOG.md +3 -0
- data/pakyow-test/LICENSE +20 -0
- data/pakyow-test/README.md +107 -0
- data/pakyow-test/lib/pakyow-test.rb +60 -0
- data/pakyow-test/lib/test_help/ext/request.rb +7 -0
- data/pakyow-test/lib/test_help/ext/response.rb +7 -0
- data/pakyow-test/lib/test_help/helpers.rb +28 -0
- data/pakyow-test/lib/test_help/mocks/presenter_mock.rb +18 -0
- data/pakyow-test/lib/test_help/mocks/status_mock.rb +23 -0
- data/pakyow-test/lib/test_help/observable.rb +74 -0
- data/pakyow-test/lib/test_help/observables/observable_logger.rb +19 -0
- data/pakyow-test/lib/test_help/observables/observable_presenter.rb +18 -0
- data/pakyow-test/lib/test_help/observables/observable_view.rb +135 -0
- data/pakyow-test/lib/test_help/observables/realtime/observable_context.rb +34 -0
- data/pakyow-test/lib/test_help/observables/realtime/observable_mutator.rb +77 -0
- data/pakyow-test/lib/test_help/simulation.rb +76 -0
- data/pakyow-test/lib/test_help/simulator.rb +42 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8e2027b0d6da447de9a63faeeb461e8075e2e98b
|
4
|
+
data.tar.gz: de9d7f71abc4ce8cd6d105c97876631dc7f3e52e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 18d6a68f1cf1f097e5278a4b6bc73ccee10cffb39f4e7770db9740833ed01397f61f5ba2ac072324da4491ef0f78a43690936016edd7a9f9b2336f396472482e
|
7
|
+
data.tar.gz: 5f8855ebb2936687620f87d4fa5825ab3d37a70d6adb60ebb300e8fc9fe8453c1424a942b335a9ed8efdca8bf965c9c69eb1f4aa3e2a341afed9a87dd754bf0b
|
data/pakyow-test/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 Bryan Powell
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# pakyow-test
|
2
|
+
|
3
|
+
Helpers for testing in Pakyow.
|
4
|
+
|
5
|
+
## Getting Started w/ TestUnit and/or Minitest
|
6
|
+
|
7
|
+
Create a `test` folder in the root app folder. In it, create a file named
|
8
|
+
`test_helper.rb` with the following code:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
require 'pakyow-test'
|
12
|
+
Pakyow::TestHelp.setup
|
13
|
+
```
|
14
|
+
|
15
|
+
Follow the rest of the instructions to gain access to helper methods.
|
16
|
+
|
17
|
+
### Test::Unit
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
include Pakyow::TestHelp::Helpers
|
21
|
+
end
|
22
|
+
|
23
|
+
### Minitest
|
24
|
+
|
25
|
+
class MiniTest::Unit::TestCase
|
26
|
+
include Pakyow::TestHelp::Helpers
|
27
|
+
end
|
28
|
+
|
29
|
+
### MiniTest::Spec
|
30
|
+
|
31
|
+
class MiniTest::Spec
|
32
|
+
include Pakyow::TestHelp::Helpers
|
33
|
+
end
|
34
|
+
|
35
|
+
---
|
36
|
+
|
37
|
+
Next, open up your `Rakefile` and define the following:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
require 'rake/testtask'
|
41
|
+
|
42
|
+
desc "Run the pakyow test suite"
|
43
|
+
Rake::TestTask.new("test") do |t|
|
44
|
+
t.libs << 'test'
|
45
|
+
t.pattern = 'test/**/*_test.rb'
|
46
|
+
t.verbose = false
|
47
|
+
t.warning = false
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
Now create files within the `test` directory that follow the `*_test.rb` naming
|
52
|
+
convention and use `rake test` to run the test suite.
|
53
|
+
|
54
|
+
## Getting Started w/ Rspec
|
55
|
+
|
56
|
+
Create a `spec` folder in the root app folder. In it, create a file named
|
57
|
+
`spec_helper.rb` with the following code:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
require 'pakyow-test'
|
61
|
+
Pakyow::TestHelp.setup
|
62
|
+
|
63
|
+
RSpec.configure do |config|
|
64
|
+
config.include Pakyow::TestHelp::Helpers
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
Now create files within the `spec` directory that follow the `*_spec.rb` naming
|
69
|
+
convention and use `spec` to run the specs.
|
70
|
+
|
71
|
+
## Usage
|
72
|
+
|
73
|
+
Check out the testing docs. It also might be helpful to take a look at the
|
74
|
+
integration tests for pakyow-test itself:
|
75
|
+
|
76
|
+
- https://github.com/pakyow/pakyow/tree/master/pakyow-test/spec/integration
|
77
|
+
|
78
|
+
# Download
|
79
|
+
|
80
|
+
The latest version of Pakyow Test can be installed with RubyGems:
|
81
|
+
|
82
|
+
```
|
83
|
+
gem install pakyow-test
|
84
|
+
```
|
85
|
+
|
86
|
+
Source code can be downloaded as part of the Pakyow project on Github:
|
87
|
+
|
88
|
+
- https://github.com/pakyow/pakyow/tree/master/pakyow-test
|
89
|
+
|
90
|
+
# License
|
91
|
+
|
92
|
+
Pakyow Test is released free and open-source under the [MIT
|
93
|
+
License](http://opensource.org/licenses/MIT).
|
94
|
+
|
95
|
+
# Support
|
96
|
+
|
97
|
+
Documentation is available here:
|
98
|
+
|
99
|
+
- http://pakyow.org/docs/testing
|
100
|
+
|
101
|
+
Found a bug? Tell us about it here:
|
102
|
+
|
103
|
+
- https://github.com/pakyow/pakyow/issues
|
104
|
+
|
105
|
+
We'd love to have you in the community:
|
106
|
+
|
107
|
+
- http://pakyow.org/get-involved
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'pakyow-support'
|
2
|
+
require 'pakyow-core'
|
3
|
+
require 'pakyow-presenter'
|
4
|
+
require 'pakyow-mailer'
|
5
|
+
require 'pakyow-realtime'
|
6
|
+
require 'pakyow-ui'
|
7
|
+
|
8
|
+
require_relative 'test_help/ext/request'
|
9
|
+
require_relative 'test_help/ext/response'
|
10
|
+
|
11
|
+
require_relative 'test_help/mocks/presenter_mock'
|
12
|
+
require_relative 'test_help/mocks/status_mock'
|
13
|
+
|
14
|
+
require_relative 'test_help/observables/observable_presenter'
|
15
|
+
require_relative 'test_help/observables/observable_view'
|
16
|
+
require_relative 'test_help/observables/observable_logger'
|
17
|
+
require_relative 'test_help/observables/realtime/observable_context'
|
18
|
+
require_relative 'test_help/observables/realtime/observable_mutator'
|
19
|
+
|
20
|
+
require_relative 'test_help/helpers'
|
21
|
+
require_relative 'test_help/simulator'
|
22
|
+
require_relative 'test_help/simulation'
|
23
|
+
|
24
|
+
module Pakyow
|
25
|
+
module TestHelp
|
26
|
+
def self.setup(path = './app/setup')
|
27
|
+
require path
|
28
|
+
|
29
|
+
Pakyow::App.after :match do
|
30
|
+
@presenter = Pakyow::TestHelp::ObservablePresenter.new(@presenter)
|
31
|
+
end
|
32
|
+
|
33
|
+
Pakyow::App.before :process do
|
34
|
+
Pakyow::TestHelp::Realtime::ObservableMutator.instance.reset
|
35
|
+
end
|
36
|
+
|
37
|
+
Pakyow::App.stage(ENV['TEST_ENV'] || :test)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Pakyow::Presenter::ViewContext::VIEW_CLASSES << Pakyow::TestHelp::ObservableView
|
43
|
+
|
44
|
+
module Pakyow
|
45
|
+
module Helpers
|
46
|
+
def socket
|
47
|
+
@socket ||= Pakyow::TestHelp::Realtime::ObservableContext.new(app)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module Pakyow
|
53
|
+
module Presenter
|
54
|
+
class ViewContext
|
55
|
+
def mutate(mutator, data: nil, with: nil)
|
56
|
+
Pakyow::TestHelp::Realtime::ObservableMutator.instance.mutate(mutator, self, data || with || [])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'simulator'
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
module TestHelp
|
5
|
+
module Helpers
|
6
|
+
def simulate(name_or_path, method: :get, with: {}, session: {}, cookies: {}, env: {}, &block)
|
7
|
+
sim = Pakyow::TestHelp::Simulator.new(
|
8
|
+
name_or_path,
|
9
|
+
method: method,
|
10
|
+
params: with,
|
11
|
+
session: session,
|
12
|
+
cookies: cookies,
|
13
|
+
env: env
|
14
|
+
)
|
15
|
+
|
16
|
+
sim.run(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method :sim, :simulate
|
20
|
+
|
21
|
+
Pakyow::RouteEval::HTTP_METHODS.each do |method|
|
22
|
+
define_method method do |name_or_path, **args, &block|
|
23
|
+
simulate(name_or_path, method: method, **args, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Pakyow
|
2
|
+
module TestHelp
|
3
|
+
class MockPresenter
|
4
|
+
attr_reader :calls
|
5
|
+
|
6
|
+
def initialize(presenter)
|
7
|
+
@presenter = presenter
|
8
|
+
@calls = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(method, *args, &block)
|
12
|
+
ret = @presenter.send(method, *args, &block)
|
13
|
+
@calls << [method, args]
|
14
|
+
return ret
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Pakyow
|
2
|
+
module TestHelp
|
3
|
+
class MockStatus
|
4
|
+
attr_reader :value
|
5
|
+
|
6
|
+
def initialize(value)
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(equal_value)
|
11
|
+
if equal_value.is_a?(Symbol)
|
12
|
+
equal_value = Pakyow::Response::STATUS_CODE_LOOKUP[equal_value]
|
13
|
+
end
|
14
|
+
|
15
|
+
@value == equal_value
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_i
|
19
|
+
@value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Pakyow
|
2
|
+
module TestHelp
|
3
|
+
module Observable
|
4
|
+
#TODO a version of this exists in ViewContext; consider drying it up
|
5
|
+
VIEW_CLASSES = [
|
6
|
+
Pakyow::Presenter::View,
|
7
|
+
Pakyow::Presenter::ViewCollection,
|
8
|
+
Pakyow::Presenter::Partial,
|
9
|
+
Pakyow::Presenter::Template,
|
10
|
+
Pakyow::Presenter::Container,
|
11
|
+
Pakyow::Presenter::ViewComposer
|
12
|
+
]
|
13
|
+
|
14
|
+
def method_missing(name, *args, &block)
|
15
|
+
handle_value(observable.send(name, *args, &block))
|
16
|
+
end
|
17
|
+
|
18
|
+
#TODO likely need to handle nested observations
|
19
|
+
def observing(scope, action, traversal, values)
|
20
|
+
@observations ||= []
|
21
|
+
@observations << {
|
22
|
+
scope: scope,
|
23
|
+
action: action,
|
24
|
+
traversal: traversal,
|
25
|
+
values: values
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def observed?(scope, action, traversal, values)
|
30
|
+
return false if @observations.nil?
|
31
|
+
@observations.each do |observation|
|
32
|
+
next if observation[:scope] != scope
|
33
|
+
next if observation[:action] != action
|
34
|
+
next if observation[:traversal] != traversal
|
35
|
+
|
36
|
+
values.each_pair do |k, v|
|
37
|
+
return false if observation[:values][k] != v
|
38
|
+
end
|
39
|
+
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def handle_value(value)
|
49
|
+
if VIEW_CLASSES.include?(value.class)
|
50
|
+
traversal = []
|
51
|
+
if self.is_a?(ObservableView)
|
52
|
+
parent = presenter
|
53
|
+
if view.is_a?(Pakyow::Presenter::View) || view.is_a?(Pakyow::Presenter::ViewCollection)
|
54
|
+
traversal = @traversal.dup
|
55
|
+
traversal << value.scoped_as
|
56
|
+
end
|
57
|
+
else
|
58
|
+
parent = self
|
59
|
+
end
|
60
|
+
|
61
|
+
if value.is_a?(Pakyow::Presenter::ViewCollection)
|
62
|
+
value.instance_variable_get(:@views).map! { |collected_view|
|
63
|
+
ObservableView.new(collected_view, parent, traversal)
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
return ObservableView.new(value, parent, traversal)
|
68
|
+
end
|
69
|
+
|
70
|
+
value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Pakyow
|
2
|
+
module TestHelp
|
3
|
+
class ObservableLogger
|
4
|
+
def initialize
|
5
|
+
@io = StringIO.new
|
6
|
+
@logger = Pakyow::Logger.new(@io)
|
7
|
+
@logs = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def include?(string)
|
11
|
+
@io.string.include?(string)
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method, *args, &block)
|
15
|
+
@logger.send(method, *args, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../observable'
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
module TestHelp
|
5
|
+
class ObservablePresenter
|
6
|
+
include Observable
|
7
|
+
attr_reader :presenter
|
8
|
+
|
9
|
+
def initialize(presenter)
|
10
|
+
@presenter = presenter
|
11
|
+
end
|
12
|
+
|
13
|
+
def observable
|
14
|
+
presenter
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require_relative '../observable'
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
module TestHelp
|
5
|
+
class ObservableView
|
6
|
+
include Observable
|
7
|
+
attr_reader :view, :presenter, :traversal
|
8
|
+
|
9
|
+
def initialize(view, presenter, traversal)
|
10
|
+
@view = view
|
11
|
+
@presenter = presenter
|
12
|
+
@traversal = traversal
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
doc == other.doc
|
17
|
+
end
|
18
|
+
|
19
|
+
def observable
|
20
|
+
view
|
21
|
+
end
|
22
|
+
|
23
|
+
def with(&block)
|
24
|
+
if block.arity == 0
|
25
|
+
instance_exec(&block)
|
26
|
+
else
|
27
|
+
yield(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def for(data, &block)
|
34
|
+
view.for(data) do |view, datum|
|
35
|
+
block.call(handle_value(view), datum)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def apply(data, bindings: {}, context: nil, &block)
|
40
|
+
presenter.observing(view.scoped_as, :apply, traversal, data: data, bindings: bindings, context: context, block: block)
|
41
|
+
|
42
|
+
result = view.apply(data, bindings: bindings, context: context) do |view, datum|
|
43
|
+
block.call(handle_value(view), datum)
|
44
|
+
end
|
45
|
+
|
46
|
+
handle_value(result)
|
47
|
+
end
|
48
|
+
|
49
|
+
def append(appendable_view)
|
50
|
+
presenter.observing(view.scoped_as, :append, traversal, view: appendable_view)
|
51
|
+
handle_value(view.append(appendable_view))
|
52
|
+
end
|
53
|
+
|
54
|
+
def prepend(prependable_view)
|
55
|
+
presenter.observing(view.scoped_as, :prepend, traversal, view: prependable_view)
|
56
|
+
handle_value(view.prepend(prependable_view))
|
57
|
+
end
|
58
|
+
|
59
|
+
def after(after_view)
|
60
|
+
presenter.observing(view.scoped_as, :after, traversal, view: after_view)
|
61
|
+
handle_value(view.after(after_view))
|
62
|
+
end
|
63
|
+
|
64
|
+
def before(before_view)
|
65
|
+
presenter.observing(view.scoped_as, :before, traversal, view: before_view)
|
66
|
+
handle_value(view.before(before_view))
|
67
|
+
end
|
68
|
+
|
69
|
+
def replace(replace_view)
|
70
|
+
presenter.observing(view.scoped_as, :replace, traversal, view: replace_view)
|
71
|
+
handle_value(view.replace(replace_view))
|
72
|
+
end
|
73
|
+
|
74
|
+
def scope?(name)
|
75
|
+
view.scope(name).length > 0
|
76
|
+
end
|
77
|
+
|
78
|
+
def prop?(name)
|
79
|
+
view.prop(name).length > 0
|
80
|
+
end
|
81
|
+
|
82
|
+
def exists?
|
83
|
+
view.length > 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def applied?(data = nil)
|
87
|
+
values = {}
|
88
|
+
values[:data] = data if data
|
89
|
+
presenter.observed?(view.scoped_as, :apply, traversal, values)
|
90
|
+
end
|
91
|
+
|
92
|
+
def bound?(value)
|
93
|
+
view[0].text == value
|
94
|
+
end
|
95
|
+
|
96
|
+
def appended?(appended_view = nil)
|
97
|
+
values = {}
|
98
|
+
values[:view] = appended_view if appended_view
|
99
|
+
presenter.observed?(view.scoped_as, :append, traversal, values)
|
100
|
+
end
|
101
|
+
|
102
|
+
def prepended?(prepended_view = nil)
|
103
|
+
values = {}
|
104
|
+
values[:view] = prepended_view if prepended_view
|
105
|
+
presenter.observed?(view.scoped_as, :prepend, traversal, values)
|
106
|
+
end
|
107
|
+
|
108
|
+
def after?(after_view = nil)
|
109
|
+
values = {}
|
110
|
+
values[:view] = after_view if after_view
|
111
|
+
presenter.observed?(view.scoped_as, :after, traversal, values)
|
112
|
+
end
|
113
|
+
|
114
|
+
def before?(before_view = nil)
|
115
|
+
values = {}
|
116
|
+
values[:view] = before_view if before_view
|
117
|
+
presenter.observed?(view.scoped_as, :before, traversal, values)
|
118
|
+
end
|
119
|
+
|
120
|
+
def replaced?(replace_view = nil)
|
121
|
+
values = {}
|
122
|
+
values[:view] = replace_view if replace_view
|
123
|
+
presenter.observed?(view.scoped_as, :replace, traversal, values)
|
124
|
+
end
|
125
|
+
|
126
|
+
def mutated?(mutation = nil, data: nil)
|
127
|
+
Pakyow::TestHelp::Realtime::ObservableMutator.instance.mutated?(self, mutation, data: data)
|
128
|
+
end
|
129
|
+
|
130
|
+
def subscribed?
|
131
|
+
Pakyow::TestHelp::Realtime::ObservableMutator.instance.subscribed?(self)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Pakyow
|
2
|
+
module TestHelp
|
3
|
+
module Realtime
|
4
|
+
class ObservableContext
|
5
|
+
def initialize(context)
|
6
|
+
@context = Pakyow::Realtime::Context.new(context)
|
7
|
+
@pushes = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing(method, *args, &block)
|
11
|
+
@context.send(method, *args, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def push(msg, *channels)
|
15
|
+
channels.each do |channel|
|
16
|
+
(@pushes[channel.to_sym] ||= []) << msg
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def pushed?(message = nil, to: nil)
|
21
|
+
if to.nil? && message.nil?
|
22
|
+
!@pushes.empty?
|
23
|
+
elsif to.nil? && message
|
24
|
+
@pushes.values.flatten.include?(message)
|
25
|
+
elsif message.nil? && to
|
26
|
+
@pushes.key?(to.to_sym)
|
27
|
+
else
|
28
|
+
@pushes.fetch(to.to_sym).include?(message)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Pakyow
|
2
|
+
module TestHelp
|
3
|
+
module Realtime
|
4
|
+
class ObservableMutator
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
reset
|
9
|
+
end
|
10
|
+
|
11
|
+
def reset
|
12
|
+
@mutations = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def mutate(mutation_name, view, data)
|
16
|
+
context = ObservableMutateContext.new(
|
17
|
+
Pakyow::UI::Mutator.instance.mutate(mutation_name, view, data)
|
18
|
+
)
|
19
|
+
|
20
|
+
@mutations << {
|
21
|
+
mutation_name: mutation_name,
|
22
|
+
context: context,
|
23
|
+
view: view,
|
24
|
+
data: data
|
25
|
+
}
|
26
|
+
|
27
|
+
context
|
28
|
+
end
|
29
|
+
|
30
|
+
def mutated?(observable_view, mutation_name, data: nil)
|
31
|
+
if mutation_name.nil? && data.nil?
|
32
|
+
@mutations.each do |mutation|
|
33
|
+
return true if mutation[:view].subject.observable == observable_view.observable
|
34
|
+
end
|
35
|
+
elsif mutation_name && data.nil?
|
36
|
+
@mutations.each do |mutation|
|
37
|
+
return true if mutation[:mutation_name] == mutation_name && mutation[:view].subject.observable == observable_view.observable
|
38
|
+
end
|
39
|
+
elsif data && mutation_name.nil?
|
40
|
+
@mutations.each do |mutation|
|
41
|
+
return true if mutation[:view].subject.observable == observable_view.observable && mutation[:data] == data
|
42
|
+
end
|
43
|
+
else
|
44
|
+
@mutations.each do |mutation|
|
45
|
+
return true if mutation[:mutation_name] == mutation_name && mutation[:view].subject.observable == observable_view.observable && mutation[:data] == data
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
def subscribed?(observable_view)
|
53
|
+
@mutations.each do |mutation|
|
54
|
+
return true if mutation[:context].subscribed? && mutation[:view].subject.observable == observable_view.observable
|
55
|
+
end
|
56
|
+
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class ObservableMutateContext
|
62
|
+
def initialize(context)
|
63
|
+
@context = context
|
64
|
+
@subscriptions = []
|
65
|
+
end
|
66
|
+
|
67
|
+
def subscribe(qualifications = {})
|
68
|
+
@subscriptions << qualifications
|
69
|
+
end
|
70
|
+
|
71
|
+
def subscribed?
|
72
|
+
!@subscriptions.empty?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
module TestHelp
|
5
|
+
class Simulation
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
REDIRECT_STATUSES = [301, 302, 307]
|
9
|
+
|
10
|
+
attr_reader :app
|
11
|
+
def_delegators :app, :request, :response, :req, :res, :presenter, :socket, :socket_digest, :socket_connection_id
|
12
|
+
def_delegators :response, :status, :type, :format
|
13
|
+
def_delegators :presenter, :view
|
14
|
+
|
15
|
+
def initialize(app)
|
16
|
+
@app = app
|
17
|
+
end
|
18
|
+
|
19
|
+
def redirected?(to: nil, as: nil)
|
20
|
+
return false unless REDIRECT_STATUSES.include?(response.status)
|
21
|
+
return false unless response.headers.key?('Location')
|
22
|
+
|
23
|
+
unless to.nil?
|
24
|
+
path = router.path(to)
|
25
|
+
return false if response.headers['Location'] != path
|
26
|
+
end
|
27
|
+
|
28
|
+
unless as.nil?
|
29
|
+
return status == as
|
30
|
+
end
|
31
|
+
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
|
35
|
+
def rerouted?(to: nil)
|
36
|
+
return false if request.first_path == request.path
|
37
|
+
|
38
|
+
unless to.nil?
|
39
|
+
return request.path == router.path(to)
|
40
|
+
end
|
41
|
+
|
42
|
+
return true
|
43
|
+
end
|
44
|
+
|
45
|
+
def subscribed?(to: nil)
|
46
|
+
if to.nil?
|
47
|
+
!channels.empty?
|
48
|
+
else
|
49
|
+
channels.include?(to.to_sym)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def unsubscribed?(to: nil)
|
54
|
+
!subscribed?(to: to)
|
55
|
+
end
|
56
|
+
|
57
|
+
def pushed?(message = nil, to: nil)
|
58
|
+
socket.pushed?(message, to: to)
|
59
|
+
end
|
60
|
+
|
61
|
+
def log
|
62
|
+
app.request.env['rack.logger']
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def router
|
68
|
+
Pakyow::Router.instance
|
69
|
+
end
|
70
|
+
|
71
|
+
def channels
|
72
|
+
socket.delegate.registry.channels_for_key(socket_digest(socket_connection_id))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative 'simulation'
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
module TestHelp
|
5
|
+
class Simulator
|
6
|
+
attr_reader :env, :path, :method, :params
|
7
|
+
|
8
|
+
def initialize(name_or_path, method: :get, params: {}, session: {}, cookies: {}, env: {})
|
9
|
+
@path = router.path(name_or_path, params)
|
10
|
+
@method = method
|
11
|
+
@params = params
|
12
|
+
@env = {
|
13
|
+
'REQUEST_METHOD' => @method.to_s.upcase,
|
14
|
+
'REQUEST_PATH' => @path,
|
15
|
+
'PATH_INFO' => @path,
|
16
|
+
'QUERY_STRING' => @params.to_a.map { |p| p.join('=') }.join('&'),
|
17
|
+
'rack.session' => session,
|
18
|
+
'rack.request.cookie_hash' => cookies,
|
19
|
+
'rack.input' => StringIO.new,
|
20
|
+
'pakyow.params' => @params,
|
21
|
+
'rack.logger' => Pakyow::TestHelp::ObservableLogger.new
|
22
|
+
}.merge(Hash[env.map{ |k,v| [k.to_s, v] }])
|
23
|
+
end
|
24
|
+
|
25
|
+
def run(&block)
|
26
|
+
app = Pakyow.app.dup
|
27
|
+
app.process(env)
|
28
|
+
|
29
|
+
sim = Simulation.new(app)
|
30
|
+
|
31
|
+
return sim unless block_given?
|
32
|
+
yield sim
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def router
|
38
|
+
Pakyow::Router.instance
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pakyow-test
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bryan Powell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pakyow-support
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.10.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.10.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pakyow-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.10.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.10.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pakyow-presenter
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.10.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.10.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pakyow-mailer
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.10.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.10.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.2'
|
83
|
+
description: Test helpers for Pakyow
|
84
|
+
email: bryan@metabahn.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- pakyow-test/CHANGELOG.md
|
90
|
+
- pakyow-test/LICENSE
|
91
|
+
- pakyow-test/README.md
|
92
|
+
- pakyow-test/lib/pakyow-test.rb
|
93
|
+
- pakyow-test/lib/test_help/ext/request.rb
|
94
|
+
- pakyow-test/lib/test_help/ext/response.rb
|
95
|
+
- pakyow-test/lib/test_help/helpers.rb
|
96
|
+
- pakyow-test/lib/test_help/mocks/presenter_mock.rb
|
97
|
+
- pakyow-test/lib/test_help/mocks/status_mock.rb
|
98
|
+
- pakyow-test/lib/test_help/observable.rb
|
99
|
+
- pakyow-test/lib/test_help/observables/observable_logger.rb
|
100
|
+
- pakyow-test/lib/test_help/observables/observable_presenter.rb
|
101
|
+
- pakyow-test/lib/test_help/observables/observable_view.rb
|
102
|
+
- pakyow-test/lib/test_help/observables/realtime/observable_context.rb
|
103
|
+
- pakyow-test/lib/test_help/observables/realtime/observable_mutator.rb
|
104
|
+
- pakyow-test/lib/test_help/simulation.rb
|
105
|
+
- pakyow-test/lib/test_help/simulator.rb
|
106
|
+
homepage: http://pakyow.org
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- pakyow-test/lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 2.0.0
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.4.5
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Pakyow Test
|
130
|
+
test_files: []
|