pry 0.10.2-i386-mingw32 → 1.0.0.pre1-i386-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. data/.document +2 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +21 -0
  4. data/.yardopts +3 -0
  5. data/CHANGELOG +503 -0
  6. data/CONTRIBUTORS +55 -0
  7. data/Gemfile +9 -0
  8. data/Guardfile +62 -0
  9. data/LICENSE +2 -2
  10. data/{README.md → README.markdown} +31 -37
  11. data/Rakefile +144 -0
  12. data/TODO +117 -0
  13. data/lib/pry.rb +146 -33
  14. data/lib/pry/cli.rb +13 -35
  15. data/lib/pry/code.rb +63 -24
  16. data/lib/pry/code/loc.rb +2 -2
  17. data/lib/pry/code_object.rb +21 -40
  18. data/lib/pry/command.rb +6 -9
  19. data/lib/pry/command_set.rb +37 -80
  20. data/lib/pry/commands.rb +1 -1
  21. data/lib/pry/commands/amend_line.rb +1 -1
  22. data/lib/pry/commands/bang.rb +1 -1
  23. data/lib/pry/commands/cat.rb +2 -11
  24. data/lib/pry/commands/cat/abstract_formatter.rb +1 -1
  25. data/lib/pry/commands/cat/exception_formatter.rb +7 -6
  26. data/lib/pry/commands/cat/file_formatter.rb +32 -15
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  28. data/lib/pry/commands/cd.rb +3 -14
  29. data/lib/pry/commands/code_collector.rb +4 -4
  30. data/lib/pry/commands/easter_eggs.rb +3 -3
  31. data/lib/pry/commands/edit.rb +22 -10
  32. data/lib/pry/commands/edit/exception_patcher.rb +1 -1
  33. data/lib/pry/commands/edit/file_and_line_locator.rb +2 -0
  34. data/lib/pry/{method/patcher.rb → commands/edit/method_patcher.rb} +37 -40
  35. data/lib/pry/commands/find_method.rb +22 -16
  36. data/lib/pry/commands/gem_install.rb +2 -5
  37. data/lib/pry/commands/gem_open.rb +1 -1
  38. data/lib/pry/commands/gist.rb +11 -10
  39. data/lib/pry/commands/help.rb +14 -14
  40. data/lib/pry/commands/hist.rb +5 -24
  41. data/lib/pry/commands/ls.rb +287 -56
  42. data/lib/pry/commands/play.rb +10 -44
  43. data/lib/pry/commands/pry_backtrace.rb +2 -1
  44. data/lib/pry/commands/raise_up.rb +1 -1
  45. data/lib/pry/commands/reload_code.rb +15 -31
  46. data/lib/pry/commands/ri.rb +3 -7
  47. data/lib/pry/commands/shell_command.rb +12 -17
  48. data/lib/pry/commands/shell_mode.rb +2 -2
  49. data/lib/pry/commands/show_doc.rb +0 -5
  50. data/lib/pry/commands/show_info.rb +10 -11
  51. data/lib/pry/commands/show_source.rb +3 -15
  52. data/lib/pry/commands/simple_prompt.rb +1 -1
  53. data/lib/pry/commands/toggle_color.rb +4 -8
  54. data/lib/pry/commands/whereami.rb +10 -18
  55. data/lib/pry/completion.rb +293 -0
  56. data/lib/pry/config.rb +233 -20
  57. data/lib/pry/core_extensions.rb +19 -29
  58. data/lib/pry/custom_completions.rb +6 -0
  59. data/lib/pry/editor.rb +103 -109
  60. data/lib/pry/helpers/base_helpers.rb +109 -22
  61. data/lib/pry/helpers/command_helpers.rb +8 -10
  62. data/lib/pry/helpers/documentation_helpers.rb +2 -1
  63. data/lib/pry/helpers/text.rb +5 -4
  64. data/lib/pry/history.rb +10 -21
  65. data/lib/pry/history_array.rb +0 -5
  66. data/lib/pry/hooks.rb +29 -9
  67. data/lib/pry/indent.rb +10 -5
  68. data/lib/pry/method.rb +86 -81
  69. data/lib/pry/method/weird_method_locator.rb +2 -4
  70. data/lib/pry/module_candidate.rb +14 -5
  71. data/lib/pry/pager.rb +48 -193
  72. data/lib/pry/plugins.rb +2 -2
  73. data/lib/pry/pry_class.rb +193 -104
  74. data/lib/pry/pry_instance.rb +154 -152
  75. data/lib/pry/rbx_method.rb +13 -0
  76. data/lib/pry/rbx_path.rb +1 -1
  77. data/lib/pry/repl.rb +14 -17
  78. data/lib/pry/repl_file_loader.rb +3 -8
  79. data/lib/pry/rubygem.rb +3 -3
  80. data/lib/pry/terminal.rb +3 -4
  81. data/lib/pry/test/helper.rb +11 -6
  82. data/lib/pry/version.rb +1 -1
  83. data/lib/pry/wrapped_module.rb +56 -49
  84. data/man/pry.1 +195 -0
  85. data/man/pry.1.html +204 -0
  86. data/man/pry.1.ronn +141 -0
  87. data/pry.gemspec +31 -0
  88. data/spec/Procfile +3 -0
  89. data/spec/cli_spec.rb +78 -0
  90. data/spec/code_object_spec.rb +277 -0
  91. data/spec/code_spec.rb +219 -0
  92. data/spec/command_helpers_spec.rb +29 -0
  93. data/spec/command_integration_spec.rb +562 -0
  94. data/spec/command_set_spec.rb +627 -0
  95. data/spec/command_spec.rb +821 -0
  96. data/spec/commands/amend_line_spec.rb +247 -0
  97. data/spec/commands/bang_spec.rb +18 -0
  98. data/spec/commands/cat_spec.rb +164 -0
  99. data/spec/commands/cd_spec.rb +250 -0
  100. data/spec/commands/disable_pry_spec.rb +25 -0
  101. data/spec/commands/edit_spec.rb +725 -0
  102. data/spec/commands/exit_all_spec.rb +27 -0
  103. data/spec/commands/exit_program_spec.rb +19 -0
  104. data/spec/commands/exit_spec.rb +28 -0
  105. data/spec/commands/find_method_spec.rb +70 -0
  106. data/spec/commands/gem_list_spec.rb +26 -0
  107. data/spec/commands/gist_spec.rb +79 -0
  108. data/spec/commands/help_spec.rb +56 -0
  109. data/spec/commands/hist_spec.rb +172 -0
  110. data/spec/commands/jump_to_spec.rb +15 -0
  111. data/spec/commands/ls_spec.rb +189 -0
  112. data/spec/commands/play_spec.rb +136 -0
  113. data/spec/commands/raise_up_spec.rb +56 -0
  114. data/spec/commands/save_file_spec.rb +177 -0
  115. data/spec/commands/show_doc_spec.rb +488 -0
  116. data/spec/commands/show_input_spec.rb +17 -0
  117. data/spec/commands/show_source_spec.rb +760 -0
  118. data/spec/commands/whereami_spec.rb +203 -0
  119. data/spec/completion_spec.rb +221 -0
  120. data/spec/control_d_handler_spec.rb +62 -0
  121. data/spec/documentation_helper_spec.rb +73 -0
  122. data/spec/editor_spec.rb +79 -0
  123. data/spec/exception_whitelist_spec.rb +21 -0
  124. data/spec/fixtures/candidate_helper1.rb +11 -0
  125. data/spec/fixtures/candidate_helper2.rb +8 -0
  126. data/spec/fixtures/example.erb +5 -0
  127. data/spec/fixtures/example_nesting.rb +33 -0
  128. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  129. data/spec/fixtures/testlinkrc +2 -0
  130. data/spec/fixtures/testrc +2 -0
  131. data/spec/fixtures/testrcbad +2 -0
  132. data/spec/fixtures/whereami_helper.rb +6 -0
  133. data/spec/helper.rb +35 -0
  134. data/spec/helpers/bacon.rb +86 -0
  135. data/spec/helpers/mock_pry.rb +44 -0
  136. data/spec/helpers/repl_tester.rb +112 -0
  137. data/spec/helpers/table_spec.rb +105 -0
  138. data/spec/history_array_spec.rb +67 -0
  139. data/spec/hooks_spec.rb +522 -0
  140. data/spec/indent_spec.rb +301 -0
  141. data/spec/method_spec.rb +482 -0
  142. data/spec/prompt_spec.rb +61 -0
  143. data/spec/pry_defaults_spec.rb +420 -0
  144. data/spec/pry_history_spec.rb +69 -0
  145. data/spec/pry_output_spec.rb +95 -0
  146. data/spec/pry_repl_spec.rb +86 -0
  147. data/spec/pry_spec.rb +394 -0
  148. data/spec/pryrc_spec.rb +97 -0
  149. data/spec/run_command_spec.rb +25 -0
  150. data/spec/sticky_locals_spec.rb +147 -0
  151. data/spec/syntax_checking_spec.rb +81 -0
  152. data/spec/wrapped_module_spec.rb +261 -0
  153. data/wiki/Customizing-pry.md +397 -0
  154. data/wiki/Home.md +4 -0
  155. metadata +272 -61
  156. checksums.yaml +0 -7
  157. data/CHANGELOG.md +0 -714
  158. data/lib/pry/code/code_file.rb +0 -103
  159. data/lib/pry/color_printer.rb +0 -55
  160. data/lib/pry/commands/change_inspector.rb +0 -27
  161. data/lib/pry/commands/change_prompt.rb +0 -26
  162. data/lib/pry/commands/list_inspectors.rb +0 -35
  163. data/lib/pry/commands/list_prompts.rb +0 -35
  164. data/lib/pry/commands/ls/constants.rb +0 -47
  165. data/lib/pry/commands/ls/formatter.rb +0 -49
  166. data/lib/pry/commands/ls/globals.rb +0 -48
  167. data/lib/pry/commands/ls/grep.rb +0 -21
  168. data/lib/pry/commands/ls/instance_vars.rb +0 -39
  169. data/lib/pry/commands/ls/interrogatable.rb +0 -18
  170. data/lib/pry/commands/ls/jruby_hacks.rb +0 -49
  171. data/lib/pry/commands/ls/local_names.rb +0 -35
  172. data/lib/pry/commands/ls/local_vars.rb +0 -39
  173. data/lib/pry/commands/ls/ls_entity.rb +0 -70
  174. data/lib/pry/commands/ls/methods.rb +0 -57
  175. data/lib/pry/commands/ls/methods_helper.rb +0 -46
  176. data/lib/pry/commands/ls/self_methods.rb +0 -32
  177. data/lib/pry/commands/watch_expression.rb +0 -105
  178. data/lib/pry/commands/watch_expression/expression.rb +0 -38
  179. data/lib/pry/config/behavior.rb +0 -139
  180. data/lib/pry/config/convenience.rb +0 -25
  181. data/lib/pry/config/default.rb +0 -161
  182. data/lib/pry/exceptions.rb +0 -78
  183. data/lib/pry/input_completer.rb +0 -242
  184. data/lib/pry/input_lock.rb +0 -132
  185. data/lib/pry/inspector.rb +0 -27
  186. data/lib/pry/last_exception.rb +0 -61
  187. data/lib/pry/object_path.rb +0 -82
  188. data/lib/pry/output.rb +0 -50
  189. data/lib/pry/prompt.rb +0 -26
@@ -0,0 +1,105 @@
1
+ require 'helper'
2
+
3
+ describe 'Formatting Table' do
4
+ it 'knows about colorized fitting' do
5
+ t = Pry::Helpers::Table.new %w(hihi), :column_count => 1
6
+ t.fits_on_line?(4).should == true
7
+ t.items = []
8
+ t.fits_on_line?(4).should == true
9
+
10
+ t.items = %w(hi hi)
11
+ t.fits_on_line?(4).should == true
12
+ t.column_count = 2
13
+ t.fits_on_line?(4).should == false
14
+
15
+ t.items = %w(
16
+ a ccc
17
+ bb dddd
18
+ ).sort
19
+ t.fits_on_line?(8).should == true
20
+ t.fits_on_line?(7).should == false
21
+ end
22
+
23
+ describe 'formatting - should order downward and wrap to columns' do
24
+ FAKE_COLUMNS = 62
25
+ def try_round_trip(expected)
26
+ things = expected.split(/\s+/).sort
27
+ actual = Pry::Helpers.tablify(things, FAKE_COLUMNS).to_s.strip
28
+ [expected, actual].each{|e| e.gsub! /\s+$/, ''}
29
+ if actual != expected
30
+ bar = '-'*25
31
+ puts \
32
+ bar+'expected'+bar,
33
+ expected,
34
+ bar+'actual'+bar,
35
+ actual
36
+ end
37
+ actual.should == expected
38
+ end
39
+
40
+ it 'should handle a tiny case' do
41
+ try_round_trip(<<-eot)
42
+ asdf asfddd fdass
43
+ eot
44
+ end
45
+
46
+ it 'should handle the basic case' do
47
+ try_round_trip(<<-eot)
48
+ aadd ddasffssdad sdsaadaasd ssfasaafssd
49
+ adassdfffaasds f sdsfasddasfds ssssdaa
50
+ assfsafsfsds fsasa ssdsssafsdasdf
51
+ eot
52
+ end
53
+
54
+ it 'should handle... another basic case' do
55
+ try_round_trip(<<-EOT)
56
+ aaad dasaasffaasf fdasfdfss safdfdddsasd
57
+ aaadfasassdfff ddadadassasdf fddsasadfssdss sasf
58
+ aaddaafaf dddasaaaaaa fdsasad sddsa
59
+ aas dfsddffdddsdfd ff sddsfsaa
60
+ adasadfaaffds dsfafdsfdfssda ffadsfafsaafa ss
61
+ asddaadaaadfdd dssdss ffssfsfafaadss ssas
62
+ asdsdaa faadf fsddfff ssdfssff
63
+ asfadsssaaad fasfaafdssd s
64
+ EOT
65
+ end
66
+
67
+ it 'should handle colors' do
68
+ try_round_trip(<<-EOT)
69
+ \e[31maaaaaaaaaa\e[0m \e[31mccccccccccccccccccccccccccccc\e[0m
70
+ \e[31mbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\e[0m \e[31mddddddddddddd\e[0m
71
+ EOT
72
+ end
73
+
74
+ it 'should handle empty input' do
75
+ try_round_trip('')
76
+ end
77
+
78
+ it 'should handle one-token input' do
79
+ try_round_trip('asdf')
80
+ end
81
+ end
82
+
83
+ describe 'line length is smaller than the length of the longest word' do
84
+ before do
85
+ element = 'swizzle'
86
+ @elem_len = element.length
87
+ @out = [element, 'crime', 'fun']
88
+ end
89
+
90
+ it 'should not raise error' do
91
+ should.not.raise(FloatDomainError) {
92
+ Pry::Helpers.tablify(@out, @elem_len - 1)
93
+ }
94
+ end
95
+
96
+ it 'should format output as one column' do
97
+ table = Pry::Helpers.tablify(@out, @elem_len - 1).to_s
98
+ table.should == "swizzle\ncrime \nfun "
99
+ end
100
+ end
101
+
102
+ describe 'decide between one-line or indented output' do
103
+ Pry::Helpers.tablify_or_one_line('head', %w(ing)).should == 'head: ing'
104
+ end
105
+ end
@@ -0,0 +1,67 @@
1
+ require 'helper'
2
+
3
+ describe Pry::HistoryArray do
4
+ before do
5
+ @array = Pry::HistoryArray.new 10
6
+ @populated = @array.dup << 1 << 2 << 3 << 4
7
+ end
8
+
9
+ it 'should have a maximum size specifed at creation time' do
10
+ @array.max_size.should == 10
11
+ end
12
+
13
+ it 'should be able to be added objects to' do
14
+ @populated.size.should == 4
15
+ @populated.to_a.should == [1, 2, 3, 4]
16
+ end
17
+
18
+ it 'should be able to access single elements' do
19
+ @populated[2].should == 3
20
+ end
21
+
22
+ it 'should be able to access negative indices' do
23
+ @populated[-1].should == 4
24
+ end
25
+
26
+ it 'should be able to access ranges' do
27
+ @populated[1..2].should == [2, 3]
28
+ end
29
+
30
+ it 'should be able to access ranges starting from a negative index' do
31
+ @populated[-2..3].should == [3, 4]
32
+ end
33
+
34
+ it 'should be able to access ranges ending at a negative index' do
35
+ @populated[2..-1].should == [3, 4]
36
+ end
37
+
38
+ it 'should be able to access ranges using only negative indices' do
39
+ @populated[-2..-1].should == [3, 4]
40
+ end
41
+
42
+ it 'should be able to use range where end is excluded' do
43
+ @populated[-2...-1].should == [3]
44
+ end
45
+
46
+ it 'should be able to access slices using a size' do
47
+ @populated[-3, 2].should == [2, 3]
48
+ end
49
+
50
+ it 'should remove older entries' do
51
+ 11.times { |n| @array << n }
52
+
53
+ @array[0].should == nil
54
+ @array[1].should == 1
55
+ @array[10].should == 10
56
+ end
57
+
58
+ it 'should not be larger than specified maximum size' do
59
+ 12.times { |n| @array << n }
60
+ @array.entries.compact.size.should == 10
61
+ end
62
+
63
+ it 'should pop!' do
64
+ @populated.pop!
65
+ @populated.to_a.should == [1, 2, 3]
66
+ end
67
+ end
@@ -0,0 +1,522 @@
1
+ require 'helper'
2
+
3
+ describe Pry::Hooks do
4
+ before do
5
+ @hooks = Pry::Hooks.new
6
+ end
7
+
8
+ describe "adding a new hook" do
9
+ it 'should not execute hook while adding it' do
10
+ run = false
11
+ @hooks.add_hook(:test_hook, :my_name) { run = true }
12
+ run.should == false
13
+ end
14
+
15
+ it 'should not allow adding of a hook with a duplicate name' do
16
+ @hooks.add_hook(:test_hook, :my_name) {}
17
+
18
+ lambda { @hooks.add_hook(:test_hook, :my_name) {} }.should.raise ArgumentError
19
+ end
20
+
21
+ it 'should create a new hook with a block' do
22
+ @hooks.add_hook(:test_hook, :my_name) { }
23
+ @hooks.hook_count(:test_hook).should == 1
24
+ end
25
+
26
+ it 'should create a new hook with a callable' do
27
+ @hooks.add_hook(:test_hook, :my_name, proc { })
28
+ @hooks.hook_count(:test_hook).should == 1
29
+ end
30
+
31
+ it 'should use block if given both block and callable' do
32
+ run = false
33
+ foo = false
34
+ @hooks.add_hook(:test_hook, :my_name, proc { foo = true }) { run = true }
35
+ @hooks.hook_count(:test_hook).should == 1
36
+ @hooks.exec_hook(:test_hook)
37
+ run.should == true
38
+ foo.should == false
39
+ end
40
+
41
+ it 'should raise if not given a block or any other object' do
42
+ lambda { @hooks.add_hook(:test_hook, :my_name) }.should.raise ArgumentError
43
+ end
44
+
45
+ it 'should create multiple hooks for an event' do
46
+ @hooks.add_hook(:test_hook, :my_name) {}
47
+ @hooks.add_hook(:test_hook, :my_name2) {}
48
+ @hooks.hook_count(:test_hook).should == 2
49
+ end
50
+
51
+ it 'should return a count of 0 for an empty hook' do
52
+ @hooks.hook_count(:test_hook).should == 0
53
+ end
54
+ end
55
+
56
+ describe "Pry::Hooks#merge" do
57
+ describe "merge!" do
58
+ it 'should merge in the Pry::Hooks' do
59
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
60
+ h2 = Pry::Hooks.new
61
+
62
+ h2.merge!(h1)
63
+ h2.get_hook(:test_hook, :testing).should == h1.get_hook(:test_hook, :testing)
64
+ end
65
+
66
+ it 'should not share merged elements with original' do
67
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
68
+ h2 = Pry::Hooks.new
69
+
70
+ h2.merge!(h1)
71
+ h2.add_hook(:test_hook, :testing2) {}
72
+ h2.get_hook(:test_hook, :testing2).should.not == h1.get_hook(:test_hook, :testing2)
73
+ end
74
+
75
+ it 'should NOT overwrite hooks belonging to shared event in receiver' do
76
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
77
+ callable = proc {}
78
+ h2 = Pry::Hooks.new.add_hook(:test_hook, :testing2, callable)
79
+
80
+ h2.merge!(h1)
81
+ h2.get_hook(:test_hook, :testing2).should == callable
82
+ end
83
+
84
+ it 'should overwrite identical hook in receiver' do
85
+ callable1 = proc { :one }
86
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing, callable1)
87
+ callable2 = proc { :two }
88
+ h2 = Pry::Hooks.new.add_hook(:test_hook, :testing, callable2)
89
+
90
+ h2.merge!(h1)
91
+ h2.get_hook(:test_hook, :testing).should == callable1
92
+ h2.hook_count(:test_hook).should == 1
93
+ end
94
+
95
+ it 'should preserve hook order' do
96
+ name = ""
97
+ h1 = Pry::Hooks.new
98
+ h1.add_hook(:test_hook, :testing3) { name << "h" }
99
+ h1.add_hook(:test_hook, :testing4) { name << "n" }
100
+
101
+ h2 = Pry::Hooks.new
102
+ h2.add_hook(:test_hook, :testing1) { name << "j" }
103
+ h2.add_hook(:test_hook, :testing2) { name << "o" }
104
+
105
+ h2.merge!(h1)
106
+ h2.exec_hook(:test_hook)
107
+
108
+ name.should == "john"
109
+ end
110
+
111
+ describe "merge" do
112
+ it 'should return a fresh, independent instance' do
113
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
114
+ h2 = Pry::Hooks.new
115
+
116
+ h3 = h2.merge(h1)
117
+ h3.should.not == h1
118
+ h3.should.not == h2
119
+ end
120
+
121
+ it 'should contain hooks from original instance' do
122
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
123
+ h2 = Pry::Hooks.new.add_hook(:test_hook2, :testing) {}
124
+
125
+ h3 = h2.merge(h1)
126
+ h3.get_hook(:test_hook, :testing).should == h1.get_hook(:test_hook, :testing)
127
+ h3.get_hook(:test_hook2, :testing).should == h2.get_hook(:test_hook2, :testing)
128
+ end
129
+
130
+ it 'should not affect original instances when new hooks are added' do
131
+ h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {}
132
+ h2 = Pry::Hooks.new.add_hook(:test_hook2, :testing) {}
133
+
134
+ h3 = h2.merge(h1)
135
+ h3.add_hook(:test_hook3, :testing) {}
136
+
137
+ h1.get_hook(:test_hook3, :testing).should == nil
138
+ h2.get_hook(:test_hook3, :testing).should == nil
139
+ end
140
+ end
141
+
142
+ end
143
+ end
144
+
145
+ describe "dupping a Pry::Hooks instance" do
146
+ it 'should share hooks with original' do
147
+ @hooks.add_hook(:test_hook, :testing) do
148
+ :none_such
149
+ end
150
+
151
+ hooks_dup = @hooks.dup
152
+ hooks_dup.get_hook(:test_hook, :testing).should == @hooks.get_hook(:test_hook, :testing)
153
+ end
154
+
155
+ it 'adding a new event to dupped instance should not affect original' do
156
+ @hooks.add_hook(:test_hook, :testing) { :none_such }
157
+ hooks_dup = @hooks.dup
158
+
159
+ hooks_dup.add_hook(:other_test_hook, :testing) { :okay_man }
160
+
161
+ hooks_dup.get_hook(:other_test_hook, :testing).should.not == @hooks.get_hook(:other_test_hook, :testing)
162
+ end
163
+
164
+ it 'adding a new hook to dupped instance should not affect original' do
165
+ @hooks.add_hook(:test_hook, :testing) { :none_such }
166
+ hooks_dup = @hooks.dup
167
+
168
+ hooks_dup.add_hook(:test_hook, :testing2) { :okay_man }
169
+
170
+ hooks_dup.get_hook(:test_hook, :testing2).should.not == @hooks.get_hook(:test_hook, :testing2)
171
+ end
172
+
173
+ end
174
+
175
+ describe "getting hooks" do
176
+ describe "get_hook" do
177
+ it 'should return the correct requested hook' do
178
+ run = false
179
+ fun = false
180
+ @hooks.add_hook(:test_hook, :my_name) { run = true }
181
+ @hooks.add_hook(:test_hook, :my_name2) { fun = true }
182
+ @hooks.get_hook(:test_hook, :my_name).call
183
+ run.should == true
184
+ fun.should == false
185
+ end
186
+
187
+ it 'should return nil if hook does not exist' do
188
+ @hooks.get_hook(:test_hook, :my_name).should == nil
189
+ end
190
+ end
191
+
192
+ describe "get_hooks" do
193
+ it 'should return a hash of hook names/hook functions for an event' do
194
+ hook1 = proc { 1 }
195
+ hook2 = proc { 2 }
196
+ @hooks.add_hook(:test_hook, :my_name1, hook1)
197
+ @hooks.add_hook(:test_hook, :my_name2, hook2)
198
+ hash = @hooks.get_hooks(:test_hook)
199
+ hash.size.should == 2
200
+ hash[:my_name1].should == hook1
201
+ hash[:my_name2].should == hook2
202
+ end
203
+
204
+ it 'should return an empty hash if no hooks defined' do
205
+ @hooks.get_hooks(:test_hook).should == {}
206
+ end
207
+ end
208
+ end
209
+
210
+ describe "clearing all hooks for an event" do
211
+ it 'should clear all hooks' do
212
+ @hooks.add_hook(:test_hook, :my_name) { }
213
+ @hooks.add_hook(:test_hook, :my_name2) { }
214
+ @hooks.add_hook(:test_hook, :my_name3) { }
215
+ @hooks.clear(:test_hook)
216
+ @hooks.hook_count(:test_hook).should == 0
217
+ end
218
+ end
219
+
220
+ describe "deleting a hook" do
221
+ it 'should successfully delete a hook' do
222
+ @hooks.add_hook(:test_hook, :my_name) {}
223
+ @hooks.delete_hook(:test_hook, :my_name)
224
+ @hooks.hook_count(:test_hook).should == 0
225
+ end
226
+
227
+ it 'should return the deleted hook' do
228
+ run = false
229
+ @hooks.add_hook(:test_hook, :my_name) { run = true }
230
+ @hooks.delete_hook(:test_hook, :my_name).call
231
+ run.should == true
232
+ end
233
+
234
+ it 'should return nil if hook does not exist' do
235
+ @hooks.delete_hook(:test_hook, :my_name).should == nil
236
+ end
237
+ end
238
+
239
+ describe "executing a hook" do
240
+ it 'should execute block hook' do
241
+ run = false
242
+ @hooks.add_hook(:test_hook, :my_name) { run = true }
243
+ @hooks.exec_hook(:test_hook)
244
+ run.should == true
245
+ end
246
+
247
+ it 'should execute proc hook' do
248
+ run = false
249
+ @hooks.add_hook(:test_hook, :my_name, proc { run = true })
250
+ @hooks.exec_hook(:test_hook)
251
+ run.should == true
252
+ end
253
+
254
+ it 'should execute a general callable hook' do
255
+ callable = Object.new.tap do |obj|
256
+ obj.instance_variable_set(:@test_var, nil)
257
+ class << obj
258
+ attr_accessor :test_var
259
+ def call() @test_var = true; end
260
+ end
261
+ end
262
+
263
+ @hooks.add_hook(:test_hook, :my_name, callable)
264
+ @hooks.exec_hook(:test_hook)
265
+ callable.test_var.should == true
266
+ end
267
+
268
+ it 'should execute all hooks for an event if more than one is defined' do
269
+ x = nil
270
+ y = nil
271
+ @hooks.add_hook(:test_hook, :my_name1) { y = true }
272
+ @hooks.add_hook(:test_hook, :my_name2) { x = true }
273
+ @hooks.exec_hook(:test_hook)
274
+ x.should == true
275
+ y.should == true
276
+ end
277
+
278
+ it 'should execute hooks in order' do
279
+ array = []
280
+ @hooks.add_hook(:test_hook, :my_name1) { array << 1 }
281
+ @hooks.add_hook(:test_hook, :my_name2) { array << 2 }
282
+ @hooks.add_hook(:test_hook, :my_name3) { array << 3 }
283
+ @hooks.exec_hook(:test_hook)
284
+ array.should == [1, 2, 3]
285
+ end
286
+
287
+ it 'return value of exec_hook should be that of last executed hook' do
288
+ @hooks.add_hook(:test_hook, :my_name1) { 1 }
289
+ @hooks.add_hook(:test_hook, :my_name2) { 2 }
290
+ @hooks.add_hook(:test_hook, :my_name3) { 3 }
291
+ @hooks.exec_hook(:test_hook).should == 3
292
+ end
293
+
294
+ it 'should add exceptions to the errors array' do
295
+ @hooks.add_hook(:test_hook, :foo1) { raise 'one' }
296
+ @hooks.add_hook(:test_hook, :foo2) { raise 'two' }
297
+ @hooks.add_hook(:test_hook, :foo3) { raise 'three' }
298
+ @hooks.exec_hook(:test_hook)
299
+ @hooks.errors.map(&:message).should == ['one', 'two', 'three']
300
+ end
301
+
302
+ it 'should return the last exception raised as the return value' do
303
+ @hooks.add_hook(:test_hook, :foo1) { raise 'one' }
304
+ @hooks.add_hook(:test_hook, :foo2) { raise 'two' }
305
+ @hooks.add_hook(:test_hook, :foo3) { raise 'three' }
306
+ @hooks.exec_hook(:test_hook).should == @hooks.errors.last
307
+ end
308
+ end
309
+
310
+ describe "integration tests" do
311
+ describe "when_started hook" do
312
+ it 'should yield options to the hook' do
313
+ options = nil
314
+ Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| options = opt }
315
+
316
+ redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do
317
+ Pry.start binding, :hello => :baby
318
+ end
319
+
320
+ options[:hello].should == :baby
321
+
322
+ Pry.config.hooks.delete_hook(:when_started, :test_hook)
323
+ end
324
+
325
+ describe "target" do
326
+
327
+ it 'should yield the target, as a binding ' do
328
+ b = nil
329
+ Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| b = target }
330
+
331
+ redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do
332
+ Pry.start 5, :hello => :baby
333
+ end
334
+
335
+ b.is_a?(Binding).should == true
336
+ Pry.config.hooks.delete_hook(:when_started, :test_hook)
337
+ end
338
+
339
+ it 'should yield the target to the hook' do
340
+ b = nil
341
+ Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| b = target }
342
+
343
+ redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do
344
+ Pry.start 5, :hello => :baby
345
+ end
346
+
347
+ b.eval('self').should == 5
348
+ Pry.config.hooks.delete_hook(:when_started, :test_hook)
349
+ end
350
+ end
351
+
352
+ it 'should allow overriding of target (and binding_stack)' do
353
+ options = nil
354
+ o = Object.new
355
+ class << o; attr_accessor :value; end
356
+
357
+ Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _pry_| _pry_.binding_stack = [Pry.binding_for(o)] }
358
+
359
+ redirect_pry_io(InputTester.new("@value = true","exit-all")) do
360
+ Pry.start binding, :hello => :baby
361
+ end
362
+
363
+ o.value.should == true
364
+ Pry.config.hooks.delete_hook(:when_started, :test_hook)
365
+ end
366
+
367
+ end
368
+
369
+ describe "after_session hook" do
370
+ it 'should always run, even if uncaught exception bubbles out of repl' do
371
+ o = OpenStruct.new
372
+ o.great_escape = Class.new(StandardError)
373
+
374
+ old_ew = Pry.config.exception_whitelist
375
+ Pry.config.exception_whitelist << o.great_escape
376
+
377
+ array = [1, 2, 3, 4, 5]
378
+
379
+ begin
380
+ redirect_pry_io(StringIO.new("raise great_escape"), out=StringIO.new) do
381
+ Pry.start o, :hooks => Pry::Hooks.new.add_hook(:after_session, :cleanup) { array = nil }
382
+ end
383
+ rescue => ex
384
+ exception = ex
385
+ end
386
+
387
+ # ensure that an exception really was raised and it broke out
388
+ # of the repl
389
+ exception.is_a?(o.great_escape).should == true
390
+
391
+ # check that after_session hook ran
392
+ array.should == nil
393
+
394
+ # cleanup after test
395
+ Pry.config.exception_whitelist = old_ew
396
+ end
397
+
398
+ describe "before_eval hook" do
399
+ describe "modifying input code" do
400
+ it 'should replace input code with code determined by hook' do
401
+ hooks = Pry::Hooks.new.add_hook(:before_eval, :quirk) { |code, pry| code.replace(":little_duck") }
402
+ redirect_pry_io(InputTester.new(":jemima", "exit-all"), out = StringIO.new) do
403
+ Pry.start(self, :hooks => hooks)
404
+ end
405
+ out.string.should =~ /little_duck/
406
+ out.string.should.not =~ /jemima/
407
+ end
408
+
409
+ it 'should not interfere with command processing when replacing input code' do
410
+ commands = Pry::CommandSet.new do
411
+ import_from Pry::Commands, "exit-all"
412
+
413
+ command "how-do-you-like-your-blue-eyed-boy-now-mister-death" do
414
+ output.puts "in hours of bitterness i imagine balls of sapphire, of metal"
415
+ end
416
+ end
417
+
418
+ hooks = Pry::Hooks.new.add_hook(:before_eval, :quirk) { |code, pry| code.replace(":little_duck") }
419
+ redirect_pry_io(InputTester.new("how-do-you-like-your-blue-eyed-boy-now-mister-death", "exit-all"), out = StringIO.new) do
420
+ Pry.start(self, :hooks => hooks, :commands => commands)
421
+ end
422
+ out.string.should =~ /in hours of bitterness i imagine balls of sapphire, of metal/
423
+ out.string.should.not =~ /little_duck/
424
+ end
425
+ end
426
+
427
+ end
428
+
429
+ describe "exceptions" do
430
+ before do
431
+ Pry.config.hooks.add_hook(:after_eval, :baddums){ raise "Baddums" }
432
+ Pry.config.hooks.add_hook(:after_eval, :simbads){ raise "Simbads" }
433
+ end
434
+
435
+ after do
436
+ Pry.config.hooks.delete_hook(:after_eval, :baddums)
437
+ Pry.config.hooks.delete_hook(:after_eval, :simbads)
438
+ end
439
+ it "should not raise exceptions" do
440
+ lambda{
441
+ mock_pry("1", "2", "3")
442
+ }.should.not.raise
443
+ end
444
+
445
+ it "should print out a notice for each exception raised" do
446
+ mock_pry("1").should =~ /after_eval hook failed: RuntimeError: Baddums\n.*after_eval hook failed: RuntimeError: Simbads/m
447
+ end
448
+ end
449
+ end
450
+ end
451
+
452
+ describe "anonymous hooks" do
453
+ it 'should allow adding of hook without a name' do
454
+ @hooks.add_hook(:test_hook, nil) {}
455
+ @hooks.hook_count(:test_hook).should == 1
456
+ end
457
+
458
+ it 'should only allow one anonymous hook to exist' do
459
+ @hooks.add_hook(:test_hook, nil) { }
460
+ @hooks.add_hook(:test_hook, nil) { }
461
+ @hooks.hook_count(:test_hook).should == 1
462
+ end
463
+
464
+ it 'should execute most recently added anonymous hook' do
465
+ x = nil
466
+ y = nil
467
+ @hooks.add_hook(:test_hook, nil) { y = 1 }
468
+ @hooks.add_hook(:test_hook, nil) { x = 2 }
469
+ @hooks.exec_hook(:test_hook)
470
+ y.should == nil
471
+ x.should == 2
472
+ end
473
+ end
474
+
475
+ describe "deprecated hash-based API" do
476
+ after do
477
+ Pry.config.hooks.clear_all if Pry.config.hooks
478
+ end
479
+
480
+ describe "Pry.config.hooks" do
481
+ it 'should allow a hash-assignment' do
482
+ Pry.config.hooks = { :before_session => proc { :hello } }
483
+ Pry.config.hooks.get_hook(:before_session, nil).call.should == :hello
484
+ end
485
+
486
+ describe "Pry.config.hooks[]" do
487
+ it 'should return the only anonymous hook' do
488
+ Pry.config.hooks = { :before_session => proc { :hello } }
489
+ Pry.config.hooks[:before_session].call.should == :hello
490
+ end
491
+
492
+ it 'should add an anonymous hook when using Pry.config.hooks[]=' do
493
+ Pry.config.hooks[:before_session] = proc { :bing }
494
+ Pry.config.hooks.hook_count(:before_session).should == 1
495
+ end
496
+
497
+ it 'should add overwrite previous anonymous hooks with new one when calling Pry.config.hooks[]= multiple times' do
498
+ x = nil
499
+ Pry.config.hooks[:before_session] = proc { x = 1 }
500
+ Pry.config.hooks[:before_session] = proc { x = 2 }
501
+
502
+ Pry.config.hooks.exec_hook(:before_session)
503
+ Pry.config.hooks.hook_count(:before_session).should == 1
504
+ x.should == 2
505
+ end
506
+ end
507
+ end
508
+
509
+ describe "Pry.start" do
510
+ it 'should accept a hash for :hooks parameter' do
511
+
512
+ redirect_pry_io(InputTester.new("exit-all"), out=StringIO.new) do
513
+ Pry.start binding, :hooks => { :before_session => proc { |output, _, _| output.puts 'hello friend' } }
514
+ end
515
+
516
+ out.string.should =~ /hello friend/
517
+ end
518
+
519
+ end
520
+ end
521
+
522
+ end