roundabout 0.2.0 → 0.3.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 +5 -5
- data/.gitignore +1 -0
- data/README.md +19 -25
- data/Rakefile +8 -0
- data/app/assets/javascripts/roundabout/application.js +0 -1
- data/app/controllers/roundabout/application_controller.rb +3 -1
- data/app/controllers/roundabout/roundabout_controller.rb +5 -3
- data/app/views/roundabout/roundabout/index.html.erb +16 -2
- data/config/routes.rb +3 -1
- data/example_diagram.png +0 -0
- data/lib/roundabout.rb +7 -1
- data/lib/roundabout/engine.rb +2 -0
- data/lib/roundabout/minitest.rb +5 -0
- data/lib/roundabout/monkey/action_controller.rb +17 -10
- data/lib/roundabout/monkey/capybara.rb +45 -21
- data/lib/roundabout/railtie.rb +28 -7
- data/lib/roundabout/recorder.rb +2 -0
- data/lib/roundabout/rspec.rb +3 -2
- data/lib/roundabout/test-unit.rb +5 -0
- data/lib/roundabout/version.rb +3 -1
- data/roundabout.gemspec +11 -1
- data/test/app/assets/javascripts/application.js +14 -0
- data/test/app/assets/stylesheets/application.css +15 -0
- data/test/app/assets/stylesheets/scaffolds.scss +84 -0
- data/test/app/views/layouts/application.html.erb +15 -0
- data/test/app/views/users/_form.html.erb +22 -0
- data/test/app/views/users/edit.html.erb +6 -0
- data/test/app/views/users/index.html.erb +27 -0
- data/test/app/views/users/new.html.erb +5 -0
- data/test/app/views/users/show.html.erb +9 -0
- data/test/application_system_test_case.rb +7 -0
- data/test/dummy_app.rb +104 -0
- data/test/public/favicon.ico +0 -0
- data/test/system/roundabout_test.rb +71 -0
- data/test/test_helper.rb +25 -0
- data/vendor/assets/javascripts/raphael-min.js +1 -13
- metadata +177 -21
- data/app/assets/javascripts/roundabout/roundabout.js.coffee +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3e04a70b5737616244de5b9c4fa9d71fb3befb049732f9690dbc0e7b8a41e0b9
|
4
|
+
data.tar.gz: 79bf12bc73b6aff9a9caad512bb9d7a5a668847a56914cbe40b35da6a5e107ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9e1cc7575ed994138a771b4807c95586b7d776026a46acefc91e46550dcbe5f76e111e4fc80967769cb0022bcbdf3c107a7ec6db31aeb949451e45ea2806fb6
|
7
|
+
data.tar.gz: b2a3f5e70f1081e13c45a53aa9301a92ca15901a7d3fd11682fec3908c62315ab1b93dbf558218ed13a696b34e88d9ca069c3c32e695d05c33b8fdd77f66095a
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,58 +1,52 @@
|
|
1
1
|
# Roundabout
|
2
2
|
|
3
|
-
A Rails Engine that generates a page transition diagram for your Rails app.
|
3
|
+
A Rails Engine that generates and shows a page transition diagram for your Rails app from system tests.
|
4
|
+
|
5
|
+

|
4
6
|
|
5
7
|
|
6
8
|
## Requirements
|
7
9
|
|
8
|
-
- Ruby
|
10
|
+
- Ruby 2.x
|
9
11
|
|
10
|
-
- Rails 3 or
|
12
|
+
- Rails 3 or newer
|
11
13
|
|
12
|
-
- RSpec
|
14
|
+
- RSpec / Minitest / TestUnit
|
13
15
|
|
14
|
-
- Capybara
|
16
|
+
- Capybara
|
15
17
|
|
16
18
|
|
17
19
|
## Installation
|
18
20
|
|
19
|
-
|
21
|
+
Bundle this gem to your Rails app's development and test env:
|
20
22
|
|
21
23
|
```ruby
|
22
|
-
gem 'roundabout'
|
24
|
+
gem 'roundabout', group :development, :test
|
23
25
|
```
|
24
26
|
|
25
|
-
And execute:
|
26
27
|
|
27
|
-
|
28
|
-
% bundle
|
29
|
-
```
|
28
|
+
## Usage
|
30
29
|
|
31
|
-
|
30
|
+
Run the whole tests with `ROUNDABOUT` envvar (I suppose parallel spec is not supported ATM):
|
32
31
|
|
33
|
-
```
|
34
|
-
|
32
|
+
```bash
|
33
|
+
% ROUNDABOUT=1 rails test:system
|
35
34
|
```
|
36
35
|
|
36
|
+
All page transitions via capybara will be recorded, then woven into a diagram.
|
37
37
|
|
38
|
-
|
38
|
+
To see the generated diagram, just browse at your `http://localhost:3000/roundabout`.
|
39
|
+
You can also download a png image version and a PDF version from that page.
|
39
40
|
|
40
|
-
Firstly, run the whole test (I suppose parallel spec is not supported ATM)
|
41
41
|
|
42
|
-
|
43
|
-
% rake spec
|
44
|
-
```
|
42
|
+
## Example
|
45
43
|
|
46
|
-
|
44
|
+
The image shown at the very top of this documentation was generated from [Redmine](https://github.com/redmine/redmine) project's codebase.
|
47
45
|
|
48
46
|
|
49
47
|
## Contributing
|
50
48
|
|
51
|
-
|
52
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
54
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
55
|
-
5. Create new Pull Request
|
49
|
+
Send me a PR with a patch.
|
56
50
|
|
57
51
|
|
58
52
|
## Team
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'roundabout/application_controller'
|
3
4
|
require 'graphviz'
|
4
5
|
|
@@ -35,8 +36,9 @@ module Roundabout
|
|
35
36
|
end
|
36
37
|
format.html do
|
37
38
|
graph = GraphViz.parse_string(viz.output(dot: String))
|
38
|
-
@nodes
|
39
|
-
@
|
39
|
+
@nodes = graph.each_node.values
|
40
|
+
@edges = graph.each_edge.map {|e| e[:pos].source.split(' ').take(2).map {|s| s.sub(/^e,/, '') }.reverse << e[:color].source << e.node_one << e.node_two }
|
41
|
+
@graph_width, @graph_height = graph.graph.data['bb'].to_ruby.last(2)
|
40
42
|
end
|
41
43
|
end
|
42
44
|
else
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id="roundabout-container" style="width: <%= @graph_width %>px; height: <%= @graph_height %>px;">
|
2
|
-
<div id="roundabout"
|
2
|
+
<div id="roundabout">
|
3
3
|
<% @nodes.each.with_index(1) do |node, i| %>
|
4
4
|
<% width, height = BigDecimal.new(node[:width].source) * 72, BigDecimal.new(node[:height].source) * 72 %>
|
5
5
|
<div id="roundabout-node-<%= i %>" class="node" style="top: <%= node[:pos].point[1] - height / 2 %>px; left: <%= node[:pos].point[0] - width / 2 %>px; width: <%= width %>px; height: <%= height %>px;">
|
@@ -7,7 +7,6 @@
|
|
7
7
|
<div class="node-name"><span class="controller_name"><%= node_controller_name %></span><span class="controller_name"><%= node_action_name %></span></div>
|
8
8
|
</div>
|
9
9
|
<% end %>
|
10
|
-
<script>window.raw_edges = '<%= @edges.to_json.html_safe %>';</script>
|
11
10
|
</div>
|
12
11
|
</div>
|
13
12
|
<div id="downloads">
|
@@ -26,3 +25,18 @@
|
|
26
25
|
</li>
|
27
26
|
</ul>
|
28
27
|
</div>
|
28
|
+
<script>
|
29
|
+
(function () {
|
30
|
+
window.paper = Raphael(0, 0, <%= @graph_width %>, <%= @graph_height %>);
|
31
|
+
|
32
|
+
<%= @edges.to_json.html_safe %>.forEach(function(e) {
|
33
|
+
var path;
|
34
|
+
if (e[3] == e[4]) {
|
35
|
+
path = ['M', e[0], 'A', 10, 10, 180, 0, 0, e[1]]
|
36
|
+
} else {
|
37
|
+
path = ['M', e[0], e[1]]
|
38
|
+
}
|
39
|
+
window.paper.path(path).attr({'stroke-width': 2, stroke: e[2], 'arrow-end': 'classic-wide-long'})
|
40
|
+
})
|
41
|
+
})();
|
42
|
+
</script>
|
data/config/routes.rb
CHANGED
data/example_diagram.png
ADDED
Binary file
|
data/lib/roundabout.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'roundabout/version'
|
2
4
|
require 'roundabout/railtie'
|
3
5
|
require 'roundabout/recorder'
|
4
|
-
require 'roundabout/monkey/capybara'
|
5
6
|
|
6
7
|
module Roundabout
|
7
8
|
def self.record_transition(from, to, method, type)
|
@@ -20,4 +21,9 @@ module Roundabout
|
|
20
21
|
h = Rails.application.routes.recognize_path(path, method: method)
|
21
22
|
"#{h[:controller]}##{h[:action]}"
|
22
23
|
end
|
24
|
+
|
25
|
+
def self.save_results
|
26
|
+
transitions = compile_page_transitions
|
27
|
+
Rails.root.join('tmp/roundabout.json').open('w') {|f| f.write transitions.to_json} unless transitions.empty?
|
28
|
+
end
|
23
29
|
end
|
data/lib/roundabout/engine.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Roundabout
|
4
|
+
module ActionController
|
5
|
+
module Redirecting
|
6
|
+
def redirect_to(*)
|
7
|
+
ret = super
|
8
|
+
|
9
|
+
begin
|
10
|
+
h = @_request.env['action_dispatch.request.path_parameters'].with_indifferent_access
|
11
|
+
Roundabout.record_transition "#{h[:controller]}##{h[:action]}", Roundabout.normalize_url(self.location), :get, :redirect
|
12
|
+
rescue => e
|
13
|
+
p e
|
14
|
+
end
|
15
|
+
ret
|
10
16
|
end
|
11
17
|
end
|
12
|
-
alias_method_chain :redirect_to, :recording
|
13
18
|
end
|
14
19
|
end
|
20
|
+
|
21
|
+
::ActionController::Base.prepend Roundabout::ActionController::Redirecting
|
@@ -1,28 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'capybara'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
module Roundabout
|
6
|
+
module Capybara
|
7
|
+
module Node
|
8
|
+
module Element
|
9
|
+
def click(*)
|
10
|
+
path_from = session.current_path
|
11
|
+
case tag_name
|
12
|
+
when 'input'
|
13
|
+
type = :form
|
14
|
+
begin
|
15
|
+
form = ancestor 'form'
|
16
|
+
path_to = form[:action]
|
17
|
+
method = form[:method]
|
18
|
+
begin
|
19
|
+
if (hidden = form.first('input[type=hidden][name=_method]', visible: false))
|
20
|
+
method = hidden.value
|
21
|
+
end
|
22
|
+
rescue ::Capybara::ExpectationNotMet
|
23
|
+
end
|
24
|
+
rescue ::Capybara::ElementNotFound
|
25
|
+
end
|
26
|
+
when 'a'
|
27
|
+
if (method = self[:'data-method'])
|
28
|
+
type = :form
|
29
|
+
else
|
30
|
+
method = :get
|
31
|
+
type = :link
|
32
|
+
end
|
33
|
+
path_to = self[:href]
|
34
|
+
end
|
11
35
|
|
12
|
-
|
13
|
-
end
|
14
|
-
alias_method_chain :follow, :recording
|
36
|
+
ret = super
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
38
|
+
if path_from && path_to && (path_from != path_to)
|
39
|
+
begin
|
40
|
+
Roundabout.record_transition Roundabout.normalize_url(path_from), Roundabout.normalize_url(path_to, method), method.to_sym, type
|
41
|
+
rescue => e
|
42
|
+
p e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
ret
|
46
|
+
end
|
47
|
+
end
|
23
48
|
end
|
24
|
-
|
25
|
-
submit_without_recording method, path, attributes
|
26
49
|
end
|
27
|
-
alias_method_chain :submit, :recording
|
28
50
|
end
|
51
|
+
|
52
|
+
::Capybara::Node::Element.prepend Roundabout::Capybara::Node::Element
|
data/lib/roundabout/railtie.rb
CHANGED
@@ -1,16 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails'
|
2
4
|
require 'roundabout/engine'
|
3
5
|
|
4
6
|
module Roundabout
|
5
7
|
class Railtie < ::Rails::Railtie #:nodoc:
|
6
|
-
initializer 'roundabout' do
|
7
|
-
|
8
|
-
|
8
|
+
initializer 'roundabout' do
|
9
|
+
if ENV['ROUNDABOUT']
|
10
|
+
if Rails::VERSION::MAJOR >= 5
|
11
|
+
ActiveSupport.on_load :action_dispatch_integration_test do
|
12
|
+
require 'roundabout/minitest' if defined? Minitest
|
13
|
+
end
|
14
|
+
else
|
15
|
+
ActiveSupport.on_load :active_support_test_case do
|
16
|
+
require 'roundabout/minitest' if defined? Minitest
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveSupport.on_load :action_controller do
|
21
|
+
require 'roundabout/monkey/action_controller'
|
22
|
+
end
|
23
|
+
|
24
|
+
config.after_initialize do |app|
|
25
|
+
require 'roundabout/monkey/capybara'
|
26
|
+
require 'roundabout/rspec' if defined? RSpec
|
27
|
+
require 'roundabout/test-unit' if defined? TestUnitRails
|
28
|
+
end
|
9
29
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
30
|
+
|
31
|
+
if Rails.env.development?
|
32
|
+
config.after_initialize do |app|
|
33
|
+
app.routes.append do
|
34
|
+
mount Roundabout::Engine => '/roundabout'
|
14
35
|
end
|
15
36
|
end
|
16
37
|
end
|
data/lib/roundabout/recorder.rb
CHANGED
data/lib/roundabout/rspec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.configure do |config|
|
2
4
|
config.after :suite do
|
3
|
-
|
4
|
-
Rails.root.join('tmp/roundabout.json').open('w') {|f| f.write transitions.to_json} unless transitions.empty?
|
5
|
+
Roundabout.save_results
|
5
6
|
end
|
6
7
|
end
|
data/lib/roundabout/version.rb
CHANGED
data/roundabout.gemspec
CHANGED
@@ -18,6 +18,16 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_runtime_dependency 'capybara', ['>= 1.0.0']
|
21
|
-
gem.add_runtime_dependency 'rspec', ['>= 2.0.0']
|
22
21
|
gem.add_runtime_dependency 'ruby-graphviz', ['>= 1.0.0']
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rails'
|
24
|
+
gem.add_development_dependency 'minitest'
|
25
|
+
gem.add_development_dependency 'sqlite3'
|
26
|
+
gem.add_development_dependency 'selenium-webdriver'
|
27
|
+
gem.add_development_dependency 'chromedriver-helper'
|
28
|
+
gem.add_development_dependency 'puma'
|
29
|
+
gem.add_development_dependency 'sass-rails'
|
30
|
+
gem.add_development_dependency 'uglifier'
|
31
|
+
gem.add_development_dependency 'sprockets-rails'
|
32
|
+
gem.add_development_dependency 'coffee-rails'
|
23
33
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
|
5
|
+
// vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require rails-ujs
|
14
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
|
6
|
+
* vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|