redcar 0.6.1 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/CHANGES +26 -0
  2. data/README.md +17 -31
  3. data/Rakefile +1 -1
  4. data/bin/redcar +1 -1
  5. data/lib/redcar.rb +8 -4
  6. data/lib/redcar/installer.rb +2 -1
  7. data/plugins/application/features/step_definitions/dialog_steps.rb +5 -0
  8. data/plugins/application/features/step_definitions/tree_steps.rb +1 -1
  9. data/plugins/application/features/support/env.rb +38 -17
  10. data/plugins/application/lib/application.rb +4 -0
  11. data/plugins/application/lib/application/command.rb +8 -2
  12. data/plugins/application/lib/application/command/executor.rb +37 -8
  13. data/plugins/application/lib/application/command/history.rb +3 -3
  14. data/plugins/application/lib/application/menu.rb +4 -0
  15. data/plugins/application/lib/application/menu/item.rb +9 -1
  16. data/plugins/application/lib/application/tab.rb +11 -0
  17. data/plugins/application/spec/application/command/executor_spec.rb +3 -3
  18. data/plugins/application/spec/application/command_spec.rb +24 -0
  19. data/plugins/application/spec/spec_helper.rb +1 -0
  20. data/plugins/application_swt/lib/application_swt.rb +27 -24
  21. data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +4 -33
  22. data/plugins/application_swt/lib/application_swt/dialogs/input_dialog.rb +46 -0
  23. data/plugins/application_swt/lib/application_swt/dialogs/text_and_file_dialog.rb +118 -0
  24. data/plugins/application_swt/lib/application_swt/icon.rb +37 -0
  25. data/plugins/application_swt/lib/application_swt/menu.rb +8 -3
  26. data/plugins/application_swt/lib/application_swt/tab.rb +6 -3
  27. data/plugins/application_swt/lib/application_swt/treebook.rb +29 -31
  28. data/plugins/application_swt/lib/swt/graphics_utils.rb +170 -0
  29. data/plugins/application_swt/lib/swt/vtab_folder.rb +125 -0
  30. data/plugins/application_swt/lib/swt/vtab_item.rb +69 -0
  31. data/plugins/application_swt/lib/swt/vtab_label.rb +84 -0
  32. data/plugins/auto_indenter/lib/auto_indenter.rb +4 -2
  33. data/plugins/core/lib/core/controller.rb +18 -0
  34. data/plugins/declarations/lib/declarations.rb +1 -1
  35. data/plugins/document_search/lib/document_search.rb +8 -6
  36. data/plugins/document_search/lib/document_search/replace.rb +51 -31
  37. data/plugins/document_search/lib/document_search/search_and_replace.rb +12 -11
  38. data/plugins/edit_view/features/step_definitions/editing_steps.rb +33 -17
  39. data/plugins/edit_view/lib/edit_view.rb +100 -21
  40. data/plugins/edit_view/lib/edit_view/actions/arrow_keys.rb +34 -11
  41. data/plugins/edit_view/lib/edit_view/actions/deletion.rb +10 -0
  42. data/plugins/edit_view/lib/edit_view/command.rb +5 -1
  43. data/plugins/edit_view/lib/edit_view/document.rb +8 -3
  44. data/plugins/edit_view/lib/edit_view/document/command.rb +15 -1
  45. data/plugins/edit_view/lib/edit_view/document/controller.rb +9 -0
  46. data/plugins/edit_view/lib/edit_view/document/history.rb +41 -0
  47. data/plugins/edit_view/lib/edit_view/tab_settings.rb +1 -11
  48. data/plugins/edit_view_swt/lib/edit_view_swt.rb +150 -4
  49. data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +1 -1
  50. data/plugins/edit_view_swt/vendor/java-mateview.rb +1 -1
  51. data/plugins/find-in-project/lib/find_in_project.rb +7 -5
  52. data/plugins/html_view/features/step_definitions/html_view_steps.rb +2 -2
  53. data/plugins/line_tools/features/step_definitions/line_tools_steps.rb +0 -1
  54. data/plugins/line_tools/lib/line_tools.rb +7 -9
  55. data/plugins/macros/features/block_selection_in_macros.feature +48 -0
  56. data/plugins/macros/features/predictive_macros.feature +79 -0
  57. data/plugins/macros/features/record_and_run_macro.feature +87 -0
  58. data/plugins/macros/features/step_definitions/macro_steps.rb +66 -0
  59. data/plugins/macros/features/step_definitions/prediction_steps.rb +8 -0
  60. data/plugins/macros/features/support/env.rb +2 -0
  61. data/plugins/macros/lib/macros.rb +167 -0
  62. data/plugins/macros/lib/macros/action_sequence.rb +30 -0
  63. data/plugins/macros/lib/macros/commands.rb +108 -0
  64. data/plugins/macros/lib/macros/macro.rb +37 -0
  65. data/plugins/macros/lib/macros/manager_controller.rb +67 -0
  66. data/plugins/macros/lib/macros/predictive/document_controller.rb +69 -0
  67. data/plugins/macros/lib/macros/predictive/sequence_finder.rb +112 -0
  68. data/plugins/macros/plugin.rb +9 -0
  69. data/plugins/macros/spec/macros/predictive/sequence_finder_spec.rb +142 -0
  70. data/plugins/macros/spec/spec_helper.rb +6 -0
  71. data/plugins/macros/views/macro_manager.html.erb +86 -0
  72. data/plugins/outline_view/lib/outline_view.rb +1 -1
  73. data/plugins/project/lib/project/commands.rb +2 -2
  74. data/plugins/redcar/redcar.rb +37 -46
  75. data/plugins/repl/lib/repl.rb +4 -4
  76. data/plugins/runnables/features/command_tree.feature +1 -1
  77. data/plugins/runnables/features/parameter_input.feature +42 -0
  78. data/plugins/runnables/features/step_definitions/runnable_steps.rb +6 -0
  79. data/plugins/runnables/features/support/env.rb +28 -8
  80. data/plugins/runnables/lib/runnables.rb +35 -206
  81. data/plugins/runnables/lib/runnables/commands.rb +65 -0
  82. data/plugins/runnables/lib/runnables/tree_mirror/nodes/runnable.rb +62 -0
  83. data/plugins/runnables/lib/runnables/tree_mirror/nodes/runnable_group.rb +59 -0
  84. data/plugins/runnables/lib/runnables/tree_mirror/nodes/runnable_type_group.rb +32 -0
  85. data/plugins/runnables/lib/runnables/tree_mirror/tree_controller.rb +41 -0
  86. data/plugins/runnables/lib/runnables/tree_mirror/tree_mirror.rb +61 -0
  87. data/plugins/scm/lib/scm.rb +78 -45
  88. data/plugins/scm/lib/scm/commands.rb +18 -4
  89. data/plugins/scm/lib/scm/model.rb +54 -41
  90. data/plugins/scm_svn/LICENSE +48 -0
  91. data/plugins/scm_svn/features/add_and_commit.feature +18 -0
  92. data/plugins/scm_svn/features/checkout.feature +5 -0
  93. data/plugins/scm_svn/features/edit_and_index.feature +12 -0
  94. data/plugins/scm_svn/features/ignore_files.feature +14 -0
  95. data/plugins/scm_svn/features/merge.feature +34 -0
  96. data/plugins/scm_svn/features/resolve_conflict.feature +23 -0
  97. data/plugins/scm_svn/features/revert_and_delete.feature +21 -0
  98. data/plugins/scm_svn/features/step_definitions/branch_and_merge_steps.rb +27 -0
  99. data/plugins/scm_svn/features/step_definitions/checkout_steps.rb +25 -0
  100. data/plugins/scm_svn/features/step_definitions/edit_and_index_steps.rb +50 -0
  101. data/plugins/scm_svn/features/step_definitions/scm_svn_steps.rb +57 -0
  102. data/plugins/scm_svn/features/support/env.rb +74 -0
  103. data/plugins/scm_svn/features/switch_branches.feature +53 -0
  104. data/plugins/scm_svn/features/update.feature +16 -0
  105. data/plugins/scm_svn/lib/scm_svn.rb +423 -9
  106. data/plugins/scm_svn/lib/scm_svn/change.rb +116 -0
  107. data/plugins/swt/lib/swt.rb +0 -15
  108. data/plugins/swt/lib/swt/cucumber_patches.rb +2 -37
  109. data/plugins/swt/lib/swt/cucumber_runner.rb +1 -0
  110. data/plugins/swt/lib/swt/full_swt.rb +2 -0
  111. data/plugins/textmate/vendor/redcar-bundles/Bundles/Clojure.tmbundle/Syntaxes/Clojure.tmLanguage +14 -2
  112. data/plugins/todo_list/lib/todo_list/todo_controller.rb +1 -1
  113. data/plugins/todo_list/views/default.css +50 -0
  114. data/plugins/todo_list/views/index.html.erb +5 -16
  115. data/plugins/todo_list/views/redcar_small_icon.png +0 -0
  116. data/plugins/tree_view_swt/lib/tree_view_swt.rb +14 -33
  117. data/plugins/view_shortcuts/views/default.css +31 -0
  118. data/plugins/view_shortcuts/views/index.html.erb +26 -16
  119. data/plugins/view_shortcuts/views/redcar_small_icon.png +0 -0
  120. data/{plugins/runnables → share}/icons/cog.png +0 -0
  121. data/share/icons/folder-gear-emblem.png +0 -0
  122. data/share/icons/folder-gear.png +0 -0
  123. data/share/icons/folder-open-small-gears.png +0 -0
  124. metadata +59 -5
@@ -0,0 +1,30 @@
1
+
2
+ module Redcar
3
+ module Macros
4
+ class ActionSequence
5
+ attr_reader :actions
6
+ attr_reader :skip_length
7
+
8
+ def initialize(actions, skip_length)
9
+ @actions = actions
10
+ @skip_length = skip_length
11
+ end
12
+
13
+ def run_in(edit_view, this_skip_length=nil)
14
+ this_skip_length ||= skip_length
15
+ edit_view.document.compound do
16
+ actions[this_skip_length..-1].each do |action|
17
+ case action
18
+ when Fixnum
19
+ edit_view.type_character(action)
20
+ when Symbol
21
+ edit_view.invoke_action(action)
22
+ when DocumentCommand
23
+ action.run(:env => {:edit_view => edit_view})
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,108 @@
1
+
2
+ module Redcar
3
+ module Macros
4
+ class StartStopRecordingCommand < Redcar::EditTabCommand
5
+ def self.unique_session_id
6
+ @unique_id ||= 0
7
+ @unique_id += 1
8
+ @unique_id
9
+ end
10
+
11
+ def self.new_macro_message
12
+ "Nameless Macro #{StartStopRecordingCommand.unique_session_id} :("
13
+ end
14
+
15
+ def execute
16
+ clear_recordings
17
+ if info = Macros.recording[edit_view]
18
+ edit_view.history.unsubscribe(info[:subscriber])
19
+ if info[:actions].any?
20
+ macro = Macro.new(StartStopRecordingCommand.new_macro_message,
21
+ info[:actions],
22
+ info[:start_in_block_selection_mode?])
23
+ Macros.session_macros << macro
24
+ Macros.last_run_or_recorded = macro
25
+ end
26
+ Macros.recording.delete(edit_view)
27
+ tab.icon = Redcar::Tab::DEFAULT_ICON
28
+ else
29
+ ev = edit_view
30
+ h = ev.history.subscribe do |action|
31
+ if should_record_action?(action)
32
+ Macros.recording[ev][:actions] << action
33
+ end
34
+ end
35
+ Macros.recording[ev] = {
36
+ :subscriber => h,
37
+ :actions => [],
38
+ :start_in_block_selection_mode? => ev.document.block_selection_mode?
39
+ }
40
+ tab.icon = :"control-record"
41
+ end
42
+ Redcar.app.repeat_event(:macro_record_changed)
43
+ end
44
+
45
+ private
46
+
47
+ def should_record_action?(action)
48
+ !action.is_a?(Redcar::Command) or action.class.record?
49
+ end
50
+
51
+ def clear_recordings
52
+ Macros.recording.keys.each do |ev|
53
+ unless ev.exists?
54
+ Macros.recording.delete(ev)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ class RunLastCommand < Redcar::DocumentCommand
61
+ sensitize :not_recording_a_macro, :is_last_macro
62
+
63
+ def execute
64
+ macro = Macros.last_run_or_recorded
65
+ macro.run_in(edit_view)
66
+ end
67
+ end
68
+
69
+ class NameLastMacroCommand < Redcar::Command
70
+ sensitize :any_macros_recorded_this_session
71
+
72
+ def execute
73
+ Macros.name_macro(Macros.session_macros.last.name,
74
+ "Assign a name to the last recorded macro:")
75
+ end
76
+ end
77
+
78
+ class MacroManagerCommand < Redcar::Command
79
+ def execute
80
+ controller = ManagerController.new
81
+ tab = win.new_tab(HtmlTab)
82
+ tab.html_view.controller = controller
83
+ tab.focus
84
+ end
85
+ end
86
+
87
+ class PredictCommand < Redcar::EditTabCommand
88
+ def execute
89
+ controller = doc.controllers(Macros::Predictive::DocumentController).first
90
+ controller.predict
91
+ end
92
+ end
93
+
94
+ class AlternatePredictCommand < Redcar::EditTabCommand
95
+ sensitize :in_prediction_mode
96
+
97
+ def execute
98
+ controller = doc.controllers(Macros::Predictive::DocumentController).first
99
+ controller.alternate_predict
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+
106
+
107
+
108
+
@@ -0,0 +1,37 @@
1
+
2
+ module Redcar
3
+ class Macro
4
+ attr_reader :actions
5
+ attr_writer :name
6
+
7
+ def initialize(name, actions, start_in_block_selection_mode)
8
+ @actions = actions.reject {|action| action.is_a?(Redcar::Macros::StartStopRecordingCommand)}
9
+ @name = name
10
+ @start_in_block_selection_mode = start_in_block_selection_mode
11
+ end
12
+
13
+ def name
14
+ @name
15
+ end
16
+
17
+ def start_in_block_selection_mode?
18
+ @start_in_block_selection_mode
19
+ end
20
+
21
+ def run
22
+ run_in EditView.focussed_edit_view
23
+ end
24
+
25
+ def run_in(edit_view)
26
+ Macros.last_run = self
27
+ Macros.last_run_or_recorded = self
28
+ previous_block_selection_mode = edit_view.document.block_selection_mode?
29
+ edit_view.document.block_selection_mode = start_in_block_selection_mode?
30
+
31
+ Macros::ActionSequence.new(actions, 0).run_in(edit_view)
32
+
33
+ edit_view.document.block_selection_mode = previous_block_selection_mode
34
+ Redcar.app.repeat_event(:macro_ran)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,67 @@
1
+
2
+ module Redcar
3
+ module Macros
4
+ class ManagerController
5
+ include Redcar::HtmlController
6
+
7
+ def title
8
+ "Macro Manager"
9
+ end
10
+
11
+ def index
12
+ rhtml = ERB.new(File.read(File.join(File.dirname(__FILE__), "..", "..", "views", "macro_manager.html.erb")))
13
+ rhtml.result(binding)
14
+ end
15
+
16
+ def assign_name(macro_name)
17
+ Macros.name_macro(macro_name, "Assign a name:")
18
+ nil
19
+ end
20
+
21
+ def rename_macro(macro_name)
22
+ Macros.rename_macro(macro_name)
23
+ nil
24
+ end
25
+
26
+ def delete_macro(macro_name)
27
+ Macros.delete_macro(macro_name)
28
+ nil
29
+ end
30
+
31
+ def macro_steps(macro)
32
+ html = ""
33
+ html << <<-HTML
34
+ <tr style="display: none;" class="macro-actions">
35
+ <td>
36
+ <table>
37
+ HTML
38
+
39
+ macro.actions.each do |action|
40
+ case action
41
+ when Fixnum
42
+ a = " "
43
+ a[0] = action
44
+ s = "Insert: #{a.inspect}"
45
+ when Symbol
46
+ s = "Navigation: #{action}"
47
+ when DocumentCommand
48
+ s = "Command: #{action.inspect.gsub("<", "&lt;").gsub(">", "&gt;")}"
49
+ else
50
+ raise "don't know what kind of action #{action.inspect} is"
51
+ end
52
+ html << <<-HTML
53
+ <tr><td>#{s}</td></tr>
54
+ HTML
55
+ end
56
+
57
+ html << <<-HTML
58
+ </table>
59
+ </td>
60
+ </tr>
61
+ HTML
62
+
63
+ html
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,69 @@
1
+
2
+ module Redcar
3
+ module Macros
4
+ module Predictive
5
+ class DocumentController
6
+ include Redcar::Document::Controller
7
+
8
+ def in_prediction
9
+ @in_prediction = true
10
+ yield
11
+ @in_prediction = false
12
+ end
13
+
14
+ def after_action(action)
15
+ unless @in_prediction
16
+ @seq = nil
17
+ @sequence_finder = nil
18
+ @previous_sequence = nil
19
+ Redcar.app.repeat_event(:end_prediction_mode)
20
+ end
21
+ end
22
+
23
+ def in_prediction_mode?
24
+ !!@seq
25
+ end
26
+
27
+ def sequence
28
+ @seq ||= sequence_finder.next
29
+ end
30
+
31
+ def previous_sequence
32
+ @previous_sequence
33
+ end
34
+
35
+ def next_sequence
36
+ @seq = sequence_finder.next
37
+ end
38
+
39
+ def sequence_finder
40
+ @sequence_finder ||= Predictive::SequenceFinder.new(document.edit_view.history)
41
+ end
42
+
43
+ def predict
44
+ in_prediction do
45
+ if sequence
46
+ skip_length = (@previous_sequence == sequence) ? 0 : nil
47
+ @previous_sequence = sequence
48
+ sequence.run_in(document.edit_view, skip_length)
49
+ Redcar.app.repeat_event(:start_prediction_mode)
50
+ end
51
+ end
52
+ end
53
+
54
+ def alternate_predict
55
+ in_prediction do
56
+ document.edit_view.undo
57
+ next_sequence
58
+ if sequence
59
+ skip_length = (@previous_sequence == sequence) ? 0 : nil
60
+ @previous_sequence = sequence
61
+ sequence.run_in(document.edit_view, skip_length)
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,112 @@
1
+
2
+ module Redcar
3
+ module Macros
4
+ module Predictive
5
+ class SequenceFinder
6
+ MAX_LENGTH = 100
7
+
8
+ attr_reader :super_sequence
9
+ attr_reader :state
10
+
11
+ def initialize(super_sequence)
12
+ @super_sequence = super_sequence.reverse
13
+ @state = {
14
+ :search_mode => :fully_repeated,
15
+ :length_x => max_possible_repeat_length,
16
+ :length_y => nil
17
+ }
18
+ end
19
+
20
+ def next
21
+ return nil if done?
22
+ seq = nil
23
+ until seq or done?
24
+ seq = detect_current
25
+ increment_state
26
+ end
27
+ seq
28
+ end
29
+
30
+ def detect_current
31
+ case current_search_mode
32
+ when :fully_repeated
33
+ detect_fully_repeated_sequence(state[:length_x])
34
+ when :partially_repeated
35
+ detect_partially_repeated_sequence(state[:length_x], state[:length_y])
36
+ end
37
+ end
38
+
39
+ def done?
40
+ @done
41
+ end
42
+
43
+ def current_search_mode
44
+ @state[:search_mode]
45
+ end
46
+
47
+ # in XX how long can X be?
48
+ def max_possible_repeat_length
49
+ super_sequence.length / 2
50
+ end
51
+
52
+ # in XYX how long can X be?
53
+ def max_possible_repeated_portion_length
54
+ r = super_sequence.length / 2
55
+ if r*2 == super_sequence.length
56
+ r - 1
57
+ else
58
+ r
59
+ end
60
+ end
61
+
62
+ # in XYX how long can Y be, given X?
63
+ def max_possible_non_repeated_portion_length(repeated_portion_length)
64
+ super_sequence.length - repeated_portion_length*2
65
+ end
66
+
67
+ private
68
+
69
+ def detect_fully_repeated_sequence(length)
70
+ candidate = super_sequence[0..(length - 1)]
71
+ confirmation = super_sequence[length..(2*length - 1)]
72
+ if candidate == confirmation
73
+ ActionSequence.new(candidate.reverse, 0)
74
+ end
75
+ end
76
+
77
+ def detect_partially_repeated_sequence(length_x, length_y)
78
+ candidate_x = super_sequence[0..(length_x - 1)]
79
+ candidate_y = super_sequence[length_x..(length_x + length_y - 1)]
80
+ confirmation_x = super_sequence[(length_x + length_y)..(2*length_x + length_y - 1)]
81
+ if candidate_x == confirmation_x
82
+ ActionSequence.new(candidate_x.reverse + candidate_y.reverse, candidate_x.length)
83
+ end
84
+ end
85
+
86
+ def increment_state
87
+ case current_search_mode
88
+ when :fully_repeated
89
+ if state[:length_x] > 1
90
+ state[:length_x] -= 1
91
+ else
92
+ state[:search_mode] = :partially_repeated
93
+ state[:length_x] = max_possible_repeated_portion_length
94
+ state[:length_y] = 1
95
+ end
96
+ when :partially_repeated
97
+ if state[:length_y] == max_possible_non_repeated_portion_length(state[:length_x])
98
+ state[:length_y] = 1
99
+ if state[:length_x] > 1
100
+ state[:length_x] -= 1
101
+ else
102
+ @done = true
103
+ end
104
+ else
105
+ state[:length_y] += 1
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,9 @@
1
+
2
+ Plugin.define do
3
+ name "macros"
4
+ version "1.0"
5
+ file "lib", "macros"
6
+ object "Redcar::Macros"
7
+ dependencies "application", ">0",
8
+ "edit_view", ">0"
9
+ end
@@ -0,0 +1,142 @@
1
+
2
+ require File.dirname(__FILE__) + '/../../spec_helper'
3
+
4
+ describe Redcar::Macros::Predictive::SequenceFinder do
5
+ SequenceFinder = Redcar::Macros::Predictive::SequenceFinder
6
+
7
+ describe "fully repeated sequences (XYXY)" do
8
+ it "should return nil if there are no repeated sequences" do
9
+ SequenceFinder.new(%w(a b c)).next.should be_nil
10
+ end
11
+
12
+ it "should find repeated sequence of length 1" do
13
+ SequenceFinder.new(%w(a a)).next.actions.should == %w(a)
14
+ end
15
+
16
+ it "should find repeated sequence of length 2" do
17
+ SequenceFinder.new(%w(a b a b)).next.actions.should == %w(a b)
18
+ end
19
+
20
+ it "should find repeated sequence of length 3" do
21
+ SequenceFinder.new(%w(a b c a b c)).next.actions.should == %w(a b c)
22
+ end
23
+
24
+ it "should find repeated sequence of length 3 with padding at the front" do
25
+ SequenceFinder.new(%w(x x a b c a b c)).next.actions.should == %w(a b c)
26
+ end
27
+
28
+ it "should choose the longest option when there are multiple options" do
29
+ SequenceFinder.new(%w(a b c c a b c c)).next.actions.should == %w(a b c c)
30
+ end
31
+
32
+ it "should cycle through fully repeated options" do
33
+ seq_finder = SequenceFinder.new(%w(a b c c a b c c))
34
+ seq1 = seq_finder.next
35
+ seq1.actions.should == %w(a b c c)
36
+
37
+ seq2 = seq_finder.next
38
+ seq2.actions.should == %w(c)
39
+ end
40
+ end
41
+
42
+ describe "partially repeated sequences (XYX)" do
43
+ it "should find partially repeated sequence of length 2, matched by 1" do
44
+ seq = SequenceFinder.new(%w(a b a)).next
45
+ seq.actions.should == %w(a b)
46
+ seq.skip_length.should == 1
47
+ end
48
+
49
+ it "should find partially repeated sequence of length 3, matched by 1" do
50
+ seq = SequenceFinder.new(%w(a b c a)).next
51
+ seq.actions.should == %w(a b c)
52
+ seq.skip_length.should == 1
53
+ end
54
+
55
+ it "should find partially repeated sequence of length 3, matched by 2" do
56
+ seq = SequenceFinder.new(%w(a b c a b)).next
57
+ seq.actions.should == %w(a b c)
58
+ seq.skip_length.should == 2
59
+ end
60
+
61
+ it "should find partially repeated sequence of length 3, matched by 2 with padding" do
62
+ seq = SequenceFinder.new(%w(x x X x X x a b c a b)).next
63
+ seq.actions.should == %w(a b c)
64
+ seq.skip_length.should == 2
65
+ end
66
+
67
+ it "should choose the longest X and shortest Y" do
68
+ seq = SequenceFinder.new(%w(a b r a c a d a b r a)).next
69
+ seq.actions.should == %w(a b r a c a d)
70
+ seq.skip_length.should == 4
71
+ end
72
+
73
+ it "should cycle through fully repeated options and partially repeated options" do
74
+ seq_finder = SequenceFinder.new(%w(a b c c a b c c))
75
+ seq1 = seq_finder.next
76
+ seq1.actions.should == %w(a b c c)
77
+ seq1.skip_length.should == 0
78
+
79
+ seq2 = seq_finder.next
80
+ seq2.actions.should == %w(c)
81
+ seq2.skip_length.should == 0
82
+
83
+ seq3 = seq_finder.next
84
+ seq3.actions.should == %w(b c c a)
85
+ seq3.skip_length.should == 3
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+
92
+
93
+
94
+ __END__
95
+ describe "find candidate sequences" do
96
+ it "should find from 1 length partial repeat" do
97
+ assert_equal [[1, 2, 3]],
98
+ Redcar::DynamicMacros.find_repeated_sequences([3, 1, 2, 3, 4, 5])
99
+ end
100
+
101
+ it "should find two possibilities from 2 length partial repeat" do
102
+ assert_equal [[1, 2, 3], [3, 1, 2]],
103
+ Redcar::DynamicMacros.find_repeated_sequences([2, 3, 1, 2, 3])
104
+ end
105
+
106
+ it "should find three possibilites from complete repetition of length 3 sequence" do
107
+ assert_equal [[1, 2, 3], [3, 1, 2], [2, 3, 1]],
108
+ Redcar::DynamicMacros.find_repeated_sequences([1, 2, 3, 1, 2, 3])
109
+ end
110
+
111
+ it "should find a lot of possibilities from a short repeated sequence"do
112
+ assert_equal [[2, 1], [1, 2, 1, 2], [2, 1, 2, 1], [1, 2], [1, 2, 1, 2], [1, 2, 1, 2, 1, 2]],
113
+ Redcar::DynamicMacros.find_repeated_sequences([2, 1, 2, 1, 2, 1, 2, 4])
114
+ end
115
+ end
116
+
117
+ it "should find most likely repeated sequence" do
118
+ assert_equal {:seq => [1, 2, 3], :length => 1, :gap => 2},
119
+ Redcar::DynamicMacros.find_repeated_sequence([3, 1, 2, 3, 4, 5])
120
+ assert_equal {:seq => [[1, 2, 3], :length => 2, :gap => 1},
121
+ Redcar::DynamicMacros.find_repeated_sequence([2, 3, 1, 2, 3])
122
+ assert_equal {:seq => [[1, 2, 3], :length => 3, :gap => 0},
123
+ Redcar::DynamicMacros.find_repeated_sequence([1, 2, 3, 1, 2, 3])
124
+ assert_equal {:seq => [[2, 1], :length => 2, :gap => 0},
125
+ Redcar::DynamicMacros.find_repeated_sequence([2, 1, 2, 1, 2, 1, 2, 4])
126
+ assert_equal {:seq => [%w{a b c c}.reverse, :length => 4, :gap => 0},
127
+ Redcar::DynamicMacros.find_repeated_sequence("abccabcc".split(//).reverse)
128
+ assert_equal {:seq => [%w{a b r a c a d}.reverse, :length => 4, :gap => 3},
129
+ Redcar::DynamicMacros.find_repeated_sequence("abracadabra".split(//).reverse)
130
+ end
131
+
132
+ it "should 3"
133
+ assert_equal {:seq => %w{a b r a c a d}.reverse, :length => 4, :gap => 3},
134
+ Redcar::DynamicMacros.find_repeated_sequence("abracadabra".split(//).reverse)
135
+ assert_equal {:seq => %w{b r a c a d a}.reverse, :length => 3, :gap => 4},
136
+ Redcar::DynamicMacros.find_repeated_sequence("abracadabra".split(//).reverse, 4, 3)
137
+ assert_equal {:seq => %w{r a c a d a b}.reverse, :length => 2, :gap => 5},
138
+ Redcar::DynamicMacros.find_repeated_sequence("abracadabra".split(//).reverse, 3, 4)
139
+ assert_equal {:seq => %w{a b r}.reverse, :length => 1, :gap => 2},
140
+ Redcar::DynamicMacros.find_repeated_sequence("abracadabra".split(//).reverse, 2, 5)
141
+ end
142
+ end