debugger-xml 0.0.1
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.
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +24 -0
- data/Rakefile +10 -0
- data/bin/rdebug-ide +90 -0
- data/debugger-xml.gemspec +25 -0
- data/lib/debugger/printers/texts/xml.yml +121 -0
- data/lib/debugger/printers/xml.rb +195 -0
- data/lib/debugger/xml.rb +3 -0
- data/lib/debugger/xml/extensions/commands/edit.rb +13 -0
- data/lib/debugger/xml/extensions/commands/frame.rb +14 -0
- data/lib/debugger/xml/extensions/commands/help.rb +13 -0
- data/lib/debugger/xml/extensions/commands/info.rb +13 -0
- data/lib/debugger/xml/extensions/commands/irb.rb +13 -0
- data/lib/debugger/xml/extensions/commands/kill.rb +13 -0
- data/lib/debugger/xml/extensions/commands/tmate.rb +13 -0
- data/lib/debugger/xml/extensions/commands/trace.rb +13 -0
- data/lib/debugger/xml/extensions/commands/variables.rb +16 -0
- data/lib/debugger/xml/extensions/debugger.rb +28 -0
- data/lib/debugger/xml/extensions/processor.rb +9 -0
- data/lib/debugger/xml/ide_processor.rb +149 -0
- data/lib/debugger/xml/interface.rb +65 -0
- data/lib/debugger/xml/version.rb +5 -0
- data/test/breakpoints_test.rb +190 -0
- data/test/conditions_test.rb +32 -0
- data/test/continue_test.rb +12 -0
- data/test/display_test.rb +25 -0
- data/test/edit_test.rb +12 -0
- data/test/eval_test.rb +20 -0
- data/test/examples/breakpoint1.rb +15 -0
- data/test/examples/breakpoint2.rb +7 -0
- data/test/examples/conditions.rb +4 -0
- data/test/examples/continue.rb +4 -0
- data/test/examples/display.rb +5 -0
- data/test/examples/edit.rb +3 -0
- data/test/examples/eval.rb +4 -0
- data/test/examples/frame.rb +31 -0
- data/test/examples/help.rb +2 -0
- data/test/examples/info.rb +48 -0
- data/test/examples/irb.rb +6 -0
- data/test/examples/jump.rb +14 -0
- data/test/examples/kill.rb +2 -0
- data/test/examples/method.rb +15 -0
- data/test/examples/reload.rb +6 -0
- data/test/examples/restart.rb +6 -0
- data/test/examples/set.rb +3 -0
- data/test/examples/stepping.rb +21 -0
- data/test/examples/thread.rb +32 -0
- data/test/examples/tmate.rb +10 -0
- data/test/examples/trace.rb +7 -0
- data/test/examples/variables.rb +26 -0
- data/test/examples/variables_xml.rb +31 -0
- data/test/frame_test.rb +29 -0
- data/test/help_test.rb +13 -0
- data/test/ide_control_command_processor_test.rb +62 -0
- data/test/ide_processor_test.rb +118 -0
- data/test/info_test.rb +12 -0
- data/test/irb_test.rb +12 -0
- data/test/jump_test.rb +22 -0
- data/test/kill_test.rb +13 -0
- data/test/method_test.rb +36 -0
- data/test/printers/xml_test.rb +193 -0
- data/test/reload_test.rb +14 -0
- data/test/restart_test.rb +50 -0
- data/test/set_test.rb +12 -0
- data/test/stepping_test.rb +15 -0
- data/test/test_helper.rb +6 -0
- data/test/thread_test.rb +20 -0
- data/test/tmate_test.rb +15 -0
- data/test/trace_test.rb +12 -0
- data/test/variables_test.rb +84 -0
- metadata +253 -0
data/test/frame_test.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Frame Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
it "must print current stack frame when without arguments" do
|
8
|
+
enter 'break 25', 'cont', 'up', 'frame'
|
9
|
+
debug_file('frame')
|
10
|
+
check_output_includes %{<frame no="0" file="#{fullpath('frame')}" line="25" current="false"/>}
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "full path settings" do
|
14
|
+
temporary_change_hash_value(Debugger::Command.settings, :full_path, false)
|
15
|
+
|
16
|
+
it "must display current backtrace with full path = true" do
|
17
|
+
enter 'set fullpath', 'break 25', 'cont', 'where'
|
18
|
+
debug_file('frame')
|
19
|
+
check_output_includes(Regexp.new(
|
20
|
+
"<frames>" +
|
21
|
+
%{<frame no="0" file="#{fullpath('frame')}" line="25" current="true"/>} +
|
22
|
+
%{<frame no="1" file="#{fullpath('frame')}" line="21" current="false"/>} +
|
23
|
+
%{<frame no="2" file="#{fullpath('frame')}" line="17" current="false"/>} +
|
24
|
+
%{<frame no="3" file="#{fullpath('frame')}" line="14" current="false"/>.*} +
|
25
|
+
"</frames>",
|
26
|
+
Regexp::MULTILINE))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/help_test.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Help Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
it "must be unsupported for XML printer" do
|
8
|
+
enter 'help'
|
9
|
+
debug_file 'help'
|
10
|
+
check_output_includes "<error>Unsupported command 'help'</error>", interface.error_queue
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'debugger/xml/ide_processor'
|
3
|
+
|
4
|
+
describe Debugger::Xml::IdeControlCommandProcessor do
|
5
|
+
include TestDsl
|
6
|
+
|
7
|
+
let(:klass) { Debugger::Xml::IdeControlCommandProcessor }
|
8
|
+
let(:interface) { Debugger.handler.interface }
|
9
|
+
let(:file) { fullpath('jump') }
|
10
|
+
let(:context) { stub(frame_binding: stub, stop_reason: nil, thread: stub, thnum: 1, stack_size: 2, dead?: false) }
|
11
|
+
subject { klass.new(interface) }
|
12
|
+
temporary_change_method_value(Debugger, :handler, Debugger::Xml::IdeProcessor.new(TestInterface.new))
|
13
|
+
|
14
|
+
before do
|
15
|
+
Thread.stubs(:stop)
|
16
|
+
Debugger.handler.instance_variable_set("@context", context)
|
17
|
+
Debugger.handler.instance_variable_set("@file", file)
|
18
|
+
Debugger.handler.instance_variable_set("@line", 30)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "must process a control command" do
|
22
|
+
Debugger::AddBreakpoint.any_instance.expects(:execute).with()
|
23
|
+
enter 'break 5'
|
24
|
+
subject.process_commands
|
25
|
+
end
|
26
|
+
|
27
|
+
it "must process several commands, separated by ;" do
|
28
|
+
Debugger::AddBreakpoint.any_instance.expects(:execute).with()
|
29
|
+
Debugger::DeleteBreakpointCommand.any_instance.expects(:execute).with()
|
30
|
+
enter 'break 5; delete 1'
|
31
|
+
subject.process_commands
|
32
|
+
end
|
33
|
+
|
34
|
+
it "must show error if there is no such command" do
|
35
|
+
enter 'bla'
|
36
|
+
subject.process_commands
|
37
|
+
check_output_includes "Unknown command: bla"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "must show error if context is dead" do
|
41
|
+
context.expects(:dead?).returns(true)
|
42
|
+
enter 'step'
|
43
|
+
subject.process_commands
|
44
|
+
check_output_includes "Command is unavailable"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "must show error if no suspended thread" do
|
48
|
+
Debugger.handler.stubs(:at_line?).returns(false)
|
49
|
+
enter 'step'
|
50
|
+
subject.process_commands
|
51
|
+
check_output_includes(
|
52
|
+
"There is no thread suspended at the time and therefore no context to execute 'step'",
|
53
|
+
interface.error_queue)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "must run stopped thread after stepping command" do
|
57
|
+
context.expects(:step).with(1, false)
|
58
|
+
context.thread.expects(:run)
|
59
|
+
enter 'step'
|
60
|
+
subject.process_commands
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'debugger/xml/ide_processor'
|
3
|
+
|
4
|
+
describe Debugger::Xml::IdeProcessor do
|
5
|
+
include TestDsl
|
6
|
+
|
7
|
+
before { Thread.stubs(:stop) }
|
8
|
+
|
9
|
+
let(:klass) { Debugger::Xml::IdeProcessor }
|
10
|
+
let(:interface) { TestInterface.new }
|
11
|
+
let(:breakpoint) { stub }
|
12
|
+
let(:context) { stub(thread: nil, stop_reason: nil, thnum: 1, stack_size: 2) }
|
13
|
+
let(:file) { fullpath('jump') }
|
14
|
+
subject { klass.new(interface) }
|
15
|
+
|
16
|
+
describe "#at_breakpoint" do
|
17
|
+
it "must assign breakpoint to instance variable" do
|
18
|
+
subject.at_breakpoint(context, breakpoint)
|
19
|
+
subject.instance_variable_get("@last_breakpoint").must_equal breakpoint
|
20
|
+
end
|
21
|
+
|
22
|
+
it "must raise error if @last_breakpoint is already assigned" do
|
23
|
+
subject.instance_variable_set("@last_breakpoint", breakpoint)
|
24
|
+
subject.at_breakpoint(context, breakpoint)
|
25
|
+
check_output_includes /INTERNAL ERROR!!!/
|
26
|
+
end
|
27
|
+
|
28
|
+
it "must not print anything" do
|
29
|
+
subject.at_breakpoint(context, breakpoint)
|
30
|
+
interface.must_be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#at_line" do
|
35
|
+
describe "print current position" do
|
36
|
+
it "must print if context is nil" do
|
37
|
+
subject.at_line(nil, file, 30)
|
38
|
+
check_output_includes "#{file}:30"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "must print in xml" do
|
42
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new) do
|
43
|
+
subject.at_line(nil, file, 30)
|
44
|
+
check_output_includes %{<suspended file="#{file}" line="30" threadId="" frames=""/>}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "must print if stop reason is :step" do
|
49
|
+
context.stubs(:stop_reason).returns(:step)
|
50
|
+
subject.at_line(context, file, 30)
|
51
|
+
check_output_includes "#{file}:30"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "must clear instance variables after resuming thread" do
|
55
|
+
subject.instance_variable_set("@line", 10)
|
56
|
+
subject.at_line(context, file, 30)
|
57
|
+
subject.instance_variable_get("@line").must_be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "print breakpoint after at_breakpoint" do
|
61
|
+
before do
|
62
|
+
Debugger.stubs(:breakpoints).returns([breakpoint])
|
63
|
+
Debugger.stubs(:current_context).returns(stub(thnum: 1))
|
64
|
+
subject.instance_variable_set("@last_breakpoint", breakpoint)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "must print in plain text" do
|
68
|
+
subject.at_line(context, file, 30)
|
69
|
+
check_output_includes "Breakpoint 1 at #{file}:30"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "must print in xml" do
|
73
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new) do
|
74
|
+
subject.at_line(context, file, 30)
|
75
|
+
check_output_includes %{<breakpoint file="#{file}" line="30" threadId="1"/>}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "must show error if current thread is DebugThread" do
|
81
|
+
context.stubs(:thread).returns(Debugger::DebugThread.new {})
|
82
|
+
subject.at_line(context, file, 30)
|
83
|
+
check_output_includes /DebuggerThread are not supposed to be traced/
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#at_line?" do
|
89
|
+
it "returns false if #at_line was not called yet" do
|
90
|
+
subject.at_line?.must_equal false
|
91
|
+
end
|
92
|
+
|
93
|
+
it "returns true if #at_line was called already" do
|
94
|
+
subject.instance_variable_set("@line", 10)
|
95
|
+
subject.at_line?.must_equal true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#at_return?" do
|
100
|
+
before { context.stubs(:stop_frame=).with(-1) }
|
101
|
+
|
102
|
+
it "sets stop_frame to -1" do
|
103
|
+
context.expects(:stop_frame=).with(-1)
|
104
|
+
subject.at_return(context, file, 30)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "prints current file and line" do
|
108
|
+
subject.at_return(context, file, 30)
|
109
|
+
check_output_includes "#{file}:30"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "stops the thread" do
|
113
|
+
Thread.expects(:stop)
|
114
|
+
subject.at_return(context, file, 30)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
data/test/info_test.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Info Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
it "must be unsupported for XML printer" do
|
8
|
+
enter 'info line'
|
9
|
+
debug_file 'info'
|
10
|
+
check_output_includes "<error>Unsupported command 'info'</error>", interface.error_queue
|
11
|
+
end
|
12
|
+
end
|
data/test/irb_test.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Irb Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
it "must be unsupported for XML printer" do
|
8
|
+
enter 'irb'
|
9
|
+
debug_file 'irb'
|
10
|
+
check_output_includes "<error>Unsupported command 'irb'</error>", interface.error_queue
|
11
|
+
end
|
12
|
+
end
|
data/test/jump_test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Jump Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
describe "successful" do
|
8
|
+
describe "jumping to the same line" do
|
9
|
+
it "must show show the same position" do
|
10
|
+
enter 'break 6', 'cont', "jump 6 #{fullpath('jump')}"
|
11
|
+
debug_file('jump')
|
12
|
+
check_output_includes /<suspended file="#{fullpath('jump')}" line="6" threadId="\d+" frames="\d+"\/>/
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must show message after jump" do
|
17
|
+
enter 'break 6', 'cont', "jump 8 #{fullpath('jump')}"
|
18
|
+
debug_file('jump')
|
19
|
+
check_output_includes /<suspended file="#{fullpath('jump')}" line="8" threadId="\d+" frames="\d+"\/>/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/test/kill_test.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Kill Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
it "must be unsupported for XML printer" do
|
8
|
+
enter 'kill'
|
9
|
+
debug_file 'kill'
|
10
|
+
check_output_includes "<error>Unsupported command 'kill'</error>", interface.error_queue
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
data/test/method_test.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Method Command" do
|
4
|
+
include TestDsl
|
5
|
+
temporary_change_method_value(Debugger, :printer, Printers::Xml.new)
|
6
|
+
|
7
|
+
describe "show instance method of a class" do
|
8
|
+
it "must show using full command name" do
|
9
|
+
enter 'break 15', 'cont', 'm MethodEx'
|
10
|
+
debug_file 'method'
|
11
|
+
check_output_includes '<methods><method name="bla"/></methods>'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "show methods of an object" do
|
16
|
+
it "must show using full command name" do
|
17
|
+
enter 'break 15', 'cont', 'method instance a'
|
18
|
+
debug_file 'method'
|
19
|
+
check_output_includes /<methods>.*<method name="bla"\/>.*<\/methods>/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "show instance variables of an object" do
|
24
|
+
it "must show using full name command" do
|
25
|
+
enter 'break 15', 'cont', 'method iv a'
|
26
|
+
debug_file 'method'
|
27
|
+
check_output_includes(Regexp.new(
|
28
|
+
%{<variables>} +
|
29
|
+
%{<variable name="@a" kind="instance" value="b" type="String" hasChildren="false" objectId=".*?"/>} +
|
30
|
+
%{<variable name="@c" kind="instance" value="d" type="String" hasChildren="false" objectId=".*?"/>} +
|
31
|
+
%{</variables>}
|
32
|
+
))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe "Printers::Xml" do
|
4
|
+
include PrinterHelpers
|
5
|
+
|
6
|
+
let(:klass) { Printers::Xml }
|
7
|
+
let(:printer) { klass.new }
|
8
|
+
let(:yaml_xml) do
|
9
|
+
{
|
10
|
+
"foo" => {
|
11
|
+
"errors" => {
|
12
|
+
"bad" => "bad behavior"
|
13
|
+
},
|
14
|
+
"confirmations" => {
|
15
|
+
"okay" => "Okay?"
|
16
|
+
},
|
17
|
+
"debug" => {
|
18
|
+
"dbg" => "Debug message"
|
19
|
+
},
|
20
|
+
"bar" => {
|
21
|
+
"tag" => "xmltag",
|
22
|
+
"attributes" => {
|
23
|
+
"boo" => "{zee} > {uga}",
|
24
|
+
"agu" => "bew"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
},
|
28
|
+
"variable" => {
|
29
|
+
"variable" => {
|
30
|
+
"tag" => "variable",
|
31
|
+
"attributes" => {
|
32
|
+
"name" => "{name}",
|
33
|
+
"kind" => "{kind}",
|
34
|
+
"value" => "{value}",
|
35
|
+
"type" => "{type}",
|
36
|
+
"hasChildren" => "{has_children}",
|
37
|
+
"objectId" => "{id}"
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
YAML.stubs(:load_file).with(yaml_file_path('xml')).returns(yaml_xml)
|
46
|
+
YAML.stubs(:load_file).with(yaml_file_path('base')).returns({})
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#print" do
|
50
|
+
it "must return correctly translated string" do
|
51
|
+
xml = ::Builder::XmlMarkup.new.xmltag(boo: "zuu > aga", agu: "bew")
|
52
|
+
printer.print("foo.bar", zee: "zuu", uga: "aga").must_equal xml
|
53
|
+
end
|
54
|
+
|
55
|
+
it "must return error string" do
|
56
|
+
printer.print("foo.errors.bad").must_equal "<error>bad behavior</error>"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "must return confirmation string" do
|
60
|
+
printer.print("foo.confirmations.okay").must_equal "<confirmation>Okay?</confirmation>"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "must return debug string" do
|
64
|
+
printer.print("foo.debug.dbg").must_equal "Debug message"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#print_collection" do
|
69
|
+
it "must print collection" do
|
70
|
+
expected = ::Builder::XmlMarkup.new.xmltags do |x|
|
71
|
+
x.xmltag(boo: "0 > a", agu: "bew") + x.xmltag(boo: "1 > b", agu: "bew")
|
72
|
+
end
|
73
|
+
result = printer.print_collection("foo.bar", [{uga: 'a'}, {uga: 'b'}]) do |item, index|
|
74
|
+
item.merge(zee: index)
|
75
|
+
end
|
76
|
+
result.must_equal expected
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#print_variables" do
|
81
|
+
it "must print variables" do
|
82
|
+
vars = [["a", "b"], ["c", "d"]]
|
83
|
+
expected = ::Builder::XmlMarkup.new.variables do |x|
|
84
|
+
vars.map do |key, value|
|
85
|
+
x.variable(name: key, kind: "instance", value: value, type: "String", hasChildren: "false", objectId: "%#+x" % value.object_id)
|
86
|
+
end.join("")
|
87
|
+
end
|
88
|
+
result = printer.print_variables(vars, 'instance')
|
89
|
+
result.must_equal expected
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "Printers::Xml::Variable" do
|
94
|
+
let(:klass) { Printers::Xml::Variable }
|
95
|
+
|
96
|
+
describe "#has_children?" do
|
97
|
+
describe "value is Array" do
|
98
|
+
it("must be true for non-empty") { klass.new('bla', ['a']).has_children?.must_equal(true) }
|
99
|
+
it("must be false for empty") { klass.new('bla', []).has_children?.must_equal(false) }
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "value is Hash" do
|
103
|
+
it("must be true for non-empty") { klass.new('bla', {a: 'b'}).has_children?.must_equal(true) }
|
104
|
+
it("must be false for empty") { klass.new('bla', {}).has_children?.must_equal(false) }
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "value is some random class" do
|
108
|
+
unless const_defined?("VariableExampleWithInstanceVars")
|
109
|
+
class VariableExampleWithInstanceVars; def initialize; @a = '1'; end; end
|
110
|
+
end
|
111
|
+
unless const_defined?("VariableExampleWithClassVars")
|
112
|
+
class VariableExampleWithClassVars; def initialize; @@a = '1'; end; end
|
113
|
+
end
|
114
|
+
unless const_defined?("VariableExampleWithoutVars")
|
115
|
+
class VariableExampleWithoutVars; end
|
116
|
+
end
|
117
|
+
it("must be true if has instance variables") { klass.new('bla', VariableExampleWithInstanceVars.new).has_children?.must_equal(true) }
|
118
|
+
it("must be true if has class variables") { klass.new('bla', VariableExampleWithClassVars.new).has_children?.must_equal(true) }
|
119
|
+
it("must be false if has no any variables") { klass.new('bla', VariableExampleWithoutVars.new).has_children?.must_equal(false) }
|
120
|
+
it("must be false as a fallback") { klass.new('bla', BasicObject.new).has_children?.must_equal(false) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#value" do
|
125
|
+
describe "value is a Array" do
|
126
|
+
it("must return string for empty") { klass.new('bla', []).value.must_equal("Empty Array") }
|
127
|
+
it("must return result for non-empty") { klass.new('bla', [1, 2]).value.must_equal("Array (2 element(s))") }
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "value is a Hash" do
|
131
|
+
it("must return string for empty") { klass.new('bla', {}).value.must_equal("Empty Hash") }
|
132
|
+
it("must return result for non-empty") { klass.new('bla', {a: 'b', c: 'd'}).value.must_equal("Hash (2 element(s))") }
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "value is some random class" do
|
136
|
+
unless const_defined?("ToSReturnNotAString")
|
137
|
+
class ToSReturnNotAString; def to_s; {}; end; end
|
138
|
+
end
|
139
|
+
it("must return nil for nil") { klass.new('bla', nil).value.must_equal("nil") }
|
140
|
+
it("must return #to_s for any other class") do
|
141
|
+
klass.new('bla', OpenStruct.new(a: 'b')).value.must_equal '#<OpenStruct a="b">'
|
142
|
+
end
|
143
|
+
it("must be able to show error") do
|
144
|
+
klass.new('bla', BasicObject.new).value.must_match /<raised exception: undefined method/
|
145
|
+
end
|
146
|
+
it("must get rid of quotes") { klass.new('bla', '"foo"').value.must_equal 'foo' }
|
147
|
+
it("must return special message for binary") { klass.new('bla', "\xFF\x12").value.must_equal '[Binary Data]' }
|
148
|
+
it("must show error if returned value is not a string") do
|
149
|
+
klass.new('bla', ToSReturnNotAString.new).value.must_equal(
|
150
|
+
'ERROR: ToSReturnNotAString.to_s method returns Hash. Should return String.'
|
151
|
+
)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "#id" do
|
157
|
+
it "must show object_id" do
|
158
|
+
object = Object.new
|
159
|
+
klass.new('bla', object).id.must_equal("%#+x" % object.object_id)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "must return nil as a fallback" do
|
163
|
+
klass.new('bla', BasicObject.new).id.must_be_nil
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "#type" do
|
168
|
+
it "must return class" do
|
169
|
+
klass.new('bla', Object.new).type.must_equal(Object.new.class)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "must return 'Undefined' as a callback" do
|
173
|
+
klass.new('bla', BasicObject.new).type.must_equal "Undefined"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#name" do
|
178
|
+
it "must return name as a string" do
|
179
|
+
klass.new(:bla, "value").name.must_equal "bla"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "#to_hash" do
|
184
|
+
it "must return a hash with values" do
|
185
|
+
var = "foo"
|
186
|
+
klass.new(:bla, var).to_hash.must_equal(
|
187
|
+
{name: "bla", kind: nil, value: var, type: String, has_children: false, id: "%#+x" % var.object_id}
|
188
|
+
)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|