kefka 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/TODO CHANGED
@@ -51,3 +51,9 @@ edge cases
51
51
  - if the user really wants to see everything, he has to specify granurality cmd line option
52
52
  what if there's a binding.pry in the code
53
53
 
54
+ ways to reduce clutter
55
+ 1. only show variable values if that variable is present on the line
56
+ 2. input file
57
+ show values over there
58
+ line values
59
+ check file
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
data/app.rb CHANGED
@@ -12,40 +12,31 @@ end
12
12
  get '/callgraph' do
13
13
  content_type :json
14
14
 
15
- path = "#{File.expand_path(File.dirname(__FILE__))}/examples/sample_a.rb"
16
- file = File.open(path)
15
+ file_path = "#{File.expand_path(File.dirname(__FILE__))}/examples/sample_a.rb"
17
16
 
18
- @tracer = Kefka::Tracer.new
19
- @tracer.trace(file, :callgraph_handler)
17
+ @tracer = Kefka::Tracer.new(Logger::INFO)
18
+ @tracer.trace(file_path)
20
19
 
21
20
  # input code
22
- code = CodeRay.scan(@tracer.code, :ruby).div(:line_numbers => :table)
21
+ input = CodeRay.scan(@tracer.code, :ruby).div(:line_numbers => :table)
23
22
 
24
23
  graph = @tracer.method_graph
25
24
 
26
25
  # output call graph using dot if graphviz is installed
27
- if graphviz_installed = system("which dot")
26
+ if is_graphviz_installed = system("which dot")
28
27
  graph.write_to_graphic_file("png", "#{File.expand_path(File.dirname(__FILE__))}/public/graph")
29
28
  end
30
29
 
31
30
  # html code graph
32
31
  graph.vertices.each { |method| method.format = :html }
33
32
 
33
+ # locals
34
+ locals = @tracer.local_values
35
+
34
36
  {
35
- :code => code,
36
- :graphviz_installed => graphviz_installed,
37
- :graph => graph
37
+ :input => input,
38
+ :is_graphviz_installed => is_graphviz_installed,
39
+ :graph => graph,
40
+ :locals => locals
38
41
  }.to_json
39
42
  end
40
-
41
- get '/locals' do
42
- content_type :json
43
-
44
- path = "#{File.expand_path(File.dirname(__FILE__))}/examples/sample_a.rb"
45
- file = File.open(path)
46
-
47
- tracer = Kefka::Tracer.new
48
- tracer.trace(file, :local_values_handler)
49
- results = tracer.local_values
50
- results.to_json
51
- end
data/kefka.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "kefka"
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Reginald Tan"]
12
- s.date = "2012-08-12"
12
+ s.date = "2012-08-18"
13
13
  s.description = " It traces the execution path of a program and displays the source code of each method call in the callgraph "
14
14
  s.email = "redge.tan@gmail.com"
15
15
  s.executables = ["kefka"]
@@ -34,8 +34,9 @@ Gem::Specification.new do |s|
34
34
  "public/javascripts/app.js",
35
35
  "public/javascripts/jquery-1.7.2.js",
36
36
  "public/stylesheets/application.css",
37
- "test/helper.rb",
38
- "test/test_kefka.rb",
37
+ "spec/fixture/sample_a.rb",
38
+ "spec/kekfa_spec.rb",
39
+ "spec/spec_helper.rb",
39
40
  "views/index.erb"
40
41
  ]
41
42
  s.homepage = "http://github.com/redgetan/kefka"
data/lib/kefka.rb CHANGED
@@ -3,6 +3,7 @@ require 'rgl/adjacency'
3
3
  require 'rgl/dot'
4
4
  require 'method_source'
5
5
 
6
+ require 'ripper'
6
7
  require 'forwardable'
7
8
  require 'logger'
8
9
 
@@ -10,23 +11,24 @@ class Kefka
10
11
 
11
12
  class Method
12
13
 
13
- attr_reader :classname, :id, :file, :line, :caller
14
- attr_accessor :format
14
+ attr_reader :classname, :id, :file, :line
15
+ attr_accessor :source, :format
15
16
 
16
17
  def initialize(options={})
17
- @classname = options[:classname]
18
- @id = options[:id]
19
- @file = options[:file]
20
- @line = options[:line]
21
- @format = options[:format] || :plain
18
+ raise ArgumentError, "missing file + line" unless options[:file] && options[:line]
19
+ @classname = options[:classname]
20
+ @id = options[:id]
21
+ @file = options[:file]
22
+ @start_line = options[:line]
23
+ @format = options[:format] || :plain
22
24
  end
23
25
 
24
26
  def source_location
25
- [@file,@line]
27
+ [@file,@start_line]
26
28
  end
27
29
 
28
30
  def end_line
29
- @line + source.lines.count - 1
31
+ @start_line + source.lines.count - 1
30
32
  end
31
33
 
32
34
  def key
@@ -34,7 +36,7 @@ class Kefka
34
36
  end
35
37
 
36
38
  def contains?(file, line)
37
- @file == file && @line < line && end_line > line
39
+ @file == file && @start_line <= line && end_line > line
38
40
  end
39
41
 
40
42
  def source
@@ -49,12 +51,18 @@ class Kefka
49
51
  def formatted_source
50
52
  if @format == :html
51
53
  CodeRay.scan(source, :ruby)
52
- .div(:line_numbers => :table, :line_number_start => @line)
54
+ .div(:line_numbers => :table, :line_number_start => @start_line)
53
55
  else
54
56
  source
55
57
  end
56
58
  end
57
59
 
60
+ def source_at_line(line)
61
+ # what if source is not known, ie. eval
62
+ index = line - @start_line
63
+ source.lines.take(index + 1)[index]
64
+ end
65
+
58
66
  def to_s
59
67
  "#{classname} #{id}"
60
68
  end
@@ -63,8 +71,10 @@ class Kefka
63
71
  self.key == other.key
64
72
  end
65
73
 
74
+ alias :== :eql?
75
+
66
76
  def hash
67
- [@file,@line].hash
77
+ [@file,@start_line].hash
68
78
  end
69
79
 
70
80
  def to_json(*a)
@@ -72,7 +82,7 @@ class Kefka
72
82
  :classname => @classname,
73
83
  :id => @id,
74
84
  :file => @file,
75
- :line => @line,
85
+ :line => @start_line,
76
86
  :end_line => end_line,
77
87
  :source => formatted_source
78
88
  }.to_json(*a)
@@ -115,35 +125,29 @@ class Kefka
115
125
  @logger.level = log_level
116
126
  end
117
127
 
118
- def get_locals(target)
119
- target.eval("local_variables")
120
- end
128
+ def trace(file_path)
129
+ file = File.open(file_path)
121
130
 
122
- def deep_copy(val)
123
- Marshal.load(Marshal.dump(val))
124
- rescue TypeError
125
- "_unknown_"
126
- end
131
+ thread = Thread.new {
132
+ @code = file.read
133
+ #@callstack << create_top_level_method(file_path)
134
+ eval(@code, TOPLEVEL_BINDING, file.path, 1)
135
+ }
127
136
 
128
- def get_values_of_locals_from_binding(target)
129
- locals = get_locals(target)
130
- locals.inject({}) do |result,l|
131
- val = target.eval(l.to_s)
132
- val = deep_copy(val)
133
- result.merge!({ l => val })
134
- result
135
- end
137
+ thread.set_trace_func method(:trace_handler).to_proc
138
+ thread.join
136
139
  end
137
140
 
138
141
  def disable_event_handlers?
139
142
  !@event_disable.empty?
140
143
  end
141
144
 
142
- def callgraph_handler(event, file, line, id, binding, classname)
145
+ def trace_handler(event, file, line, id, binding, classname)
143
146
  return if file == __FILE__
144
147
 
145
148
  @logger.debug "#{event} - #{file}:#{line} #{classname} #{id}"
146
149
 
150
+ # skip event handling when iseq is happening inside class loading
147
151
  if disable_event_handlers?
148
152
  @event_disable.pop if event == "end"
149
153
  return
@@ -167,6 +171,28 @@ class Kefka
167
171
  end
168
172
 
169
173
  @callstack << method
174
+ when "line"
175
+ # skip variables that should not be tracked
176
+ # 1. anything in current lib (i.e __FILE__)
177
+ # 2. all local variables that are in TOP LEVEL BINDING before tracing
178
+ # - but these variables may be overwritten by the traced program,
179
+ # excluding them would mean not displaying certain relevant
180
+ # vars in that program
181
+ #current_method = @callstack.last
182
+
183
+ # given current file & line, determine what method I am in
184
+
185
+ method = @method_graph.vertices
186
+ .select { |method| method.contains?(file,line) }
187
+ .first
188
+
189
+ # skip if not in any previously called method
190
+ if method
191
+ line_source = method.source_at_line(line)
192
+
193
+ iseq_key = [file, line].join(":")
194
+ @local_values[iseq_key] = get_values_of_locals_from_binding(binding, line_source)
195
+ end
170
196
  when "return"
171
197
  @callstack.pop
172
198
  else
@@ -177,48 +203,48 @@ class Kefka
177
203
  Process.kill("KILL", $$)
178
204
  end
179
205
 
180
- def local_values_handler(event, file, line, id, binding, classname)
181
- # skip variables that should not be tracked
182
- # 1. anything in current lib (i.e __FILE__)
183
- # 2. all local variables that are in TOP LEVEL BINDING before tracing
184
- # - but these variables may be overwritten by the traced program,
185
- # excluding them would mean not displaying certain relevant
186
- # vars in that program
187
- return if file == __FILE__
206
+ def get_values_of_locals_from_binding(target, line_source)
207
+ locals = get_locals(target,line_source)
208
+ locals.inject({}) do |result,l|
209
+ val = target.eval(l.to_s)
210
+ val = deep_copy(val)
211
+ result.merge!({ l => val })
212
+ result
213
+ end
214
+ end
188
215
 
189
- @logger.debug "#{event} - #{file}:#{line} #{classname} #{id}" if $DEBUG
216
+ def get_locals(target, line_source)
217
+ scope_locals = target.eval("local_variables")
218
+ scope_locals.map! { |local| local.to_s }
190
219
 
191
- if disable_event_handlers?
192
- @event_disable.pop if event == "end"
193
- return
194
- end
220
+ tokens = Ripper.lex(line_source)
195
221
 
196
- case event
197
- when "class"
198
- @event_disable << true
199
- when "line"
200
- key = [file, line].join(":")
201
- @local_values[key] = get_values_of_locals_from_binding(binding)
202
- else
203
- # do nothing
204
- end
205
- end
222
+ tokens.select! { |token|
223
+ type = token[1]
224
+ type == :on_ident || type == :on_ivar || type == :on_cvar
225
+ }
206
226
 
207
- def print_callgraph
208
- public_dir = "#{File.expand_path(File.dirname(__FILE__))}/../public"
209
- @method_graph.write_to_graphic_file("png", "#{public_dir}/graph")
227
+ possible_line_variables = tokens.map { |token| token[2] }
228
+ line_variables = scope_locals & possible_line_variables
229
+ line_variables
210
230
  end
211
231
 
212
- def trace(file_path, handler = :callgraph_handler)
213
- file = File.open(file_path)
232
+ def deep_copy(val)
233
+ Marshal.load(Marshal.dump(val))
234
+ rescue TypeError
235
+ "_unknown_"
236
+ end
214
237
 
215
- thread = Thread.new {
216
- @code = file.read
217
- eval(@code, TOPLEVEL_BINDING, file.path, 1)
218
- }
219
238
 
220
- thread.set_trace_func method(handler).to_proc
221
- thread.join
239
+ def create_top_level_method(file)
240
+ method = Method.new(
241
+ :classname => "Object",
242
+ :id => "<main>",
243
+ :file => file,
244
+ :line => 1
245
+ )
246
+ method.source = File.readlines(file).join
247
+ return method
222
248
  end
223
249
 
224
250
  end
@@ -2,27 +2,34 @@ var jqSelectorEscape = function(text) {
2
2
  return text.replace(/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g, "\\$&");
3
3
  };
4
4
 
5
- var createCodeBubbles = function(data) {
6
- console.log(data);
7
-
8
- var input = data.code;
9
-
5
+ var outputTrace = function(data) {
6
+ displayInput(data.input);
7
+ displayGraphiz(data.is_graphviz_installed);
8
+ createCodeBubbles(data.graph);
9
+ displayLocals(data.locals);
10
+ }
11
+
12
+ var displayInput = function(input) {
10
13
  $("div#input").last().append(input);
14
+ };
11
15
 
12
- if (data.graphviz_installed == true) {
16
+ var displayGraphiz = function(is_graphviz_installed) {
17
+ if (is_graphviz_installed) {
13
18
  $("div#callGraph").last().append("<img src='graph.png'/>");
14
19
  } else {
15
20
  $("div#callGraph").last().append("Graphviz visualization not Available. Install Graphviz to enable it.");
16
21
  }
22
+ };
17
23
 
18
- var codeGraph = data.graph;
24
+ var createCodeBubbles = function(graph) {
25
+ console.log(graph);
19
26
 
20
27
  var xPos = 0;
21
28
  var bubbleDiv, $bubble, $code,
22
29
  key, header,
23
30
  lineCount, column;
24
31
 
25
- var methods = codeGraph.vertices;
32
+ var methods = graph.vertices;
26
33
 
27
34
  for (var i = 0; i < methods.length; i++ )
28
35
  {
@@ -68,23 +75,21 @@ var createCodeBubbles = function(data) {
68
75
  }
69
76
  };
70
77
 
71
- var displayLocalValues = function(data) {
72
- console.log(data);
73
-
74
- var localValues = data;
78
+ var displayLocals = function(locals) {
79
+ console.log(locals);
75
80
 
76
81
  var values, keys, file, line, $bubbles, $line;
77
82
 
78
- for (var key in localValues)
83
+ for (var key in locals)
79
84
  {
80
85
  values = "";
81
86
 
82
- for (var local in localValues[key])
87
+ for (var local in locals[key])
83
88
  {
84
89
  values += "\t";
85
90
  values += local;
86
91
  values += ": ";
87
- values += localValues[key][local];
92
+ values += locals[key][local];
88
93
  }
89
94
 
90
95
  keys = key.split(":");
@@ -102,20 +107,11 @@ var displayLocalValues = function(data) {
102
107
 
103
108
  $(document).ready(function(){
104
109
 
105
- var getLocalValues = function() {
106
- $.ajax({
107
- url: "/locals",
108
- dataType: "json",
109
- success: displayLocalValues
110
- });
111
- };
112
-
113
110
  $.ajax({
114
111
  url: "/callgraph",
115
112
  dataType: "json",
116
- success: [createCodeBubbles, getLocalValues]
113
+ success: outputTrace
117
114
  });
118
115
 
119
-
120
116
  });
121
117
 
@@ -0,0 +1,73 @@
1
+ require 'forwardable'
2
+ require 'date'
3
+ require 'net/http'
4
+
5
+ # class with function calls inside class loading
6
+ class Book
7
+ extend Forwardable
8
+ def_delegators :@store, :first, :last
9
+
10
+ def initialize
11
+ @store = [1,2]
12
+ end
13
+
14
+ def []
15
+ "array accessor"
16
+ end
17
+ end
18
+
19
+ # class with variable of IO instance
20
+ class Displayer
21
+ def initialize(out)
22
+ @out = out
23
+ end
24
+
25
+ def puts(val)
26
+ @out.puts val
27
+ end
28
+ end
29
+
30
+ def hello
31
+ shout("holdon")
32
+
33
+ num = init
34
+ x = 4
35
+ x = x * 2
36
+ b = Book.new
37
+
38
+ shout("yeah")
39
+
40
+ if b.first
41
+ puts "lol"
42
+ end
43
+
44
+ c = b[]
45
+ display = Displayer.new($stdout)
46
+ display.puts "Hello #{num}"
47
+ end
48
+
49
+ def shout(text)
50
+ a = text
51
+ a.split("").map(&:ord)
52
+ end
53
+
54
+ def init
55
+ a = 1 + rand(9)
56
+ (0..3).each do |x|
57
+ a = a + time_diff + x
58
+ end
59
+ a
60
+ end
61
+
62
+ # function called inside a loop
63
+ def time_diff
64
+ before = Time.now
65
+ after = Time.now
66
+ (after - before).to_i
67
+ end
68
+
69
+ hello
70
+
71
+ # stdlib function call (network)
72
+ Net::HTTP.get_response(URI.parse("http://www.twitter.com")).body
73
+
@@ -0,0 +1,294 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ def trace(source)
5
+ file = File.open(StringIO.new(source))
6
+ tracer = Kefka::Tracer.new
7
+ tracer.trace(file)
8
+ tracer
9
+ end
10
+
11
+ # start with user story
12
+ # understanding URI.parse
13
+ #
14
+ # key features
15
+ # reduce clutter
16
+ # only show variable values when line contains that var
17
+ # variables include instance/class/local variable
18
+ # on_ident (do not include method, i.e. if preceded by period)
19
+ # on_ivar
20
+ # on_cvar
21
+ # all variable values within a method should replace their variable counterparts
22
+ # when mouse hovers over a variable in that method
23
+ # collapsible
24
+ # only show bubbles at toplevel (main entry point of program), others are hidden
25
+ # each bubble will have a # children counter which specifies how many bubbles it has down the chain
26
+ # bubble children count = sum of each methodcall children count
27
+ # expanding a bubble
28
+ # can be a specific method call
29
+ # can be all method calls within bubble
30
+ # immediate children becomes visible to view
31
+ #
32
+ #
33
+ #
34
+ #
35
+ #
36
+
37
+ describe "Kefka::Inspector" do
38
+
39
+ # file = File.open(file_path)
40
+ # puts "\n#{e.class}: #{e.message} \n from #{e.backtrace.join("\n")}"
41
+ #
42
+ context "when current line contains any local_variables" do
43
+ it "should evaluate the local_variables for that line" do
44
+
45
+ end
46
+ end
47
+
48
+ context "when current line does not contain any local_variables" do
49
+ it "should not do anything" do
50
+
51
+ end
52
+ end
53
+ end
54
+
55
+ # Given a method_call, line_no, N-th visit
56
+ # line_locals.should == { :x => 4, y => "reg" }
57
+ #
58
+ #
59
+ # Future: Given a method, determine code paths
60
+ # given a vertex, show all adjacency lists
61
+ #
62
+ #
63
+ #
64
+ #
65
+ #
66
+ # determine what exactly the output of callgraph is gonna be
67
+ # could reperesent just methodname callgraph
68
+ # |----|
69
+ # | |
70
+ # | |
71
+ # |----|
72
+ #
73
+ # Method
74
+ # has many locals (array)
75
+ #
76
+ # MethodLocal
77
+ # has many line locals
78
+ #
79
+ # callstack: call1<method:line> -> call2
80
+ # iteration: 6
81
+ # line_locals: [line_local, line_local, ..]
82
+ #
83
+ # LineLocal
84
+ # iteration: 3 #{based on length of data array
85
+ # data: { :x => 1, :y => 4}
86
+ #
87
+ # Call
88
+ # method:
89
+ # line:
90
+
91
+ #
92
+ # Use case
93
+ # I'm at a method bubble
94
+ #
95
+ # i wanna see all the execution paths that have gone through this bubble
96
+ # i should be able to filter incoming paths by their caller/callstack/n-th iteration
97
+ # i should be able to filter a methods locals by their caller/callstack/n-th iteration
98
+ #
99
+ #
100
+ # 3 containers
101
+ # codegraph - graph of what method source called what method source (vertices)
102
+ # callgraph - graph of what line of method source called what method source (links)
103
+ #
104
+ # power - line value
105
+ #
106
+ describe "Kekfa::Callgraph" do
107
+ # holds methodcalls (entity)
108
+
109
+ # {
110
+ # vertices => []
111
+ # }
112
+ it "#to_json" do
113
+
114
+ end
115
+
116
+ describe "edges" do
117
+ # source is a methodcall
118
+ # target is a methodcall
119
+ end
120
+
121
+ describe "links" do
122
+ # source is a line
123
+ # line - identified by methodcall + lineno
124
+ # target is a methodcall
125
+ end
126
+
127
+ end
128
+
129
+ describe "Kefka::Method" do
130
+ describe "#source_location" do
131
+ it "should be an array containing file and line where method is defined" do
132
+ file, line = "filename.rb", 20
133
+ method = Method.new(:file => file, :line => line)
134
+ method.source_location.should == [file, line]
135
+ end
136
+ end
137
+ end
138
+
139
+ #
140
+ # Callstack
141
+ #
142
+ # "call" -> push method, line into stack if method && line
143
+ # "call" -> store curr_method
144
+ # "line" -> store curr_line
145
+
146
+ describe "Kefka::Call" do
147
+ it "stores current method" do
148
+
149
+ end
150
+ it "stores current line" do
151
+
152
+ end
153
+ end
154
+
155
+ #
156
+ #
157
+ describe "Kekfa::Tracer" do
158
+
159
+ describe "Locals" do
160
+
161
+ describe "line entered once" do
162
+ before do
163
+ @source = <<-RUBY
164
+ def hello
165
+ x = 1
166
+ x += 2
167
+ end
168
+
169
+ hello
170
+ RUBY
171
+ end
172
+
173
+ it "should able to get locals value" do
174
+ locals = trace(@source).locals
175
+
176
+ locals = locals.for_method(:hello).iter(0)
177
+
178
+ locals.for_line(0).iter(0)[:x].should == nil
179
+ locals.for_line(1).iter(0)[:x].should == 1
180
+ locals.for_line(2).iter(0)[:x].should == 3
181
+ end
182
+ end
183
+
184
+ describe "line entered multiple times" do
185
+
186
+ describe "iteration" do
187
+ before do
188
+ @source = <<-RUBY
189
+ def hello
190
+ x = 1
191
+ (0..3).each do
192
+ x += 2
193
+ end
194
+ end
195
+
196
+ hello
197
+ RUBY
198
+ end
199
+
200
+ it "should able to get locals value" do
201
+ locals = trace(@source).locals
202
+
203
+ locals = locals.for_method(:hello).iter(0)
204
+
205
+ locals.for_line(2).iter(0)[:x].should == 3
206
+ locals.for_line(2).iter(1)[:x].should == 5
207
+ locals.for_line(2).iter(2)[:x].should == 7
208
+ locals.for_line(2).iter(3)[:x].should == 9
209
+ end
210
+ end
211
+
212
+ describe "different call_source same method + diff line" do
213
+ before do
214
+ @source = <<-RUBY
215
+ def hello(x)
216
+ y = x
217
+ end
218
+
219
+ def day
220
+ hello(3)
221
+ end
222
+
223
+ def night
224
+ hello(8)
225
+ end
226
+
227
+ day
228
+ night
229
+ RUBY
230
+ end
231
+
232
+ it "should able to get locals value" do
233
+ locals = trace(@source).locals
234
+
235
+ locals = locals.for_method(:hello).iter(0)
236
+ locals.for_line(0).iter(0)[:x].should == 3
237
+ line_locals[0][0].var(:x).value.should == 3
238
+
239
+ locals = locals.for_method(:hello).iter(1)
240
+ locals.for_line(0).iter(0)[:x].should == 8
241
+ end
242
+ end
243
+
244
+ describe "different call_source diff method + diff line" do
245
+
246
+ end
247
+
248
+ describe "recursion" do
249
+
250
+ end
251
+ end
252
+
253
+ end
254
+
255
+ describe "locals value storage" do
256
+ describe "line entered once" do
257
+ # sample_a.rb:30 -> x should be nil
258
+ # sample_a.rb:31 -> x should be 4
259
+ # sample_a.rb:32 -> x should be 8
260
+ it "should show variable output" do
261
+
262
+ end
263
+ end
264
+
265
+ describe "line entered more than once" do
266
+ # sample_a.rb:46:0 -> x should be nil
267
+ # sample_a.rb:46:1 -> x should be 4
268
+ # sample_a.rb:46:2 -> x should be 8
269
+ # sample_a.rb:46 -> array
270
+ # array index representh the N-th iteration
271
+ # idx 0 -> LocalValue
272
+ # keys -> x,a
273
+ # values ->
274
+ #
275
+ it "should show variable output" do
276
+
277
+ end
278
+ end
279
+ end
280
+ # should store locals_value_table
281
+ it "should store locals_value_table" do
282
+ end
283
+ #
284
+ end
285
+
286
+ #class Inspector
287
+ #def initialize
288
+
289
+ #end
290
+
291
+ #def
292
+
293
+ #end
294
+ #end
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
+
3
4
  begin
4
5
  Bundler.setup(:default, :development)
5
6
  rescue Bundler::BundlerError => e
@@ -7,12 +8,9 @@ rescue Bundler::BundlerError => e
7
8
  $stderr.puts "Run `bundle install` to install missing gems"
8
9
  exit e.status_code
9
10
  end
10
- require 'test/unit'
11
- require 'shoulda'
12
11
 
13
12
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+
15
14
  require 'kefka'
16
15
 
17
- class Test::Unit::TestCase
18
- end
16
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kefka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-12 00:00:00.000000000 Z
12
+ date: 2012-08-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby
16
- requirement: &70273937010140 !ruby/object:Gem::Requirement
16
+ requirement: &70342061670580 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70273937010140
24
+ version_requirements: *70342061670580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: coderay
27
- requirement: &70273937009600 !ruby/object:Gem::Requirement
27
+ requirement: &70342061668920 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70273937009600
35
+ version_requirements: *70342061668920
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &70273937008940 !ruby/object:Gem::Requirement
38
+ requirement: &70342061667860 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70273937008940
46
+ version_requirements: *70342061667860
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: method_source
49
- requirement: &70273936990620 !ruby/object:Gem::Requirement
49
+ requirement: &70342061665980 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70273936990620
57
+ version_requirements: *70342061665980
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rgl
60
- requirement: &70273936989280 !ruby/object:Gem::Requirement
60
+ requirement: &70342061665180 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70273936989280
68
+ version_requirements: *70342061665180
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry
71
- requirement: &70273936987380 !ruby/object:Gem::Requirement
71
+ requirement: &70342061656240 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70273936987380
79
+ version_requirements: *70342061656240
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: pry-doc
82
- requirement: &70273936986160 !ruby/object:Gem::Requirement
82
+ requirement: &70342061655300 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70273936986160
90
+ version_requirements: *70342061655300
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rspec
93
- requirement: &70273936984420 !ruby/object:Gem::Requirement
93
+ requirement: &70342061654480 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70273936984420
101
+ version_requirements: *70342061654480
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: jeweler
104
- requirement: &70273936983420 !ruby/object:Gem::Requirement
104
+ requirement: &70342061653480 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70273936983420
112
+ version_requirements: *70342061653480
113
113
  description: ! ' It traces the execution path of a program and displays the source
114
114
  code of each method call in the callgraph '
115
115
  email: redge.tan@gmail.com
@@ -136,8 +136,9 @@ files:
136
136
  - public/javascripts/app.js
137
137
  - public/javascripts/jquery-1.7.2.js
138
138
  - public/stylesheets/application.css
139
- - test/helper.rb
140
- - test/test_kefka.rb
139
+ - spec/fixture/sample_a.rb
140
+ - spec/kekfa_spec.rb
141
+ - spec/spec_helper.rb
141
142
  - views/index.erb
142
143
  - TODO
143
144
  homepage: http://github.com/redgetan/kefka
@@ -155,7 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
156
  version: '0'
156
157
  segments:
157
158
  - 0
158
- hash: -1427345181685482934
159
+ hash: 3078071895690683820
159
160
  required_rubygems_version: !ruby/object:Gem::Requirement
160
161
  none: false
161
162
  requirements:
data/test/test_kefka.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestKefka < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end