crabfarm 0.4.2 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/assets/live-tools/instructions.html +17 -0
  3. data/assets/live-tools/tools.css +16 -0
  4. data/assets/live-tools/tools.js +41 -47
  5. data/assets/live-tools/welcome.html +18 -0
  6. data/lib/crabfarm/adapters/browser/abstract_webdriver.rb +19 -16
  7. data/lib/crabfarm/adapters/browser/phantom_js.rb +11 -11
  8. data/lib/crabfarm/assertion/fields.rb +8 -0
  9. data/lib/crabfarm/base_navigator.rb +4 -11
  10. data/lib/crabfarm/base_reducer.rb +5 -1
  11. data/lib/crabfarm/cli.rb +13 -13
  12. data/lib/crabfarm/context.rb +15 -3
  13. data/lib/crabfarm/factories/context.rb +24 -0
  14. data/lib/crabfarm/factories/decorable.rb +71 -0
  15. data/lib/crabfarm/factories/navigator.rb +14 -0
  16. data/lib/crabfarm/factories/reducer.rb +14 -0
  17. data/lib/crabfarm/factories/snapshot_reducer.rb +14 -0
  18. data/lib/crabfarm/http_client.rb +2 -5
  19. data/lib/crabfarm/live/context.rb +21 -0
  20. data/lib/crabfarm/live/controller.rb +20 -72
  21. data/lib/crabfarm/live/interactable.rb +6 -2
  22. data/lib/crabfarm/live/manager.rb +90 -18
  23. data/lib/crabfarm/live/navigator_runner.rb +43 -13
  24. data/lib/crabfarm/live/navigator_runner_direct.rb +39 -0
  25. data/lib/crabfarm/live/navigator_runner_rspec.rb +111 -0
  26. data/lib/crabfarm/live/reducer_runner.rb +61 -10
  27. data/lib/crabfarm/live/reducer_runner_direct.rb +41 -0
  28. data/lib/crabfarm/live/reducer_runner_rspec.rb +23 -0
  29. data/lib/crabfarm/live/watcher.rb +21 -7
  30. data/lib/crabfarm/modes/console.rb +1 -1
  31. data/lib/crabfarm/modes/live.rb +7 -4
  32. data/lib/crabfarm/modes/recorder/memento.rb +1 -5
  33. data/lib/crabfarm/modes/recorder/snapshot.rb +2 -2
  34. data/lib/crabfarm/modes/shared/interactive_decorator.rb +0 -1
  35. data/lib/crabfarm/modes/shared/snapshot_decorator.rb +17 -22
  36. data/lib/crabfarm/rspec/navigator_spec_helpers.rb +56 -0
  37. data/lib/crabfarm/rspec/reducer_spec_helpers.rb +29 -0
  38. data/lib/crabfarm/rspec/reducer_spy.rb +36 -0
  39. data/lib/crabfarm/rspec/reducer_spy_manager.rb +38 -0
  40. data/lib/crabfarm/rspec.rb +22 -66
  41. data/lib/crabfarm/support/phantom_runner.rb +77 -0
  42. data/lib/crabfarm/templates/Gemfile.erb +1 -0
  43. data/lib/crabfarm/transition_service.rb +3 -48
  44. data/lib/crabfarm/utils/console.rb +77 -0
  45. data/lib/crabfarm/utils/naming.rb +4 -3
  46. data/lib/crabfarm/utils/resolve.rb +39 -0
  47. data/lib/crabfarm/utils/rspec_runner.rb +54 -0
  48. data/lib/crabfarm/{live/helpers.rb → utils/webdriver.rb} +3 -3
  49. data/lib/crabfarm/version.rb +1 -1
  50. data/lib/crabfarm.rb +24 -3
  51. metadata +23 -6
  52. data/lib/crabfarm/context_factory.rb +0 -32
  53. data/lib/crabfarm/global_state.rb +0 -22
  54. data/lib/crabfarm/phantom_runner.rb +0 -75
@@ -0,0 +1,41 @@
1
+ require 'benchmark'
2
+ require 'crabfarm/utils/console'
3
+
4
+ module Crabfarm
5
+ module Live
6
+ class ReducerRunnerDirect
7
+
8
+ def initialize(_manager, _snapshot, _target, _params)
9
+ @manager = _manager
10
+ @snapshot = _snapshot
11
+ @target = _target
12
+ @params = _params
13
+ end
14
+
15
+ def execute
16
+ raise ArgumentError.new 'Must provide a snapshot to execute reducer' if @snapshot.nil?
17
+
18
+ snapshot_path = @target.snapshot_path @snapshot
19
+ raise ArgumentError.new "Snapshot does not exist #{snapshot_path}" unless File.exist? snapshot_path
20
+
21
+ @reducer = Factories::SnapshotReducer.build @target, snapshot_path, (@params || {})
22
+ @elapsed = Benchmark.measure { @reducer.run }
23
+ end
24
+
25
+ def show_results
26
+ @manager.inject_web_tools
27
+ @manager.show_dialog(
28
+ :neutral,
29
+ 'Reducing completed!',
30
+ "The page was parsed in #{@elapsed.real} seconds",
31
+ @reducer.to_json,
32
+ :json
33
+ )
34
+
35
+ Utils::Console.json_result @reducer
36
+ Utils::Console.info "Completed in #{@elapsed.real} s"
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ require 'crabfarm/utils/rspec_runner'
2
+ require 'crabfarm/live/navigator_runner_rspec'
3
+
4
+ module Crabfarm
5
+ module Live
6
+ class ReducerRunnerRSpec < NavigatorRunnerRSpec
7
+
8
+ def execute
9
+ @examples = Utils::RSpecRunner.run_spec_for spec_for(@target), live: true
10
+ end
11
+
12
+ private
13
+
14
+ def spec_for(_class)
15
+ route = Utils::Naming.route_from_constant(_class.to_s)
16
+ route = route.join(File::SEPARATOR)
17
+ route = route + '_spec.rb'
18
+ File.join('spec','reducers', route)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -1,10 +1,12 @@
1
1
  require 'listen'
2
+ require 'crabfarm/utils/console'
2
3
 
3
4
  module Crabfarm
4
5
  module Live
5
6
  class Watcher
6
7
 
7
8
  PATH_RGX = /^\/[^\/]+\/(.*?)\.rb$/i
9
+ SPEC_RGX = /^\/[^\/]+\/(.*?)_spec\.rb$/i
8
10
 
9
11
  def initialize(_controller)
10
12
  @controller = _controller
@@ -26,15 +28,21 @@ module Crabfarm
26
28
  private
27
29
 
28
30
  def start_listener
29
- base_path = File.join CF_PATH, 'app'
30
- @listener = Listen.to(base_path) do |modified, added, removed|
31
+ app_path = File.join CF_PATH, 'app'
32
+ spec_path = File.join CF_PATH, 'spec'
33
+ @listener = Listen.to(app_path, spec_path) do |modified, added, removed|
31
34
  @candidates = (added + modified).map do |path|
32
- class_from_path path[base_path.length..-1]
33
- end.reject &:nil?
35
+ if path.start_with? app_path
36
+ class_from_path path[app_path.length..-1], PATH_RGX
37
+ else
38
+ class_from_path path[spec_path.length..-1], SPEC_RGX
39
+ end
40
+ end.reject(&:nil?)
34
41
  end
35
42
  @listener.start
36
43
  end
37
44
 
45
+
38
46
  def stop_listener
39
47
  @listener.stop if @listener
40
48
  end
@@ -43,7 +51,13 @@ module Crabfarm
43
51
  unless @candidates.nil?
44
52
  ActiveSupport::Dependencies.clear
45
53
  @candidates.each do |class_name|
46
- target = class_name.constantize rescue nil
54
+ target = begin
55
+ class_name.constantize
56
+ rescue Exception => exc
57
+ @controller.display_external_error exc
58
+ nil
59
+ end
60
+
47
61
  if target and target < Crabfarm::Live::Interactable
48
62
  @controller.execute_live target
49
63
  break
@@ -54,9 +68,9 @@ module Crabfarm
54
68
  end
55
69
  end
56
70
 
57
- def class_from_path(_filename)
71
+ def class_from_path(_filename, _regexp)
58
72
  _filename = _filename.gsub File::SEPARATOR, '/'
59
- m = _filename.match PATH_RGX
73
+ m = _filename.match _regexp
60
74
  return nil if m.nil?
61
75
  Utils::Naming.decode_crabfarm_uri m[1]
62
76
  end
@@ -61,7 +61,7 @@ module Crabfarm
61
61
  begin
62
62
  puts "Navigating, waiting to hit a reducer...".color Colors::NOTICE
63
63
  require 'crabfarm/modes/shared/snapshot_decorator'
64
- TransitionService.with_navigator_decorator Shared::SnapshotDecorator do
64
+ Factories::Reducer.with_decorator Shared::SnapshotDecorator do
65
65
  @manager.navigate _name, _params
66
66
  end
67
67
  puts "Navigation completed".color Colors::NOTICE
@@ -1,5 +1,6 @@
1
1
  require 'crabfarm/live/watcher'
2
2
  require 'crabfarm/live/controller'
3
+ require 'crabfarm/utils/console'
3
4
 
4
5
  module Crabfarm
5
6
  module Modes
@@ -7,6 +8,8 @@ module Crabfarm
7
8
  extend self
8
9
 
9
10
  def start_watch
11
+ Utils::Console.system 'Starting crabfarm live'
12
+
10
13
  begin
11
14
  Crabfarm.enable_debugging!
12
15
  Crabfarm.install_live_backend!
@@ -18,11 +21,11 @@ module Crabfarm
18
21
 
19
22
  rescue SystemExit, Interrupt
20
23
  # nothing
21
- rescue Exception => e
22
- puts "Fatal error: #{e.to_s}".color Console::Colors::ERROR
23
- puts e.backtrace
24
+ rescue Exception => exc
25
+ Utils::Console.error "Fatal error!"
26
+ Utils::Console.exception exc
24
27
  ensure
25
- puts 'Exiting'
28
+ Utils::Console.system 'Exiting'
26
29
  Crabfarm.live.stop rescue nil
27
30
  end
28
31
  end
@@ -9,14 +9,10 @@ module Crabfarm
9
9
  module Memento
10
10
  extend self
11
11
 
12
- def memento_path(_name)
13
- File.join(GlobalState.mementos_path, _name + '.json.gz')
14
- end
15
-
16
12
  def start(_target, _replay=false)
17
13
  return puts "Must provide a recording target" unless _target.is_a? String
18
14
 
19
- target_path = memento_path _target
15
+ target_path = Utils::Resolve.memento_path _target
20
16
  return puts "Memento file does not exist: #{target_path}" if _replay and not File.exist? target_path
21
17
 
22
18
  start_crabtrap _replay, target_path
@@ -15,9 +15,9 @@ module Crabfarm
15
15
 
16
16
  begin
17
17
  puts "Navigating, waiting to hit a reducer...".color(Console::Colors::NOTICE)
18
- service.with_navigator_decorator Shared::SnapshotDecorator do
18
+ Factories::Reducer.with_decorator Shared::SnapshotDecorator do
19
19
  if _query.nil?
20
- service.with_navigator_decorator Shared::InteractiveDecorator do
20
+ Factories::Navigator.with_decorator Shared::InteractiveDecorator do
21
21
  service.transition _context, _navigator
22
22
  end
23
23
  else
@@ -61,7 +61,6 @@ module Crabfarm
61
61
  @i_params ||= InteractiveHash.new.merge! @params
62
62
  end
63
63
 
64
- _navigator
65
64
  end
66
65
 
67
66
  end
@@ -10,33 +10,28 @@ module Crabfarm
10
10
  include Crabfarm::Modes::Console::Colors
11
11
  end
12
12
 
13
- def self.decorate(_navigator)
14
-
15
- def _navigator.execute_reducer(_reducer)
16
- loop do
17
- name = Ask.input "-- Name for #{_reducer.class.to_s} snapshot (blank to skip)".color Colors::QUESTION
18
- if name.empty?
19
- puts "-- Skipping snapshot".color Colors::WARNING
20
- break
13
+ def self.decorate(_reducer)
14
+ loop do
15
+ name = Ask.input "-- Name for #{_reducer.class.to_s} snapshot (blank to skip)".color Colors::QUESTION
16
+ if name.empty?
17
+ puts "-- Skipping snapshot".color Colors::WARNING
18
+ break
19
+ else
20
+ file_path = _reducer.class.snapshot_path name
21
+
22
+ if File.exist? file_path
23
+ puts "-- Could not save snapshot, file already exist!".color Colors::ERROR
21
24
  else
22
- file_path = _reducer.class.snapshot_path name
23
-
24
- if File.exist? file_path
25
- puts "-- Could not save snapshot, file already exist!".color Colors::ERROR
26
- else
27
- dir_path = file_path.split(File::SEPARATOR)[0...-1]
28
- FileUtils.mkpath dir_path.join(File::SEPARATOR) if dir_path.length > 0
29
- File.write file_path, _reducer.raw_document
30
- puts "-- Snapshot written to #{file_path}".color Colors::RESULT
31
- break
32
- end
25
+ dir_path = file_path.split(File::SEPARATOR)[0...-1]
26
+ FileUtils.mkpath dir_path.join(File::SEPARATOR) if dir_path.length > 0
27
+ File.write file_path, _reducer.raw_document
28
+ puts "-- Snapshot written to #{file_path}".color Colors::RESULT
29
+ break
33
30
  end
34
31
  end
35
-
36
- _reducer.run
37
32
  end
38
33
 
39
- _navigator
34
+ nil
40
35
  end
41
36
 
42
37
  end
@@ -0,0 +1,56 @@
1
+ require 'crabfarm/rspec/reducer_spy_manager'
2
+
3
+ module Crabfarm
4
+ module RSpec
5
+ module NavigatorSpecHelpers
6
+
7
+ def navigate(_name=nil, _params={})
8
+ ensure_context_for :navigate
9
+
10
+ if _name.is_a? Hash
11
+ _params = _name
12
+ _name = nil
13
+ end
14
+
15
+ Factories::Reducer.with_decorator spy_manager do
16
+ if _name.nil?
17
+ return nil unless described_class < BaseNavigator # TODO: maybe raise an error here.
18
+ @navigator_state = @last_state = TransitionService.transition @navigator_context, described_class, _params
19
+ else
20
+ @last_state = TransitionService.transition @navigator_context, _name, (_params || {})
21
+ end
22
+ end
23
+ end
24
+
25
+ def state
26
+ @navigator_state || navigate(@navigator_params)
27
+ end
28
+
29
+ def last_state
30
+ @last_state
31
+ end
32
+
33
+ def spy_reducer(_name_or_class)
34
+ ensure_context_for :spy_reducer
35
+ reducer_class = Utils::Resolve.reducer_class _name_or_class
36
+ spy_manager.new_spy_for reducer_class
37
+ end
38
+
39
+ def browser(_session_id=nil)
40
+ ensure_context_for :browser
41
+ @navigator_context.pool.driver _session_id
42
+ end
43
+
44
+ private
45
+
46
+ def spy_manager
47
+ @navigator_spy_manager ||= ReducerSpyManager.new
48
+ end
49
+
50
+ def ensure_context_for(_name)
51
+ raise "'#{_name}' is only available in navigator specs." if @navigator_context.nil?
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ module Crabfarm
2
+ module RSpec
3
+ module ReducerSpecHelpers
4
+
5
+ def reduce(_snapshot, _params={})
6
+ ensure_reducer_for :reduce
7
+ raise ArgumentError.new 'Must provide a snapshot for reducer specs' if _snapshot.nil?
8
+
9
+ snap_path = described_class.snapshot_path _snapshot
10
+ raise ArgumentError.new "Snapshot does not exist #{snap_path}" unless File.exist? snap_path
11
+
12
+ reducer = Factories::SnapshotReducer.build described_class, snap_path, (_params || {})
13
+ reducer.run
14
+ reducer
15
+ end
16
+
17
+ def reducer
18
+ @reducer_state ||= reduce @reducer_snapshot, @reducer_params
19
+ end
20
+
21
+ private
22
+
23
+ def ensure_reducer_for(_name)
24
+ raise "'#{_name}' is only available in reducer specs." unless described_class < Crabfarm::BaseReducer
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ module Crabfarm
2
+ module RSpec
3
+ class ReducerSpy
4
+
5
+ Call = Struct.new(:target, :params)
6
+
7
+ attr_reader :original, :mock, :calls
8
+
9
+ def initialize(_original)
10
+ @original = _original
11
+ @calls = []
12
+ @mock = nil
13
+ end
14
+
15
+ def register_call(_target, _params)
16
+ @calls << Call.new(_target, _params)
17
+ end
18
+
19
+ def target
20
+ raise "'#{_original.to_s}' was not invoked" if calls.size == 0
21
+ calls.first.target
22
+ end
23
+
24
+ def params
25
+ raise "'#{_original.to_s}' was not invoked" if calls.size == 0
26
+ calls.first.params
27
+ end
28
+
29
+ def mock_with(_attributes)
30
+ @mock = _attributes
31
+ self
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require 'crabfarm/rspec/reducer_spy'
2
+
3
+ module Crabfarm
4
+ module RSpec
5
+
6
+ class ReducerSpyManager
7
+
8
+ def initialize
9
+ @spies = {}
10
+ end
11
+
12
+ def new_spy_for(_reducer_class)
13
+ @spies[_reducer_class.to_s] = ReducerSpy.new(_reducer_class)
14
+ end
15
+
16
+ # reducer decorator implementation
17
+
18
+ def prepare(_class, _target, _params)
19
+ spy = @spies[_class.to_s]
20
+ unless spy.nil?
21
+ spy.register_call _target, _params
22
+ if spy.mock
23
+ mock = _class.new _target, _params
24
+ mock.mock spy.mock
25
+
26
+ def mock.run
27
+ # do nothing
28
+ end
29
+
30
+ return mock
31
+ end
32
+ end
33
+ nil
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -1,76 +1,32 @@
1
- module Crabfarm
2
- module RSpec
3
-
4
- class Error < Crabfarm::Error; end
5
-
6
- def reduce(_snapshot=nil, _options={})
7
-
8
- raise Error.new "'reduce' is only available in reducer specs" unless described_class < Crabfarm::BaseReducer
9
-
10
- if _snapshot.is_a? Hash
11
- raise ArgumentException.new 'Invalid arguments' unless _options.nil?
12
- _options = _snapshot
13
- _snapshot = nil
14
- end
15
-
16
- snapshot_path = described_class.snapshot_path _snapshot
17
- raise Error.new "Snapshot does not exist #{snapshot_path}" unless File.exist? snapshot_path
18
-
19
- data = File.read snapshot_path
20
- reducer = described_class.new data, _options
21
- reducer.run
22
- reducer
23
- end
24
-
25
- def navigate(_name=nil, _params={})
26
-
27
- raise Error.new "'navigate' is only available in navigator specs" if @context.nil?
28
-
29
- if _name.is_a? Hash
30
- _params = _name
31
- _name = nil
32
- end
33
-
34
- if _name.nil?
35
- return nil unless described_class < BaseNavigator # TODO: maybe raise an error here.
36
- @state = @last_state = TransitionService.transition @context, described_class, _params
37
- else
38
- @last_state = TransitionService.transition @context, _name, _params
39
- end
40
- end
41
-
42
- def state
43
- @state ||= navigate
44
- end
45
-
46
- def last_state
47
- @last_state
48
- end
49
-
50
- def reducer
51
- @reducer ||= reduce
52
- end
53
-
54
- def browser(_session_id=nil)
55
- @context.pool.driver(_session_id)
56
- end
57
-
58
- end
59
- end
1
+ require 'crabfarm/rspec/navigator_spec_helpers'
2
+ require 'crabfarm/rspec/reducer_spec_helpers'
60
3
 
61
4
  RSpec.configure do |config|
62
- config.include Crabfarm::RSpec
5
+ config.include Crabfarm::RSpec::NavigatorSpecHelpers
6
+ config.include Crabfarm::RSpec::ReducerSpecHelpers
63
7
 
64
8
  config.around(:example) do |example|
65
9
  if described_class < Crabfarm::BaseReducer
66
- if example.metadata[:reducing] || example[:reducing_with_params]
67
- @reducer = reduce example.metadata[:reducing], example.metadata[:reducing_with_params] || {}
10
+ @reducer_snapshot = example.metadata[:reducing]
11
+ @reducer_params = example.metadata[:with_params] || {}
12
+
13
+ begin
14
+ example.run
15
+ ensure
16
+ # store result in metadata so it can be accessed by formatters/reporters
17
+ example.metadata[:result] = @reducer_state.as_json if @reducer_state
68
18
  end
69
- example.run
70
19
  elsif described_class < Crabfarm::BaseNavigator
71
- Crabfarm::ContextFactory.with_context example.metadata[:navigating] do |ctx|
72
- @context = ctx
73
- example.run
20
+ Crabfarm.with_context example.metadata[:navigating] do |ctx|
21
+ @navigator_context = ctx
22
+ @navigator_params = (example.metadata[:with_params] || {})
23
+
24
+ begin
25
+ example.run
26
+ ensure
27
+ # store result in metadata so it can be accessed by formatters/reporters
28
+ example.metadata[:result] = @navigator_state.document if @navigator_state
29
+ end
74
30
  end
75
31
  else
76
32
  example.run
@@ -0,0 +1,77 @@
1
+ require 'timeout'
2
+ require 'crabfarm/utils/processes'
3
+
4
+ module Crabfarm
5
+ module Support
6
+ class PhantomRunner
7
+
8
+ PHANTOM_START_TM = 5 # seconds
9
+
10
+ def initialize(_config={})
11
+ @config = _config;
12
+ @process = nil
13
+ end
14
+
15
+ def port
16
+ @config[:port]
17
+ end
18
+
19
+ def start
20
+ logger.info "Starting phantomjs in port #{port}"
21
+ @process = spawn_phantomjs
22
+ logger.info "Phantomjs started (PID: #{@process.pid})"
23
+ end
24
+
25
+ def stop
26
+ unless @process.nil?
27
+ logger.info "Stopping phantomjs (PID: #{@process.pid})"
28
+ @process.stop
29
+ @process = nil
30
+ logger.info "Phantomjs stopped"
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def spawn_phantomjs
37
+ proc = nil
38
+ begin
39
+ proc = Utils::Processes.start_logged_process 'phantomjs', phantomjs_cmd, logger
40
+ Timeout::timeout(PHANTOM_START_TM) { wait_for_server }
41
+ rescue ChildProcess::LaunchError
42
+ raise BinaryMissingError.new 'phantomjs', @config[:bin_path]
43
+ rescue Timeout::Error
44
+ proc.stop
45
+ raise
46
+ end
47
+ proc
48
+ end
49
+
50
+ def phantomjs_cmd
51
+ cmd = [@config[:bin_path]]
52
+ cmd << '--load-images=false' unless @config[:load_images]
53
+ cmd << "--proxy=#{@config[:proxy]}" unless @config[:proxy].nil?
54
+ cmd << "--webdriver=#{port}"
55
+ cmd << "--ssl-protocol=#{@config[:ssl]}" unless @config[:ssl].nil?
56
+ cmd << "--ignore-ssl-errors=true"
57
+ cmd << "--webdriver-loglevel=WARN"
58
+ cmd
59
+ end
60
+
61
+ def wait_for_server
62
+ loop do
63
+ begin
64
+ Net::HTTP.get_response(URI.parse("http://127.0.0.1:#{port}/status"))
65
+ break
66
+ rescue
67
+ end
68
+ end
69
+ end
70
+
71
+ def logger
72
+ Crabfarm.logger
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -12,5 +12,6 @@ gem "selenium-webdriver", "~> 2.45"
12
12
  gem "watir-webdriver"
13
13
 
14
14
  group :test do
15
+ gem "rspec", "~> 3.2.0"
15
16
  gem "rspec-nc"
16
17
  end
@@ -1,19 +1,6 @@
1
1
  module Crabfarm
2
2
  class TransitionService
3
3
 
4
- def self.with_navigator_decorator(_decorator)
5
- @decorator = DecoratorChain.new @decorator, _decorator
6
- begin
7
- yield
8
- ensure
9
- @decorator = @decorator.base
10
- end
11
- end
12
-
13
- def self.current_decorator
14
- @decorator
15
- end
16
-
17
4
  def self.transition(_context, _name, _params={})
18
5
  self.new(_context).transition(_name, _params)
19
6
  end
@@ -24,48 +11,16 @@ module Crabfarm
24
11
  @context = _context
25
12
  end
26
13
 
27
- def transition(_name, _params={})
28
- navigator_class = if _name.is_a? String or _name.is_a? Symbol
29
- load_class_from_uri _name
30
- else _name end
14
+ def transition(_name_or_class, _params={})
15
+ navigator_class = Utils::Resolve.navigator_class _name_or_class
31
16
 
32
17
  @context.prepare
33
- @navigator = navigator_class.new @context, _params
34
- @navigator = current_decorator.decorate @navigator unless current_decorator.nil?
35
-
18
+ @navigator = Factories::Navigator.build navigator_class, @context, _params
36
19
  @document = @navigator.run
37
20
  @document = @document.as_json if @document.respond_to? :as_json
38
21
 
39
22
  self
40
23
  end
41
24
 
42
- private
43
-
44
- def current_decorator
45
- self.class.current_decorator
46
- end
47
-
48
- def load_class_from_uri(_uri)
49
- class_name = Utils::Naming.decode_crabfarm_uri _uri
50
- class_name.constantize
51
- end
52
-
53
- class DecoratorChain
54
-
55
- attr_reader :base, :new
56
-
57
- def initialize(_base, _new)
58
- @base = _base
59
- @new = _new
60
- end
61
-
62
- def decorate(_navigator)
63
- _navigator = @new.decorate _navigator
64
- return _navigator if @base.nil?
65
- @base.decorate _navigator
66
- end
67
-
68
- end
69
-
70
25
  end
71
26
  end