augment 1.0.0 → 1.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/History.txt +3 -0
- data/Manifest.txt +15 -9
- data/README.txt +8 -8
- data/Rakefile +15 -2
- data/TODO +15 -5
- data/bin/augment +9 -3
- data/lib/augment.rb +9 -3
- data/lib/backends/backend.rb +20 -0
- data/lib/backends/clear_backend.rb +14 -0
- data/lib/backends/coloring_backend.rb +6 -2
- data/lib/backends/flog_backend.rb +27 -0
- data/lib/backends/test_unit_backend.rb +22 -27
- data/lib/flet.rb +20 -11
- data/lib/frontends/ansi_color_frontend.rb +2 -3
- data/lib/frontends/augment.el +16 -4
- data/lib/frontends/html_frontend.rb +2 -3
- data/lib/layer.rb +62 -10
- data/spec/ansi_frontend_spec.rb +4 -0
- data/spec/color_backend_spec.rb +10 -10
- data/spec/emacs-frontend-test.el +30 -6
- data/spec/fixtures/drinks/lib/drink.rb +8 -6
- data/spec/fixtures/fix_test.rb +7 -0
- data/spec/fixtures/layers.json +3 -3
- data/spec/fixtures/working_test.rb +7 -0
- data/spec/flog_backend_spec.rb +24 -0
- data/spec/html_frontend_spec.rb +0 -8
- data/spec/layer_spec.rb +59 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/test_backend_spec.rb +15 -10
- metadata +20 -14
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -1,27 +1,33 @@
|
|
1
1
|
COPYING
|
2
|
-
TODO
|
3
2
|
History.txt
|
4
3
|
Manifest.txt
|
5
4
|
README.txt
|
6
5
|
Rakefile
|
6
|
+
TODO
|
7
7
|
bin/augment
|
8
8
|
lib/augment.rb
|
9
|
-
lib/layer.rb
|
10
|
-
lib/flet.rb
|
11
9
|
lib/backends/backend.rb
|
10
|
+
lib/backends/clear_backend.rb
|
12
11
|
lib/backends/coloring_backend.rb
|
12
|
+
lib/backends/flog_backend.rb
|
13
13
|
lib/backends/test_unit_backend.rb
|
14
|
-
lib/frontends/frontend.rb
|
15
14
|
lib/frontends/ansi_color_frontend.rb
|
16
|
-
lib/frontends/html_frontend.rb
|
17
15
|
lib/frontends/augment.el
|
16
|
+
lib/frontends/frontend.rb
|
17
|
+
lib/frontends/html_frontend.rb
|
18
|
+
lib/layer.rb
|
19
|
+
lib/flet.rb
|
18
20
|
spec/ansi_frontend_spec.rb
|
19
21
|
spec/color_backend_spec.rb
|
20
22
|
spec/emacs-frontend-test.el
|
21
|
-
spec/
|
22
|
-
spec/spec_helper.rb
|
23
|
-
spec/test_backend_spec.rb
|
23
|
+
spec/layer_spec.rb
|
24
24
|
spec/fixtures/augment-output.txt
|
25
|
-
spec/fixtures/layers.json
|
26
25
|
spec/fixtures/drinks/lib/drink.rb
|
27
26
|
spec/fixtures/drinks/test/test_drink.rb
|
27
|
+
spec/fixtures/layers.json
|
28
|
+
spec/fixtures/fix_test.rb
|
29
|
+
spec/fixtures/working_test.rb
|
30
|
+
spec/html_frontend_spec.rb
|
31
|
+
spec/spec_helper.rb
|
32
|
+
spec/test_backend_spec.rb
|
33
|
+
spec/flog_backend_spec.rb
|
data/README.txt
CHANGED
@@ -20,12 +20,11 @@ Example:
|
|
20
20
|
|
21
21
|
$ augment test lib/foo.rb # will store metadata for test/test_foo.rb
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
shell:
|
23
|
+
You can also use the +augment+ executable to display stored
|
24
|
+
metadata. The simplest frontend is +color+ which outputs the
|
25
|
+
layers via ANSI color codes to the shell:
|
27
26
|
|
28
|
-
$
|
27
|
+
$ augment color test/test_foo.rb
|
29
28
|
|
30
29
|
Most other frontends are editor-specific.
|
31
30
|
|
@@ -73,13 +72,14 @@ Backends:
|
|
73
72
|
Frontends:
|
74
73
|
|
75
74
|
* ANSI color codes (for shells)
|
76
|
-
*
|
77
|
-
*
|
75
|
+
* HTML
|
76
|
+
* Emacs
|
78
77
|
* Textmate (planned)
|
78
|
+
* Vim (planned, need help)
|
79
79
|
|
80
80
|
== Issues
|
81
81
|
|
82
|
-
*
|
82
|
+
* A bit short on frontends and backends.
|
83
83
|
|
84
84
|
== License
|
85
85
|
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'hoe'
|
5
|
+
require 'erb'
|
5
6
|
require 'spec/rake/spectask'
|
6
7
|
require './lib/augment.rb'
|
7
8
|
|
@@ -13,12 +14,24 @@ Hoe.new('augment', Augment::VERSION) do |p|
|
|
13
14
|
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
14
15
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
15
16
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
16
|
-
p.extra_deps << ['miniunit', '>= 1.0
|
17
|
+
p.extra_deps << ['miniunit', '>= 1.1.0']
|
17
18
|
p.extra_deps << ['json', '>= 1.1.1']
|
18
19
|
end
|
19
20
|
|
20
21
|
task :publish_html do
|
21
|
-
system("scp
|
22
|
+
system("scp html/* technomancy@rubyforge.org:/var/www/gforge-projects/augment/")
|
23
|
+
end
|
24
|
+
|
25
|
+
task :render_html do
|
26
|
+
FileUtils.cd(File.dirname(__FILE__) + '/html/src/')
|
27
|
+
TEMPLATE = File.read('html.erb')
|
28
|
+
Dir.glob('*html').each do |filename|
|
29
|
+
@title = ("Augment - " + filename.match(/(.*)\.html/)[1].gsub(/_/, ' ').capitalize).gsub(/ - Index/, '')
|
30
|
+
@body = File.read(filename)
|
31
|
+
|
32
|
+
html = ERB.new(TEMPLATE).result( binding )
|
33
|
+
File.open("../#{filename}", 'w') { |f| f.puts html }
|
34
|
+
end
|
22
35
|
end
|
23
36
|
|
24
37
|
Spec::Rake::SpecTask.new
|
data/TODO
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
Layers:
|
2
|
+
- determine char range from ambiguous method names and class methods
|
3
|
+
- get the char range for a whole method
|
4
|
+
- get the char range for the "def" line of a method
|
5
|
+
FlogBackend:
|
6
|
+
- color layers based on the severity of complexity
|
7
|
+
General:
|
8
|
+
- allow "--interactive" use to specify what backends to use
|
9
|
+
- allow for a broader range of colors (html colors?) (how to handle ANSI?)
|
10
|
+
- overlapping layers?
|
11
|
+
- publish html+docs using rsync
|
12
|
+
Emacs:
|
13
|
+
- stability issues
|
14
|
+
- augment-show-message
|
15
|
+
- specify what backends to use
|
data/bin/augment
CHANGED
@@ -3,13 +3,19 @@ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
|
|
3
3
|
|
4
4
|
require 'augment'
|
5
5
|
|
6
|
+
# TODO: real option parsing?
|
6
7
|
if ARGV.first == '--interactive'
|
7
8
|
Augment.interactive
|
8
9
|
exit 0
|
9
10
|
elsif ARGV.size != 2
|
10
|
-
puts "Usage: augment BACKEND/FRONTEND FILE
|
11
|
-
|
12
|
-
|
11
|
+
puts "Usage: augment BACKEND/FRONTEND FILE
|
12
|
+
or: augment --interactive
|
13
|
+
Output or store metadata regarding code.
|
14
|
+
|
15
|
+
Available backends:
|
16
|
+
#{Augment::BACKENDS.map { |k, v| " #{k}:#{v}"}.join("\n")}
|
17
|
+
Available frontends:
|
18
|
+
#{Augment::FRONTENDS.map { |k, v| " #{k}:#{v}"}.join("\n")}"
|
13
19
|
exit 1
|
14
20
|
end
|
15
21
|
|
data/lib/augment.rb
CHANGED
@@ -10,7 +10,7 @@ require 'backend'
|
|
10
10
|
require 'frontend'
|
11
11
|
|
12
12
|
class Augment
|
13
|
-
VERSION = '1.0.
|
13
|
+
VERSION = '1.0.1'
|
14
14
|
BACKENDS = {}
|
15
15
|
FRONTENDS = {}
|
16
16
|
|
@@ -20,8 +20,12 @@ class Augment
|
|
20
20
|
end
|
21
21
|
|
22
22
|
class << self
|
23
|
+
##
|
24
|
+
# Interactive mode allows you to repeatedly give augment a filename and have
|
25
|
+
# it spit back layer JSON immediately. By default only uses the test backend.
|
26
|
+
#
|
23
27
|
def interactive(backend_names = 'test')
|
24
|
-
|
28
|
+
loop do
|
25
29
|
begin
|
26
30
|
filename = STDIN.gets.chomp
|
27
31
|
backend_names.each { |backend| BACKENDS[backend].run(filename) }
|
@@ -31,11 +35,13 @@ class Augment
|
|
31
35
|
end
|
32
36
|
end
|
33
37
|
end
|
34
|
-
|
38
|
+
|
39
|
+
# Where should the JSON layer files be given a file?
|
35
40
|
def augment_path(original)
|
36
41
|
"#{File.dirname(File.expand_path(original))}/.augment/#{File.basename(original)}"
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
46
|
+
# Load up backends and frontends
|
41
47
|
Dir.glob(File.dirname(__FILE__) + '/*ends/*rb').each { |b| require b[0 .. -4] }
|
data/lib/backends/backend.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Base class from which to subclass other backends. Subclasses must
|
5
|
+
# implement the +run+ method that gets passed a file name and must (0)
|
6
|
+
# set the +@layers+ instance var to a hash of layers containing the
|
7
|
+
# metadata gathered and call the +write_layers+ method when finished
|
8
|
+
# to save that data.
|
9
|
+
#
|
3
10
|
class Backend
|
4
11
|
class << self
|
12
|
+
def run(file)
|
13
|
+
raise "Base Backend class shouldn't be used for real augmentation."
|
14
|
+
end
|
15
|
+
|
16
|
+
# Output the +@layers+ hash as JSON where augment expects it.
|
5
17
|
def write_layers
|
6
18
|
@layers.each do |file, layers|
|
7
19
|
FileUtils.mkpath(File.dirname(file) + '/.augment')
|
@@ -10,5 +22,13 @@ class Backend
|
|
10
22
|
end
|
11
23
|
end
|
12
24
|
end
|
25
|
+
|
26
|
+
# Suppress STDOUT while a block runs.
|
27
|
+
def with_no_output
|
28
|
+
old_stdout = $stdout.clone
|
29
|
+
$stdout.reopen(File.new('/dev/null','w'))
|
30
|
+
yield
|
31
|
+
$stdout.reopen(old_stdout)
|
32
|
+
end
|
13
33
|
end
|
14
34
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'find'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
##
|
5
|
+
# This backend just gets rid of all .augment files in a directory, recursively.
|
6
|
+
class ClearBackend < Backend
|
7
|
+
class << self
|
8
|
+
def run(file)
|
9
|
+
Find.find(file) { |f| FileUtils.rm_rf(f) if f =~ /\.augment$/ }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Augment::BACKENDS['clear'] = self
|
14
|
+
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
##
|
2
|
+
# This backend is just a dummy that isn't actually useful for anything
|
3
|
+
# other than testing purposes.
|
4
|
+
#
|
1
5
|
class ColoringBackend < Backend
|
2
6
|
COLORS = ['white', 'red', 'green', 'blue', 'black']
|
3
7
|
|
@@ -20,6 +24,6 @@ class ColoringBackend < Backend
|
|
20
24
|
write_layers
|
21
25
|
end
|
22
26
|
end
|
27
|
+
|
28
|
+
Augment::BACKENDS['color'] = self
|
23
29
|
end
|
24
|
-
|
25
|
-
Augment::BACKENDS['color'] = ColoringBackend
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'flog'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Gather complexity metrics about a piece of code via flog
|
5
|
+
#
|
6
|
+
class FlogBackend < Backend
|
7
|
+
class << self
|
8
|
+
def run(file)
|
9
|
+
@file = file
|
10
|
+
@layers = {}
|
11
|
+
|
12
|
+
flogger = Flog.new
|
13
|
+
flogger.flog_files @file
|
14
|
+
flogger.totals.each { |method, score| record method, score }
|
15
|
+
write_layers
|
16
|
+
end
|
17
|
+
|
18
|
+
def record(method, score)
|
19
|
+
return if method =~ /\#none$/ # tossing this stuff
|
20
|
+
color = 'red' # TODO: determine color smartly
|
21
|
+
message = "#{method} flogs at #{score}"
|
22
|
+
(@layers[@file] ||= []) << Layer.new(method, color, message, self, @file)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Augment::BACKENDS['flog'] = self
|
27
|
+
end
|
@@ -1,19 +1,26 @@
|
|
1
1
|
Object.flet(:at_exit => lambda {}) do
|
2
2
|
# keep miniunit's at_exit block from running
|
3
|
-
gem 'miniunit', ">= 1.0
|
3
|
+
gem 'miniunit', ">= 1.1.0"
|
4
4
|
require 'test/unit'
|
5
5
|
end
|
6
6
|
|
7
|
-
module
|
8
|
-
|
9
|
-
|
7
|
+
module MiniTest
|
8
|
+
class Unit
|
9
|
+
# Puke failures/errors in a bucket
|
10
|
+
def puke(*args)
|
11
|
+
TestUnitBackend.failure_bucket(*args)
|
12
|
+
end
|
10
13
|
end
|
11
|
-
|
12
|
-
def Unit.puts(*args); end # muffle test output
|
13
14
|
end
|
14
15
|
|
16
|
+
##
|
17
|
+
# Backend for gathering test results. Instead of ntalbott's test/unit
|
18
|
+
# which ships with Ruby as of 1.8.6, this uses miniunit, a vastly
|
19
|
+
# simpler mostly-compatible replacement.
|
20
|
+
#
|
15
21
|
class TestUnitBackend < Backend
|
16
22
|
class << self
|
23
|
+
# Kicks off a miniunit run and captures the failures
|
17
24
|
def run(file)
|
18
25
|
@file = file
|
19
26
|
@layers = {}
|
@@ -24,33 +31,21 @@ class TestUnitBackend < Backend
|
|
24
31
|
write_layers
|
25
32
|
end
|
26
33
|
|
27
|
-
def
|
34
|
+
def failure_bucket(klass, method, exception)
|
28
35
|
# FIXME: errors here could actually occur in impl rather than test file
|
29
|
-
|
36
|
+
color = Test::Assertion === exception ? 'red' : 'yellow'
|
37
|
+
line = exception.backtrace.grep(Regexp.new(@file))[0].match(/:(\d*):/)[1].to_i
|
38
|
+
|
39
|
+
(@layers[@file] ||= []) << Layer.new(line, color, exception.message, self, @file)
|
30
40
|
end
|
31
41
|
|
42
|
+
# This should allow us to augment a test by running its associated
|
43
|
+
# implementation
|
32
44
|
def find_test_for(file)
|
33
45
|
# TODO: return test for implementation if possible
|
34
46
|
file
|
35
47
|
end
|
36
|
-
|
37
|
-
def with_no_output
|
38
|
-
old_stdout = $stdout.clone
|
39
|
-
$stdout.reopen(File.new('/dev/null','w'))
|
40
|
-
yield
|
41
|
-
$stdout.reopen(old_stdout)
|
42
|
-
end
|
43
48
|
end
|
49
|
+
|
50
|
+
Augment::BACKENDS['test'] = self
|
44
51
|
end
|
45
|
-
|
46
|
-
def Layer.from_failure(file, klass, method, exception)
|
47
|
-
color = Test::Assertion === exception ? 'red' : 'yellow'
|
48
|
-
|
49
|
-
trace = exception.backtrace.detect { |e| e =~ /test_drink/ }
|
50
|
-
line = trace.match(/:(\d*):/)[1]
|
51
|
-
|
52
|
-
range = Layer.line_to_char_range(file, line.to_i)
|
53
|
-
Layer.new(range, color, exception.message, TestUnitBackend)
|
54
|
-
end
|
55
|
-
|
56
|
-
Augment::BACKENDS['test'] = TestUnitBackend
|
data/lib/flet.rb
CHANGED
@@ -1,20 +1,29 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
##
|
2
|
+
# Horribly disregard any OOP best practices by temporarily redefining
|
3
|
+
# methods for the duration of a block. Stolen from Common Lisp.
|
4
|
+
#
|
5
|
+
# DON'T USE THIS! (unless your *really* mean it and there's no other way)
|
6
|
+
#
|
7
|
+
class Object
|
8
|
+
def flet(bindings) # :nodoc:all
|
9
|
+
old_methods = {}
|
3
10
|
|
4
|
-
bindings.each do |the_method, body|
|
5
|
-
old_methods[the_method] = method(the_method)
|
6
|
-
define_method(the_method, body)
|
7
|
-
end
|
8
|
-
|
9
|
-
begin
|
10
|
-
block.call
|
11
|
-
ensure
|
12
11
|
bindings.each do |the_method, body|
|
13
|
-
|
12
|
+
old_methods[the_method] = method(the_method)
|
13
|
+
define_method(the_method, body)
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
bindings.each do |the_method, body|
|
20
|
+
define_method(the_method) { |*args| old_methods[the_method].call(*args) }
|
21
|
+
end
|
14
22
|
end
|
15
23
|
end
|
16
24
|
end
|
17
25
|
|
26
|
+
# Demo:
|
18
27
|
if $0 == __FILE__
|
19
28
|
puts "foo" # should output "foo"
|
20
29
|
|
@@ -30,9 +30,8 @@ class AnsiColorFrontend < Frontend
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def process_layer(text, layer)
|
33
|
-
text.colorize_range(layer
|
33
|
+
text.colorize_range(layer.range, layer.color)
|
34
34
|
end
|
35
35
|
end
|
36
|
+
Augment::FRONTENDS['ansi'] = self
|
36
37
|
end
|
37
|
-
|
38
|
-
Augment::FRONTENDS['ansi'] = AnsiColorFrontend
|
data/lib/frontends/augment.el
CHANGED
@@ -52,6 +52,8 @@
|
|
52
52
|
|
53
53
|
(defstruct layer begin end color message backend)
|
54
54
|
|
55
|
+
(setq augment-debug t)
|
56
|
+
|
55
57
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
56
58
|
|
57
59
|
(defun augment-layer-from-plist (plist)
|
@@ -75,7 +77,7 @@
|
|
75
77
|
(file-name-directory file) ".augment/"
|
76
78
|
(file-name-nondirectory file)))
|
77
79
|
|
78
|
-
(defun augment-message
|
80
|
+
(defun augment-show-message (&optional point)
|
79
81
|
(interactive)
|
80
82
|
;; find the first layer that the point is between begin and end
|
81
83
|
(layer-message (find (or point (point)) layers :test
|
@@ -93,7 +95,7 @@
|
|
93
95
|
|
94
96
|
(define-key augment-mode-map (kbd "C-c C-s") 'augment-initiate)
|
95
97
|
(define-key augment-mode-map (kbd "C-c C-k") 'augment-clear)
|
96
|
-
(define-key augment-mode-map (kbd "C-c C-i") 'augment-message
|
98
|
+
(define-key augment-mode-map (kbd "C-c C-i") 'augment-show-message)
|
97
99
|
|
98
100
|
(make-local-variable 'layers)
|
99
101
|
|
@@ -107,7 +109,13 @@
|
|
107
109
|
(setq layers nil)
|
108
110
|
(augment-clear)
|
109
111
|
(augment-start-process)
|
110
|
-
(
|
112
|
+
(setq in (concat (or file
|
113
|
+
(expand-file-name (buffer-file-name)))
|
114
|
+
"\n"))
|
115
|
+
|
116
|
+
(process-send-string "augment" (concat (or file
|
117
|
+
(expand-file-name (buffer-file-name)))
|
118
|
+
"\n")))
|
111
119
|
|
112
120
|
(defun augment-start-process ()
|
113
121
|
(unless (get-process "augment") ;; only one should be running at a time
|
@@ -117,6 +125,9 @@
|
|
117
125
|
'augment-filter)))
|
118
126
|
|
119
127
|
(defun augment-filter (process output)
|
128
|
+
(setq out output)
|
129
|
+
;; (if augment-debug (with-current-buffer "*augment-debug*"
|
130
|
+
;; (insert output)))
|
120
131
|
(if (string-match "^Error augmenting \\(.*\\)\\." output)
|
121
132
|
(error "Error augmenting %s." (match-string 1 output))
|
122
133
|
;; layers need to be cached in local var for messages
|
@@ -141,7 +152,8 @@
|
|
141
152
|
|
142
153
|
(defun augment-reset ()
|
143
154
|
(interactive)
|
144
|
-
(
|
155
|
+
(if (get-process "augment")
|
156
|
+
(kill-process "augment"))
|
145
157
|
(augment-clear))
|
146
158
|
|
147
159
|
(provide 'augment)
|
@@ -20,9 +20,8 @@ class HtmlFrontend < Frontend
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def process_layer(text, layer)
|
23
|
-
text.html_colorize_range(layer
|
23
|
+
text.html_colorize_range(layer.range, layer.color)
|
24
24
|
end
|
25
25
|
end
|
26
|
+
Augment::FRONTENDS['html'] = self
|
26
27
|
end
|
27
|
-
|
28
|
-
Augment::FRONTENDS['html'] = HtmlFrontend
|
data/lib/layer.rb
CHANGED
@@ -1,27 +1,79 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Stores metadata about a file. Fields stored are:
|
5
|
+
#
|
6
|
+
# * range - the character range the layer applies to
|
7
|
+
# * color - the color with which to highlight the piece of code
|
8
|
+
# * message - what to display to the user
|
9
|
+
# * backend - which backend generated this layer
|
10
|
+
#
|
11
|
+
# Layer data is stored and emitted in JSON format.
|
12
|
+
#
|
13
|
+
# Note that ranges are always exclusive, so always use three dots!
|
14
|
+
#
|
3
15
|
class Layer
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
16
|
+
attr_accessor :range, :color, :message, :backend
|
17
|
+
|
18
|
+
def initialize(where, color, message, backend, file = nil)
|
19
|
+
@range, @color, @message, @backend = [Layer.interpret_where(where, file),
|
20
|
+
color, message,
|
21
|
+
backend.to_s.downcase.gsub(/backend/, '')]
|
8
22
|
end
|
9
23
|
|
10
|
-
|
11
|
-
|
24
|
+
##
|
25
|
+
# Determines the correct range as defined by a few rules:
|
26
|
+
#
|
27
|
+
# * Numbers get interpreted as line numbers
|
28
|
+
# * Strings get converted into Ranges if they include '...'
|
29
|
+
# * Otherwise Strings are interpreted as Class#method names
|
30
|
+
# * Ranges pass through untouched
|
31
|
+
#
|
32
|
+
def Layer.interpret_where where, file = nil
|
33
|
+
case where
|
34
|
+
when Fixnum
|
35
|
+
Layer.line_to_char_range file, where
|
36
|
+
when String
|
37
|
+
if where =~ /\.\.\./ # grabbing this from JSON strings
|
38
|
+
Layer.range_string_to_char_range where
|
39
|
+
else
|
40
|
+
Layer.method_to_char_range file, where
|
41
|
+
end
|
42
|
+
else
|
43
|
+
where
|
44
|
+
end
|
12
45
|
end
|
13
46
|
|
47
|
+
# Convert a line number to a character range given a file.
|
14
48
|
def self.line_to_char_range(file, line)
|
15
49
|
file = File.read(file).split("\n")
|
16
50
|
start = file[0 ... line - 1].join("\n").size + 2
|
17
51
|
(start ... start + file[line - 1].size)
|
18
52
|
end
|
19
53
|
|
20
|
-
|
21
|
-
|
54
|
+
# Basically implements the inverse of Range#to_s
|
55
|
+
def self.range_string_to_char_range(range)
|
56
|
+
(range.split('...').first.to_i ... range.split('...').last.to_i)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Convert a method name to a character range given a file.
|
60
|
+
def self.method_to_char_range(file, method)
|
61
|
+
# TODO: get smart about what class the method is defined on... ugh
|
62
|
+
start = File.read(file) =~ Regexp.new("def .*#{method.split(/#/).last}")
|
63
|
+
finish = start + 5 # TODO: fix
|
64
|
+
(start ... finish) # we're just layering the word "def" for now
|
22
65
|
end
|
23
66
|
|
24
|
-
|
25
|
-
|
67
|
+
# Slurp up layer data from stored JSON given the original file.
|
68
|
+
def self.read(original_file)
|
69
|
+
return [] if !File.exist?(Augment.augment_path(original_file))
|
70
|
+
layers = JSON.parse(File.read(Augment.augment_path(original_file)))
|
71
|
+
layers.map!{ |l| Layer.new(l['range'], l['color'], l['message'], l['backend']) }
|
72
|
+
layers.sort_by{ |l| l.range.begin }.reverse
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_json
|
76
|
+
{ 'range' => @range, 'color' => @color, 'message' => @message,
|
77
|
+
'backend' => @backend}.to_json
|
26
78
|
end
|
27
79
|
end
|
data/spec/ansi_frontend_spec.rb
CHANGED
@@ -23,4 +23,8 @@ describe Frontend, " when outputting ANSI color" do
|
|
23
23
|
output.to_s.should match(/\e\[#{String::COLOR_LOOKUP['red']}m *assert/)
|
24
24
|
output.to_s.should match(/\e\[#{String::COLOR_LOOKUP['yellow']}m *junk/)
|
25
25
|
end
|
26
|
+
|
27
|
+
it "shouldn't complain if the layer file doesn't exist" do
|
28
|
+
Layer.read(__FILE__) # should not raise error
|
29
|
+
end
|
26
30
|
end
|
data/spec/color_backend_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__)
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe ColoringBackend, " when augmenting by color" do
|
5
5
|
before do
|
6
6
|
FileUtils.cd(PROJECT_ROOT)
|
7
7
|
FileUtils.rm_r('lib/.augment') rescue nil
|
@@ -18,15 +18,15 @@ describe Backend, " when augmenting by color" do
|
|
18
18
|
layers = Layer.read('lib/drink.rb')
|
19
19
|
layers.size.should == 4
|
20
20
|
|
21
|
-
layers[0]
|
22
|
-
layers[1]
|
23
|
-
layers[2]
|
24
|
-
layers[3]
|
21
|
+
layers[0].color.should == 'black'
|
22
|
+
layers[1].color.should == 'green'
|
23
|
+
layers[2].color.should == 'red'
|
24
|
+
layers[3].color.should == 'white'
|
25
25
|
|
26
|
-
layers[0]
|
27
|
-
layers[1]
|
28
|
-
layers[2]
|
29
|
-
layers[3]
|
30
|
-
layers.map{ |l| l
|
26
|
+
layers[0].range.should == (575 ... 580)
|
27
|
+
layers[1].range.should == (495 ... 500)
|
28
|
+
layers[2].range.should == (405 ... 408)
|
29
|
+
layers[3].range.should == (245 ... 250)
|
30
|
+
layers.map{ |l| l.backend }.uniq.should == ['coloring']
|
31
31
|
end
|
32
32
|
end
|
data/spec/emacs-frontend-test.el
CHANGED
@@ -12,13 +12,16 @@
|
|
12
12
|
|
13
13
|
(require 'elunit) ;; See http://www.emacswiki.org/cgi-bin/wiki/ElUnit
|
14
14
|
(require 'augment)
|
15
|
-
(require 'flymake)
|
15
|
+
(require 'flymake) ;; for flymake-read-file-to-string
|
16
16
|
|
17
17
|
;; in case it hasn't been properly installed
|
18
18
|
(add-to-list 'exec-path (expand-file-name "../bin"))
|
19
19
|
|
20
20
|
(elunit-clear-suites)
|
21
|
-
(
|
21
|
+
(lexical-let ((spec-dir (file-name-nondirectory (buffer-file-name (current-buffer)))))
|
22
|
+
(defsuite augment-suite nil :setup-hook (lambda () (cd spec-dir))))
|
23
|
+
|
24
|
+
(augment-reset)
|
22
25
|
|
23
26
|
(deftest layer-from-plist augment-suite
|
24
27
|
"The layer struct should populated from a plist."
|
@@ -49,9 +52,9 @@
|
|
49
52
|
(json-array-type 'list)
|
50
53
|
(layers (mapcar #'augment-layer-from-plist
|
51
54
|
(json-read-file "fixtures/layers.json"))))
|
52
|
-
(assert-equal "cons" (augment-message
|
53
|
-
(assert-equal "car" (augment-message
|
54
|
-
(assert-equal "cdr" (augment-message
|
55
|
+
(assert-equal "cons" (augment-show-message 5))
|
56
|
+
(assert-equal "car" (augment-show-message 16))
|
57
|
+
(assert-equal "cdr" (augment-show-message 29))))
|
55
58
|
|
56
59
|
(deftest augment-filter augment-suite
|
57
60
|
(with-test-buffer
|
@@ -60,4 +63,25 @@
|
|
60
63
|
(augment-filter nil (flymake-read-file-to-string "fixtures/augment-output.txt"))
|
61
64
|
(assert-overlay 2)))
|
62
65
|
|
63
|
-
(
|
66
|
+
(deftest no-problems-file augment-suite
|
67
|
+
(save-excursion
|
68
|
+
(find-file "fixtures/working_test.rb")
|
69
|
+
(augment-initiate)
|
70
|
+
(sleep-for 1)
|
71
|
+
(kill-buffer "working_test.rb")))
|
72
|
+
|
73
|
+
(deftest fix-all-problems augment-suite
|
74
|
+
(save-excursion
|
75
|
+
(find-file "fixtures/fix_test.rb")
|
76
|
+
(augment-initiate)
|
77
|
+
(sleep-for 1)
|
78
|
+
(assert-overlay 88)
|
79
|
+
(beginning-of-buffer)
|
80
|
+
(replace-regexp "assert false" "assert true")
|
81
|
+
(augment-initiate)
|
82
|
+
(sleep-for 1)
|
83
|
+
(assert-no-overlay 77)
|
84
|
+
(revert-buffer t t)
|
85
|
+
(kill-buffer "fix_test.rb")))
|
86
|
+
|
87
|
+
(elunit-quiet "augment-suite")
|
@@ -6,10 +6,12 @@ class Drink
|
|
6
6
|
@proof = args[:proof]
|
7
7
|
@color = args[:color]
|
8
8
|
end
|
9
|
-
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def self.load_drinks
|
11
|
+
@vodka = Drink.new :name => 'Vodka', :proof => 80, :color => 'white'
|
12
|
+
@kahlua = Drink.new :name => 'Kahlua', :proof => 40, :color => 'brown'
|
13
|
+
@tomatoJuice = Drink.new :name => 'Tomato Juice', :proof => 0, :color => 'red'
|
14
|
+
@mikesHardLime = Drink.new :name => 'Mike\'s Hard Lime', :proof => 8, :color => 'green'
|
15
|
+
@jager = Drink.new :name => 'Jagermeister', :proof => 40, :color => 'black'
|
16
|
+
end
|
17
|
+
end
|
data/spec/fixtures/layers.json
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
[{"message":"cons", "color":"red", "range":"1...12"},
|
2
|
-
{"message":"car", "color":"green", "range":"13...24"},
|
3
|
-
{"message":"cdr", "color":"blue", "range":"25...36"}]
|
1
|
+
[{"message":"cons", "color":"red", "range":"1...12", "backend":"coloring"},
|
2
|
+
{"message":"car", "color":"green", "range":"13...24", "backend":"coloring"},
|
3
|
+
{"message":"cdr", "color":"blue", "range":"25...36", "backend":"coloring"}]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe FlogBackend, " when augmenting flog results" do
|
6
|
+
before do
|
7
|
+
FileUtils.cd(PROJECT_ROOT)
|
8
|
+
FileUtils.rm_r('lib/.augment') rescue nil
|
9
|
+
|
10
|
+
FlogBackend.run('lib/drink.rb')
|
11
|
+
@layers = Layer.read('lib/drink.rb')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should create layers for all methods" do
|
15
|
+
@layers.size.should == 2
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should include flog levels in the messages" do
|
19
|
+
@layers.first.message.should =~ /9.5/
|
20
|
+
@layers.last.message.should =~ /5.0/
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should color different levels of ugliness different colors"
|
24
|
+
end
|
data/spec/html_frontend_spec.rb
CHANGED
@@ -14,11 +14,3 @@ describe Frontend, " when outputting HTML" do
|
|
14
14
|
output.to_s.should include("<span style='color: white;'>white</span>")
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
18
|
-
describe Layer, " when converting line range to char range" do
|
19
|
-
it "should convert properly" do
|
20
|
-
Layer.line_to_char_range('test/test_drink.rb', 10).should == (153 ... 176)
|
21
|
-
Layer.line_to_char_range('test/test_drink.rb', 3).should == (22 ... 61)
|
22
|
-
Layer.line_to_char_range('test/test_drink.rb', 17).should == (289 ... 332)
|
23
|
-
end
|
24
|
-
end
|
data/spec/layer_spec.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Layer, " when creating ranges" do
|
5
|
+
before do
|
6
|
+
FileUtils.cd(PROJECT_ROOT)
|
7
|
+
@filename = "test/test_drink.rb"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should get range from a line number" do
|
11
|
+
Layer.interpret_where(5, @filename).should == (85 ... 97)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should get range from a range string" do
|
15
|
+
Layer.interpret_where("22 ... 33").should == (22 ... 33)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should get range from a method name" do
|
19
|
+
Layer.interpret_where("#test_might_error", @filename).should == (63 ... 68)
|
20
|
+
Layer.interpret_where("#test_will_fail", @filename).should == (230 ... 235)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should get range from an ambiguous method name"
|
24
|
+
it "should get range from a class method name"
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Layer, " when working with JSON" do
|
28
|
+
before do
|
29
|
+
FileUtils.cd(PROJECT_ROOT + '/..')
|
30
|
+
# have to create this on the fly since "augment clear"ing the spec dir will erase it. =(
|
31
|
+
Dir.mkdir('.augment') rescue nil
|
32
|
+
FileUtils.cp('layers.json', '.augment/layers.json')
|
33
|
+
@layers = Layer.read('layers.json').reverse
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should read from a file" do
|
37
|
+
@layers.map{ |l| l.message }.should == ['cons', 'car', 'cdr']
|
38
|
+
@layers.map{ |l| l.color }.should == ['red', 'green', 'blue']
|
39
|
+
@layers.map{ |l| l.range }.should == [(1...12), (13...24), (25...36)]
|
40
|
+
@layers.map{ |l| l.backend }.uniq.should == ['coloring']
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should output valid JSON" do
|
44
|
+
@layers.to_json.should == File.read('layers.json').gsub(/[ \n]/, '')
|
45
|
+
end
|
46
|
+
|
47
|
+
after do
|
48
|
+
FileUtils.rm_rf('.augment')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe Layer, " when converting line range to char range" do
|
53
|
+
it "should convert properly" do
|
54
|
+
FileUtils.cd(PROJECT_ROOT)
|
55
|
+
Layer.line_to_char_range('test/test_drink.rb', 10).should == (153 ... 176)
|
56
|
+
Layer.line_to_char_range('test/test_drink.rb', 3).should == (22 ... 61)
|
57
|
+
Layer.line_to_char_range('test/test_drink.rb', 17).should == (289 ... 332)
|
58
|
+
end
|
59
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/test_backend_spec.rb
CHANGED
@@ -2,27 +2,32 @@ $LOAD_PATH << File.dirname(__FILE__)
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe TestUnitBackend, " when augmenting test results" do
|
6
6
|
before do
|
7
7
|
FileUtils.cd(PROJECT_ROOT)
|
8
8
|
FileUtils.rm_r('test/.augment') rescue nil
|
9
9
|
|
10
10
|
TestUnitBackend.run('test/test_drink.rb')
|
11
|
+
@layers = Layer.read('test/test_drink.rb')
|
11
12
|
end
|
12
13
|
|
13
14
|
it "should color failing/erroring tests" do
|
14
|
-
|
15
|
-
layers
|
16
|
-
|
17
|
-
layers.last['color'].should == 'yellow'
|
15
|
+
@layers.first.color.should == 'red'
|
16
|
+
@layers.last.color.should == 'yellow'
|
17
|
+
end
|
18
18
|
|
19
|
-
|
19
|
+
it "should set the range to the line of the error/failure" do
|
20
|
+
@layers.first.range.should == (289 ... 332)
|
21
|
+
@layers.last.range.should == (85 ... 97)
|
20
22
|
end
|
21
23
|
|
22
24
|
it "should include failure message" do
|
23
|
-
layers = Layer.read('test/test_drink.rb')
|
24
|
-
layers.first
|
25
|
-
layers.last
|
26
|
-
|
25
|
+
@layers = Layer.read('test/test_drink.rb')
|
26
|
+
@layers.first.message.should =~ /bad length/
|
27
|
+
@layers.last.message.should =~ /undefined local variable or method/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set the backend field" do
|
31
|
+
@layers.map{ |l| l.backend }.uniq.should == ['testunit']
|
27
32
|
end
|
28
33
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: augment
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2007-10
|
6
|
+
version: 1.0.1
|
7
|
+
date: 2007-11-10 00:00:00 -08:00
|
8
8
|
summary: Augment is a system for collecting and displaying code metadata.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -30,32 +30,38 @@ authors:
|
|
30
30
|
- Phil Hagelberg
|
31
31
|
files:
|
32
32
|
- COPYING
|
33
|
-
- TODO
|
34
33
|
- History.txt
|
35
34
|
- Manifest.txt
|
36
35
|
- README.txt
|
37
36
|
- Rakefile
|
37
|
+
- TODO
|
38
38
|
- bin/augment
|
39
39
|
- lib/augment.rb
|
40
|
-
- lib/layer.rb
|
41
|
-
- lib/flet.rb
|
42
40
|
- lib/backends/backend.rb
|
41
|
+
- lib/backends/clear_backend.rb
|
43
42
|
- lib/backends/coloring_backend.rb
|
43
|
+
- lib/backends/flog_backend.rb
|
44
44
|
- lib/backends/test_unit_backend.rb
|
45
|
-
- lib/frontends/frontend.rb
|
46
45
|
- lib/frontends/ansi_color_frontend.rb
|
47
|
-
- lib/frontends/html_frontend.rb
|
48
46
|
- lib/frontends/augment.el
|
47
|
+
- lib/frontends/frontend.rb
|
48
|
+
- lib/frontends/html_frontend.rb
|
49
|
+
- lib/layer.rb
|
50
|
+
- lib/flet.rb
|
49
51
|
- spec/ansi_frontend_spec.rb
|
50
52
|
- spec/color_backend_spec.rb
|
51
53
|
- spec/emacs-frontend-test.el
|
52
|
-
- spec/
|
53
|
-
- spec/spec_helper.rb
|
54
|
-
- spec/test_backend_spec.rb
|
54
|
+
- spec/layer_spec.rb
|
55
55
|
- spec/fixtures/augment-output.txt
|
56
|
-
- spec/fixtures/layers.json
|
57
56
|
- spec/fixtures/drinks/lib/drink.rb
|
58
57
|
- spec/fixtures/drinks/test/test_drink.rb
|
58
|
+
- spec/fixtures/layers.json
|
59
|
+
- spec/fixtures/fix_test.rb
|
60
|
+
- spec/fixtures/working_test.rb
|
61
|
+
- spec/html_frontend_spec.rb
|
62
|
+
- spec/spec_helper.rb
|
63
|
+
- spec/test_backend_spec.rb
|
64
|
+
- spec/flog_backend_spec.rb
|
59
65
|
test_files: []
|
60
66
|
|
61
67
|
rdoc_options:
|
@@ -80,7 +86,7 @@ dependencies:
|
|
80
86
|
requirements:
|
81
87
|
- - ">="
|
82
88
|
- !ruby/object:Gem::Version
|
83
|
-
version: 1.0
|
89
|
+
version: 1.1.0
|
84
90
|
version:
|
85
91
|
- !ruby/object:Gem::Dependency
|
86
92
|
name: json
|
@@ -98,5 +104,5 @@ dependencies:
|
|
98
104
|
requirements:
|
99
105
|
- - ">="
|
100
106
|
- !ruby/object:Gem::Version
|
101
|
-
version: 1.
|
107
|
+
version: 1.3.0
|
102
108
|
version:
|