bond 0.1.4 → 0.2.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.
Files changed (43) hide show
  1. data/CHANGELOG.rdoc +12 -0
  2. data/LICENSE.txt +1 -1
  3. data/README.rdoc +195 -173
  4. data/Rakefile +9 -45
  5. data/lib/bond.rb +62 -93
  6. data/lib/bond/agent.rb +39 -33
  7. data/lib/bond/completion.rb +15 -27
  8. data/lib/bond/completions/activerecord.rb +12 -0
  9. data/lib/bond/completions/array.rb +1 -0
  10. data/lib/bond/completions/bond.rb +2 -0
  11. data/lib/bond/completions/hash.rb +3 -0
  12. data/lib/bond/completions/kernel.rb +13 -0
  13. data/lib/bond/completions/module.rb +7 -0
  14. data/lib/bond/completions/object.rb +21 -0
  15. data/lib/bond/completions/struct.rb +1 -0
  16. data/lib/bond/input.rb +28 -0
  17. data/lib/bond/m.rb +95 -0
  18. data/lib/bond/mission.rb +109 -69
  19. data/lib/bond/missions/anywhere_mission.rb +18 -0
  20. data/lib/bond/missions/default_mission.rb +16 -6
  21. data/lib/bond/missions/method_mission.rb +194 -13
  22. data/lib/bond/missions/object_mission.rb +29 -32
  23. data/lib/bond/missions/operator_method_mission.rb +26 -0
  24. data/lib/bond/rawline.rb +3 -3
  25. data/lib/bond/rc.rb +48 -0
  26. data/lib/bond/readline.rb +9 -6
  27. data/lib/bond/search.rb +51 -12
  28. data/lib/bond/version.rb +3 -0
  29. data/test/agent_test.rb +168 -65
  30. data/test/anywhere_mission_test.rb +34 -0
  31. data/test/bacon_extensions.rb +26 -0
  32. data/test/bond_test.rb +38 -23
  33. data/test/completion_test.rb +123 -21
  34. data/test/completions_test.rb +96 -0
  35. data/test/method_mission_test.rb +246 -0
  36. data/test/mission_test.rb +30 -44
  37. data/test/object_mission_test.rb +28 -32
  38. data/test/operator_method_mission_test.rb +66 -0
  39. data/test/search_test.rb +106 -29
  40. data/test/test_helper.rb +20 -13
  41. metadata +37 -8
  42. data/VERSION.yml +0 -4
  43. data/lib/bond/actions.rb +0 -69
@@ -0,0 +1,34 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "anywhere mission" do
4
+ before { Bond.agent.reset }
5
+
6
+ describe "normally" do
7
+ before { complete(:anywhere=>':[^:\s.]*') {|e| %w{:ab :bd :ae} } }
8
+
9
+ it "completes at beginning" do
10
+ tab(":a").should == %w{:ab :ae}
11
+ end
12
+
13
+ it "completes in middle of string" do
14
+ tab("hash[:a").should == %w{hash[:ab hash[:ae}
15
+ end
16
+
17
+ it "completes after word break chars" do
18
+ tab("{:ab=>1}[:a").should == ["1}[:ab", "1}[:ae"]
19
+ tab("nil;:a").should == %w{:ab :ae}
20
+ end
21
+ end
22
+
23
+ it 'with special chars and custom search completes' do
24
+ complete(:anywhere=>'\$[^\s.]*', :search=>false) {|e|
25
+ global_variables.grep(/^#{Regexp.escape(e.matched[1])}/)
26
+ }
27
+ tab("$LO").should == ["$LOAD_PATH", "$LOADED_FEATURES"]
28
+ end
29
+
30
+ it 'with :prefix completes' do
31
+ complete(:prefix=>'_', :anywhere=>':[^:\s.]*') { %w{:ab :bd :ae} }
32
+ tab("_:a").should == %w{_:ab _:ae}
33
+ end
34
+ end
@@ -0,0 +1,26 @@
1
+ module BaconExtensions
2
+ def self.included(mod)
3
+ mod.module_eval do
4
+ # nested context methods automatically inherit methods from parent contexts
5
+ def describe(*args, &block)
6
+ context = Bacon::Context.new(args.join(' '), &block)
7
+ (parent_context = self).methods(false).each {|e|
8
+ class<<context; self end.send(:define_method, e) {|*args| parent_context.send(e, *args)}
9
+ }
10
+ @before.each { |b| context.before(&b) }
11
+ @after.each { |b| context.after(&b) }
12
+ context.run
13
+ end
14
+ end
15
+ end
16
+
17
+ def xit(*args); end
18
+ def xdescribe(*args); end
19
+ def before_all; yield; end
20
+ def after_all; yield; end
21
+ def assert(description, &block)
22
+ it(description) do
23
+ block.call.should == true
24
+ end
25
+ end
26
+ end
data/test/bond_test.rb CHANGED
@@ -1,40 +1,55 @@
1
1
  require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
- class BondTest < Test::Unit::TestCase
4
- context "debrief" do
5
- before(:each) {|e| Bond.instance_eval("@agent = @config = nil")}
6
- test "prints error if readline_plugin is not a module" do
7
- capture_stderr { Bond.debrief :readline_plugin=>false }.should =~ /Invalid/
3
+ describe "Bond" do
4
+ describe "start" do
5
+ before { M.instance_eval("@agent = @config = nil"); M.expects(:load_completions) }
6
+ it "prints error if readline_plugin is not a module" do
7
+ capture_stderr { Bond.start :readline_plugin=>false }.should =~ /Invalid/
8
8
  end
9
9
 
10
- test "prints error if readline_plugin doesn't have all required methods" do
11
- capture_stderr {Bond.debrief :readline_plugin=>Module.new{ def setup; end } }.should =~ /Invalid/
10
+ it "prints error if readline_plugin doesn't have all required methods" do
11
+ capture_stderr {Bond.start :readline_plugin=>Module.new{ def setup(arg); end } }.should =~ /Invalid/
12
12
  end
13
13
 
14
- test "prints no error if valid readline_plugin" do
15
- capture_stderr {Bond.debrief :readline_plugin=>valid_readline_plugin }.should == ''
14
+ it "prints no error if valid readline_plugin" do
15
+ capture_stderr {Bond.start :readline_plugin=>valid_readline_plugin }.should == ''
16
16
  end
17
17
 
18
- test "sets default mission" do
19
- default_mission = lambda { %w{1 2 3}}
20
- Bond.reset
21
- Bond.debrief :default_mission=>default_mission, :readline_plugin=>valid_readline_plugin
22
- tabtab('1').should == ['1']
18
+ it "sets default mission" do
19
+ Bond.start :default_mission=>lambda {|e| %w{1 2 3}}, :readline_plugin=>valid_readline_plugin
20
+ tab('1').should == ['1']
23
21
  end
24
22
 
25
- test "sets default search" do
26
- Bond.reset
27
- Bond.debrief :default_search=>:underscore
28
- complete(:method=>'blah') { %w{all_quiet on_the western_front}}
29
- tabtab('blah a-q').should == ["all_quiet"]
30
- Bond.reset
23
+ it "sets default search" do
24
+ Bond.start :default_search=>:anywhere, :readline_plugin=>valid_readline_plugin
25
+ complete(:on=>/blah/) { %w{all_quiet on_the western_front}}
26
+ tab('blah qu').should == ["all_quiet"]
31
27
  end
28
+
29
+ it "defines completion in block" do
30
+ Bond.start do
31
+ complete(:on=>/blah/) { %w{all_quiet on_the western_front}}
32
+ end
33
+ tab('blah all').should == ["all_quiet"]
34
+ end
35
+ after_all { M.debrief :readline_plugin=>valid_readline_plugin; M.reset }
36
+ end
37
+
38
+ it "prints error if Readline setup fails" do
39
+ Bond::Readline.expects(:setup).raises('WTF')
40
+ capture_stderr { Bond.start(:readline_plugin=>Bond::Readline) }.should =~ /Error.*Failed Readline.*'WTF'/
41
+ M.debrief :readline_plugin=>valid_readline_plugin
42
+ end
43
+
44
+ it "start prints error for failed completion file" do
45
+ Rc.stubs(:module_eval).raises('wtf')
46
+ capture_stderr { Bond.start }.should =~ /Bond Error: Completion file.*with:\nwtf/
32
47
  end
33
48
 
34
- test "reset clears existing missions" do
49
+ it "reset clears existing missions" do
35
50
  complete(:on=>/blah/) {[]}
36
- Bond.agent.missions.size.should_not == 0
37
- Bond.reset
51
+ Bond.agent.missions.size.should.not == 0
52
+ M.reset
38
53
  Bond.agent.missions.size.should == 0
39
54
  end
40
55
  end
@@ -1,38 +1,140 @@
1
1
  require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
- class Bond::CompletionTest < Test::Unit::TestCase
4
- before(:all) { Bond.reset; Bond.debrief(:readline_plugin=>valid_readline_plugin); require 'bond/completion' }
3
+ describe "Completion" do
4
+ before_all {
5
+ M.reset
6
+ M.load_file File.dirname(__FILE__) + '/../lib/bond/completion.rb'
7
+ M.load_dir File.dirname(__FILE__) + '/../lib/bond'
8
+ }
5
9
 
6
- test "completes object methods anywhere" do
7
- matches = tabtab("blah :man.")
8
- assert matches.size > 0
9
- assert matches.all? {|e| e=~ /^:man/}
10
+ it "completes global variables anywhere" do
11
+ tab("blah $LOA").should.satisfy {|e|
12
+ e.size > 0 && e.all? {|e| e=~ /^\$LOA/} }
13
+ tab("h[$LOADED").should == ["h[$LOADED_FEATURES"]
10
14
  end
11
15
 
12
- test "completes global variables anywhere" do
13
- matches = tabtab("blah $-")
14
- assert matches.size > 0
15
- assert matches.all? {|e| e=~ /^\$-/}
16
+ it "completes absolute constants anywhere" do
17
+ tab("blah ::Arr").should == ["::Array"]
18
+ tab("h[::Arr").should == ["h[::Array"]
16
19
  end
17
20
 
18
- test "completes absolute constants anywhere" do
19
- tabtab("blah ::Arr").should == ["::Array"]
21
+ it "completes invalid constants safely" do
22
+ capture_stdout {
23
+ tab("Bond::MethodMission ").should == []
24
+ }.should == ''
20
25
  end
21
26
 
22
- test "completes nested classes anywhere" do
23
- tabtab("blah IRB::In").should == ["IRB::InputCompletor"]
27
+ it "completes nested classes anywhere" do
28
+ mock_irb
29
+ tab("blah IRB::In").should == ["IRB::InputCompletor"]
24
30
  end
25
31
 
26
- test "completes symbols anywhere" do
27
- Symbol.expects(:all_symbols).returns([:mah])
28
- assert tabtab("blah :m").size > 0
32
+ it "completes symbols anywhere" do
33
+ Symbol.expects(:all_symbols).twice.returns([:mah])
34
+ tab("blah :m").size.should.be > 0
35
+ tab("blah[:m").should == ["blah[:mah"]
29
36
  end
30
37
 
31
- test "completes string methods anywhere" do
32
- tabtab("blah 'man'.f").include?('.freeze').should == true
38
+ it "completes method arguments with parenthesis" do
39
+ tab("%w{ab bc cd}.delete(").should == %w{ab bc cd}
33
40
  end
34
41
 
35
- test "methods don't swallow up default completion" do
36
- Bond.agent.find_mission("Bond.complete(:method=>'blah') { Arr").should == nil
42
+ it "completes hash coming from a method" do
43
+ tab('Bond.config[:r').should == ["Bond.config[:readline_plugin"]
44
+ end
45
+
46
+ it "methods don't swallow up default completion" do
47
+ Bond.agent.find_mission("some_method(:verbose=>true) { Arr").should == nil
48
+ end
49
+
50
+ describe "completes object methods" do
51
+ def be_methods_from(klass, regex, obj=klass.new)
52
+ lambda {|e|
53
+ meths = e.map {|f| f.sub(/^#{Regexp.quote(regex)}/, '') }
54
+ meths.size.should.be > 0
55
+ (meths - obj.methods.map {|e| e.to_s} - Mission::OPERATORS).size.should == 0
56
+ }
57
+ end
58
+
59
+ shared "objects" do
60
+ it "non whitespace object" do
61
+ tab(':man.').should be_methods_from(Symbol, ':man.', :man)
62
+ end
63
+
64
+ it "nil" do
65
+ tab("nil.t").should be_methods_from(NilClass, 'nil.', nil)
66
+ end
67
+
68
+ it "false" do
69
+ tab("false.f").should be_methods_from(FalseClass, 'false.', false)
70
+ end
71
+
72
+ it "strings" do
73
+ tab("'man oh'.s").should be_methods_from(String, '.')
74
+ tab('"man oh".s').should be_methods_from(String, '.')
75
+ end
76
+
77
+ it "array" do
78
+ tab("[1, 2].f").should be_methods_from(Array, '2].')
79
+ end
80
+
81
+ it "hash" do
82
+ tab("{:a =>1}.f").should be_methods_from(Hash, '1}.')
83
+ end
84
+
85
+ it "regexp" do
86
+ tab("/man oh/.c").should be_methods_from(Regexp, 'oh/.', /man oh/)
87
+ end
88
+
89
+ it "proc" do
90
+ tab('lambda { }.c').should be_methods_from(Proc, '}.', lambda{})
91
+ tab('proc { }.c').should be_methods_from(Proc, '}.', lambda{})
92
+ end
93
+
94
+ it "range" do
95
+ tab("(1 .. 10).m").should be_methods_from(Range, '10).', (1..10))
96
+ end
97
+
98
+ it "object between ()" do
99
+ tab("(2 * 2).").should be_methods_from(Fixnum, '2).', 2)
100
+ tab("String.new('man oh').s").should be_methods_from(String, ').')
101
+ end
102
+
103
+ it "object quoted by {}" do
104
+ tab("%r{man oh}.c").should be_methods_from(Regexp, 'oh}.', /man oh/)
105
+ tab("%q{man oh}.s").should be_methods_from(String, 'oh}.')
106
+ tab("%Q{man oh}.s").should be_methods_from(String, 'oh}.')
107
+ tab("%w{man oh}.f").should be_methods_from(Array, 'oh}.')
108
+ tab("%s{man oh}.t").should be_methods_from(Symbol, 'oh}.', :man)
109
+ tab("%{man oh}.t").should be_methods_from(String, 'oh}.')
110
+ end
111
+
112
+ it "object quoted by []" do
113
+ tab("%r[man oh].c").should be_methods_from(Regexp, 'oh].', /man oh/)
114
+ tab("%q[man oh].s").should be_methods_from(String, 'oh].')
115
+ tab("%Q[man oh].s").should be_methods_from(String, 'oh].')
116
+ tab("%w[man oh].f").should be_methods_from(Array, 'oh].')
117
+ tab("%s[man oh].t").should be_methods_from(Symbol, 'oh].', :man)
118
+ tab("%[man oh].t").should be_methods_from(String, 'oh].')
119
+ end
120
+ end
121
+
122
+ describe "for" do
123
+ behaves_like "objects"
124
+ end
125
+
126
+ describe "after valid ruby for" do
127
+ def tab(str)
128
+ super("nil; "+str)
129
+ end
130
+ behaves_like "objects"
131
+ end
132
+
133
+ describe "after invalid ruby for" do
134
+ def tab(str)
135
+ super("blah "+str)
136
+ end
137
+ behaves_like "objects"
138
+ end
37
139
  end
38
140
  end
@@ -0,0 +1,96 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "completions for" do
4
+ before_all {
5
+ M.reset
6
+ complete(:all_methods=>true)
7
+ complete(:all_operator_methods=>true)
8
+ M.load_file File.dirname(__FILE__) + '/../lib/bond/completion.rb'
9
+ M.load_dir File.dirname(__FILE__) + '/../lib/bond'
10
+ }
11
+
12
+ it "Array#delete" do
13
+ tab("[12,23,34,15].delete 1").should == %w{12 15}
14
+ end
15
+
16
+ describe "Hash" do
17
+ before { @hash = %q{{:ab=>1,:bc=>1,:cd=>3,:ae=>2}} }
18
+
19
+ it "#delete" do
20
+ tab("#{@hash}.delete :a").sort.should == %w{:ab :ae}
21
+ end
22
+
23
+ it "#index" do
24
+ tab("#{@hash}.index 2").should == %w{2}
25
+ end
26
+
27
+ it "#[]" do
28
+ tab("#{@hash}['a").sort.should == %w{ab ae}
29
+ end
30
+ end
31
+
32
+ describe "Kernel" do
33
+ it "#raise" do
34
+ tab("raise Errno::ETIME").should == %w{Errno::ETIMEDOUT Errno::ETIME}
35
+ end
36
+
37
+ it "#require" do
38
+ mock_libs = ['net/http.rb', 'net/http/get.rb', 'abbrev.rb'].map {|e| $:[0] + "/#{e}" }
39
+ Dir.stubs(:[]).returns(mock_libs)
40
+ tab("require 'net/htt").should == %w{net/http.rb net/http/}
41
+ end
42
+ end
43
+
44
+ describe "Object" do
45
+ it "#instance_of?" do
46
+ tab("[].instance_of? Arr").should == ['Array']
47
+ end
48
+
49
+ it "#is_a?" do
50
+ tab("Module.is_a? Mod").should == ['Module']
51
+ end
52
+
53
+ it "#send" do
54
+ tab("Object.send :super").should == [':superclass']
55
+ end
56
+
57
+ it "#send and additional arguments" do
58
+ tab('Bond.send :const_get, Ag').should == ['Agent']
59
+ end
60
+
61
+ it "#send and invalid first argument" do
62
+ tab('Bond.send :blah, ').should == []
63
+ end
64
+
65
+ it "#instance_variable_get" do
66
+ tab("Bond::M.instance_variable_get '@a").should == ['@agent']
67
+ end
68
+
69
+ it "#method" do
70
+ tab("Bond::M.method :ho").should == [':home']
71
+ end
72
+
73
+ it "#[]" do
74
+ ::ENV['ZZZ'] = ::ENV['ZZY'] = 'blah'
75
+ tab("ENV['ZZ").should == %w{ZZY ZZZ}
76
+ end
77
+ end
78
+
79
+ describe "Module" do
80
+ it "#const_get" do
81
+ tab("Bond.const_get M").sort.should == ['M', 'MethodMission', 'Mission']
82
+ end
83
+
84
+ it "#instance_methods" do
85
+ tab("Bond::Agent.instance_method :ca").should == [':call']
86
+ end
87
+
88
+ it "#>" do
89
+ tab("Object > Mod").should == %w{Module}
90
+ end
91
+
92
+ it "#> and :files search" do
93
+ tab("Object > Bon").should == %w{Bond Bond::}
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,246 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "method mission" do
4
+ before_all { MethodMission.reset }
5
+ before { Bond.agent.reset; Bond.complete(:all_methods=>true) }
6
+
7
+ describe "method" do
8
+ before { complete(:method=>'Array#index') {|e| %w{ab cd ef ad} } }
9
+
10
+ it "completes" do
11
+ tab('[].index c').should == %w{cd}
12
+ end
13
+
14
+ it "completes quoted argument" do
15
+ tab('[].index "a').should == %w{ab ad}
16
+ end
17
+
18
+ it "completes parenthetical argument" do
19
+ tab('[].index("a').should == %w{ab ad}
20
+ end
21
+
22
+ it "completes symbolic argument" do
23
+ tab('[].index :a').should == %w{:ab :ad}
24
+ end
25
+
26
+ it "needs space to complete argument" do
27
+ tab('[].indexa').should == []
28
+ tab('[].index a').should == %w{ab ad}
29
+ end
30
+
31
+ it "completes all arguments with only space as argument" do
32
+ tab('[].index ').should == %w{ab cd ef ad}
33
+ end
34
+
35
+ it "completes with a chain of objects" do
36
+ tab('{}.to_a.index a').should == %w{ab ad}
37
+ end
38
+
39
+ it "completes after valid ruby" do
40
+ tab('nil; [].index a').should == %w{ab ad}
41
+ end
42
+
43
+ it "completes after invalid ruby" do
44
+ tab('blah [].index a').should == %w{ab ad}
45
+ end
46
+
47
+ describe "completes for whitespaced object that is" do
48
+ def complete_and_tab(klass, example)
49
+ complete(:method=>"#{klass}#to_s") { %w{ab cd ef ad} }
50
+ tab(example + '.to_s a').should == %w{ab ad}
51
+ end
52
+
53
+ it "a string" do
54
+ complete_and_tab(String, "'man oh'")
55
+ end
56
+
57
+ it "an array" do
58
+ complete_and_tab(Array, "[1, 2, 3]")
59
+ end
60
+
61
+ it "a hash" do
62
+ complete_and_tab(Hash, "{:a => 1}")
63
+ end
64
+
65
+ it "a regexp" do
66
+ complete_and_tab(Regexp, "/man oh/")
67
+ end
68
+
69
+ it "a proc" do
70
+ complete_and_tab(Proc, "lambda { }")
71
+ complete_and_tab(Proc, "proc { }")
72
+ end
73
+
74
+ it "a range" do
75
+ complete_and_tab(Range, "(1.. 10)")
76
+ end
77
+
78
+ it "wrapped ()" do
79
+ complete_and_tab(Fixnum, "(2 * 2)")
80
+ end
81
+
82
+ it "quoted by {}" do
83
+ complete_and_tab(String, "%q{man oh}")
84
+ end
85
+
86
+ it "quoted by []" do
87
+ complete_and_tab(String, "%q[man oh]")
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "any instance method" do
93
+ before { complete(:method=>'Array#index', :search=>:anywhere) {|e| %w{ab cd ef ad} } }
94
+
95
+ it "completes for objects of a subclass" do
96
+ class ::MyArray < Array; end
97
+ tab('MyArray.new.index a').should == %w{ab ad}
98
+ end
99
+
100
+ it "completes for objects of a subclass using its own definition" do
101
+ class ::MyArray < Array; end
102
+ complete(:method=>'MyArray#index') {|e| %w{aa ab bc} }
103
+ tab('MyArray.new.index a').should == %w{aa ab}
104
+ end
105
+
106
+ it "ignores invalid ruby" do
107
+ tab("[{].index a").should == []
108
+ end
109
+
110
+ it "with string :action copies its action" do
111
+ complete(:method=>"Array#fetch", :action=>"Array#index")
112
+ tab('[].fetch a').should == %w{ab ad}
113
+ end
114
+
115
+ it "with string :action copies its search" do
116
+ complete(:method=>"Array#fetch", :action=>"Array#index")
117
+ tab('[].fetch d').should == %w{cd ad}
118
+ end
119
+
120
+ it "with string :action and :search doesn't copy its search" do
121
+ complete(:method=>"Array#fetch", :action=>"Array#index", :search=>:normal)
122
+ tab('[].fetch d').should == []
123
+ end
124
+
125
+ it "with symbol :action references Rc method" do
126
+ Rc.module_eval %[def _fetch(input); %w{ab cd ef ad}; end ]
127
+ complete(:method=>"Array#fetch", :action=>:_fetch)
128
+ tab('[].fetch a').should == %w{ab ad}
129
+ end
130
+ end
131
+
132
+ describe "any class method" do
133
+ before { complete(:method=>'Date.parse') {|e| %w{12/01 03/01 01/01} } }
134
+
135
+ it "completes" do
136
+ tab('Date.parse 0').should == ["03/01", "01/01"]
137
+ end
138
+
139
+ it "completes for a subclass using inherited definition" do
140
+ class ::MyDate < Date; end
141
+ tab('MyDate.parse 0').should == ["03/01", "01/01"]
142
+ end
143
+
144
+ it "completes for a subclass using its own definition" do
145
+ class ::MyDate < Date; end
146
+ complete(:method=>'MyDate.parse') {|e| %w{12 03 01} }
147
+ tab('MyDate.parse 0').should == %w{03 01}
148
+ end
149
+
150
+ it "with string :action copies existing action" do
151
+ complete(:method=>"Date.blah", :action=>"Date.parse")
152
+ tab('Date.blah 0').should == ["03/01", "01/01"]
153
+ end
154
+
155
+ it "doesn't conflict with instance method completion" do
156
+ complete(:method=>'Date#parse') {|e| %w{01 02 23}}
157
+ tab('Date.today.parse 0').should == %w{01 02}
158
+ end
159
+ end
160
+
161
+ describe "multi argument method" do
162
+ before { complete(:method=>'Array#index') {|e| %w{ab cd ef ad e,e} } }
163
+
164
+ it "completes second argument" do
165
+ tab('[].index ab, a').should == %w{ab ad}
166
+ end
167
+
168
+ it "completes second argument as a symbol" do
169
+ tab('[].index ab, :a').should == %w{:ab :ad}
170
+ end
171
+
172
+ it "completes second argument as a string" do
173
+ tab('[].index \'ab\' , "a').should == %w{ab ad}
174
+ end
175
+
176
+ it "completes third argument" do
177
+ tab('[].index ab, zz, c').should == %w{cd}
178
+ end
179
+
180
+ it "completes all arguments after comma" do
181
+ tab('[].index ab,').should == %w{ab cd ef ad e,e}
182
+ tab('[].index ab, ').should == %w{ab cd ef ad e,e}
183
+ end
184
+
185
+ it "completes based on argument number" do
186
+ complete(:method=>'blah') {|e| e.argument == 2 ? %w{ab ad} : %w{ab ae} }
187
+ tab('blah a').should == %w{ab ae}
188
+ tab('blah zz, a').should == %w{ab ad}
189
+ end
190
+
191
+ it "can't handle a completion with a comma as a completion" do
192
+ tab('[].index e,').should == %w{ab cd ef ad e,e}
193
+ end
194
+ end
195
+
196
+ describe "top-level method" do
197
+ before { complete(:method=>'cool') {|e| %w{ab cd ef ad} } }
198
+
199
+ it "completes" do
200
+ complete(:method=>'cool?') {|e| [] }
201
+ tab('cool c').should == %w{cd}
202
+ end
203
+
204
+ it "completes after valid ruby" do
205
+ tab('nil; cool a').should == %w{ab ad}
206
+ end
207
+ end
208
+
209
+ it "with :methods completes for multiple instance methods" do
210
+ complete(:methods=>%w{cool ls}) {|e| %w{ab cd ef ad}}
211
+ tab("cool a").should == %w{ab ad}
212
+ tab("ls c").should == %w{cd}
213
+ end
214
+
215
+ it "with :methods completes for instance and class methods" do
216
+ complete(:methods=>%w{String#include? String.new}) {|e| %w{ab cd ef ad}}
217
+ tab("'blah'.include? a").should == %w{ab ad}
218
+ tab("String.new a").should == %w{ab ad}
219
+ end
220
+
221
+ it "with :search completes" do
222
+ complete(:method=>"blah", :search=>:anywhere) { %w{abc bcd cde} }
223
+ tab('blah bc').should == ['abc', 'bcd']
224
+ end
225
+
226
+ describe "with :class" do
227
+ it "completes for instance methods" do
228
+ complete(:method=>"blong", :class=>"Array#") { %w{ab cd ef ad} }
229
+ tab('[].blong a').should == %w{ab ad}
230
+ complete(:methods=>["bling"], :class=>"Array#") { %w{ab cd ef ad} }
231
+ tab('[].bling a').should == %w{ab ad}
232
+ end
233
+
234
+ it "that is ambiguous defaults to instance methods" do
235
+ complete(:method=>"blong", :class=>"Array") { %w{ab cd ef ad} }
236
+ tab('[].blong a').should == %w{ab ad}
237
+ end
238
+
239
+ it "completes for class methods" do
240
+ complete(:method=>"blong", :class=>"Array.") { %w{ab cd ef ad} }
241
+ tab('Array.blong a').should == %w{ab ad}
242
+ complete(:methods=>["bling"], :class=>"Array.") { %w{ab cd ef ad} }
243
+ tab('Array.bling a').should == %w{ab ad}
244
+ end
245
+ end
246
+ end