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.
@@ -3,3 +3,6 @@
3
3
  * Works with a minimal set of backends and frontends
4
4
  * Birthday!
5
5
 
6
+ == 1.0.1 / 2007-11-10
7
+
8
+ * Works with newly-released miniunit 1.1.0.
@@ -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/html_frontend_spec.rb
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
- The various frontends have their own executables that provide access
24
- to the layer metadata once it's stored. The simplest frontend is
25
- +augment_color+ which outputs the layers via ANSI color codes to the
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
- $ augment_color test/test_foo.rb
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
- * Emacs (planned)
77
- * Vim (planned)
75
+ * HTML
76
+ * Emacs
78
77
  * Textmate (planned)
78
+ * Vim (planned, need help)
79
79
 
80
80
  == Issues
81
81
 
82
- * Not really, um, written yet.
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.1']
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 -r html/* technomancy@rubyforge.org:/var/www/gforge-projects/augment/")
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
- = Backends
2
- == test/unit
3
- * Discover char range from exception
4
-
5
- * Report rubyforge bug when doing "rubyforge config" on project rinari
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
@@ -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
- puts " or: augment --interactive"
12
- puts "Output or store metadata regarding code."
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
 
@@ -10,7 +10,7 @@ require 'backend'
10
10
  require 'frontend'
11
11
 
12
12
  class Augment
13
- VERSION = '1.0.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
- while true
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] }
@@ -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.1"
3
+ gem 'miniunit', ">= 1.1.0"
4
4
  require 'test/unit'
5
5
  end
6
6
 
7
- module Test
8
- def Unit.puke(*args) # pass on failure info
9
- TestUnitBackend.record_failure(*args)
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 record_failure(klass, method, exception)
34
+ def failure_bucket(klass, method, exception)
28
35
  # FIXME: errors here could actually occur in impl rather than test file
29
- (@layers[@file] ||= []) << Layer.from_failure(@file, klass, method, exception)
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
@@ -1,20 +1,29 @@
1
- def Object.flet(bindings, &block)
2
- old_methods = {}
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
- define_method(the_method) { |*args| old_methods[the_method].call(*args) }
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['range'], layer['color'])
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
@@ -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-at-point (&optional point)
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-at-point)
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
- (process-send-string "augment" (concat (or file (buffer-file-name)) "\n")))
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
- (kill-process "augment")
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['range'], layer['color'])
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
@@ -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
- def initialize(range, color, message, backend)
5
- range = (range.split('...').first.to_i ... range.split('...').last.to_i) if range.is_a? String
6
- @attrs = { 'range' => range, 'color' => color, 'message' => message,
7
- 'backend' => backend.to_s.downcase.gsub(/backend/, '')}
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
- def self.read(original_file)
11
- JSON.parse(File.read(Augment.augment_path(original_file))).map{ |l| Layer.new(l['range'], l['color'], l['message'], l['backend']) }.sort_by{ |l| l['range'].begin }.reverse
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
- def to_json
21
- @attrs.to_json
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
- def [](attr)
25
- @attrs[attr]
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
@@ -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
@@ -1,7 +1,7 @@
1
1
  $LOAD_PATH << File.dirname(__FILE__)
2
2
  require 'spec_helper'
3
3
 
4
- describe Backend, " when augmenting by color" do
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]['color'].should == 'black'
22
- layers[1]['color'].should == 'green'
23
- layers[2]['color'].should == 'red'
24
- layers[3]['color'].should == 'white'
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]['range'].should == (531 ... 536)
27
- layers[1]['range'].should == (456 ... 461)
28
- layers[2]['range'].should == (371 ... 374)
29
- layers[3]['range'].should == (221 ... 226)
30
- layers.map{ |l| l['backend'] }.uniq.should == ['coloring']
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
@@ -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
- (defsuite augment-suite nil)
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-at-point 5))
53
- (assert-equal "car" (augment-message-at-point 16))
54
- (assert-equal "cdr" (augment-message-at-point 29))))
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
- (elunit "augment-suite")
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
- 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'
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
@@ -0,0 +1,7 @@
1
+ require 'test/unit'
2
+
3
+ class FixTest < Test::Unit::TestCase
4
+ def test_might_error
5
+ assert false
6
+ end
7
+ end
@@ -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,7 @@
1
+ require 'test/unit'
2
+
3
+ class WorkingTest < Test::Unit::TestCase
4
+ def test_works_fine
5
+ assert_equal 2, 1 + 1
6
+ end
7
+ end
@@ -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
@@ -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
@@ -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
@@ -1,4 +1,5 @@
1
1
  $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
2
2
  require 'augment'
3
+ require 'fileutils'
3
4
 
4
5
  PROJECT_ROOT = File.expand_path(File.dirname(__FILE__) + '/fixtures/drinks/') unless defined? PROJECT_ROOT
@@ -2,27 +2,32 @@ $LOAD_PATH << File.dirname(__FILE__)
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Backend, " when augmenting test results" do
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
- File.should exist(Augment.augment_path('test/test_drink.rb'))
15
- layers = Layer.read('test/test_drink.rb')
16
- layers.first['color'].should == 'red'
17
- layers.last['color'].should == 'yellow'
15
+ @layers.first.color.should == 'red'
16
+ @layers.last.color.should == 'yellow'
17
+ end
18
18
 
19
- layers.first['range'].should == (289 ... 332)
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['message'].should =~ /bad length/
25
- layers.last['message'].should =~ /undefined local variable or method/
26
- layers.map{ |l| l['backend'] }.uniq.should == ['testunit']
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
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.0
7
- date: 2007-10-27 00:00:00 -07:00
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/html_frontend_spec.rb
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.1
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.2.2
107
+ version: 1.3.0
102
108
  version: