spackle 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +166 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/bin/ruby-project-root +14 -0
- data/bin/spackle +14 -0
- data/bin/spackle-vim-load-quickfix +47 -0
- data/bin/spackle-vim-open +49 -0
- data/lib/spackle/commandline.rb +53 -0
- data/lib/spackle/configuration.rb +37 -0
- data/lib/spackle/error.rb +31 -0
- data/lib/spackle/helpers/ruby_project_root.rb +34 -0
- data/lib/spackle/output/base.rb +44 -0
- data/lib/spackle/output/vim_quickfix.rb +7 -0
- data/lib/spackle/output.rb +2 -0
- data/lib/spackle/spec/base_formatter.rb +22 -0
- data/lib/spackle/spec/spackle_formatter.rb +14 -0
- data/lib/spackle/spec.rb +1 -0
- data/lib/spackle.rb +104 -0
- data/spec/integration_spec.rb +84 -0
- data/spec/spackle/commandline_spec.rb +48 -0
- data/spec/spackle/configuration_spec.rb +43 -0
- data/spec/spackle/error_spec.rb +34 -0
- data/spec/spackle/output/base_spec.rb +53 -0
- data/spec/spackle/output/vim_quickfix_spec.rb +25 -0
- data/spec/spackle/spec/base_formatter_spec.rb +15 -0
- data/spec/spackle/spec/spackle_formatter_spec.rb +58 -0
- data/spec/spackle_error_fixture.rb +10 -0
- data/spec/spackle_spec.rb +203 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/test_app_helper.rb +55 -0
- data/support/vim/spackle.vim +17 -0
- data/test_app/lib/error_raiser.rb +7 -0
- data/test_app/lib/method_typo.rb +7 -0
- data/test_app/lib/missing_end.rb +7 -0
- data/test_app/lib/working_class.rb +7 -0
- data/test_app/spec/error_raiser_spec.rb +14 -0
- data/test_app/spec/failing_working_class_spec.rb +14 -0
- data/test_app/spec/method_typo_spec.rb +14 -0
- data/test_app/spec/missing_end_spec.rb +13 -0
- data/test_app/spec/passing_working_class_spec.rb +14 -0
- data/test_app/spec/spec_helper.rb +8 -0
- metadata +127 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Rick Lee-Morlang
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
= Spackle
|
2
|
+
|
3
|
+
<em>Smoothing out the gaps between the Rubyist and the Ruby.</em>
|
4
|
+
|
5
|
+
Well, honestly, it only fills in the gaps between RSpec and Vim right now,
|
6
|
+
but that's a good start. Cucumber support is in the works, and perhaps a
|
7
|
+
few other surprises if I make the time.
|
8
|
+
|
9
|
+
Patches supporting other editors gladly accepted. Most people aren't very
|
10
|
+
editor-agnostic, but Spackle doesn't care! (Or, at least, it wouldn't if
|
11
|
+
you patched it with support for your amazing editor that's surely better
|
12
|
+
than mine.)
|
13
|
+
|
14
|
+
== Elevator Pitch
|
15
|
+
|
16
|
+
Spackle tells your editor about the errors in your code. No more need to
|
17
|
+
visually scan your test output for errors, filenames, and line numbers.
|
18
|
+
Just tell your editor to jump to the next error location.
|
19
|
+
|
20
|
+
== Features
|
21
|
+
|
22
|
+
* custom RSpec formatters that generate output compatible with
|
23
|
+
Vim's quickfix functionality
|
24
|
+
* a simple Vim plugin to allow a quickfix list to be loaded
|
25
|
+
from a file
|
26
|
+
* shell scripts to glue Spackle's output and Vim together
|
27
|
+
* easy to use?
|
28
|
+
|
29
|
+
== Quick Installation
|
30
|
+
|
31
|
+
gem install spackle --source http://gemcutter.org
|
32
|
+
spackle --install vim # described below
|
33
|
+
echo 'Spackle.configuration.set_defaults_for :vim' > ~/.spackle
|
34
|
+
|
35
|
+
== Configuration and Usage
|
36
|
+
|
37
|
+
For a tool that doesn't do a heck of alot, it's pretty configurable.
|
38
|
+
If it <b>could</b> do something else, it'd be easy to tell it how to do
|
39
|
+
it with either a <tt>.spackle</tt> file in your home directory, or a
|
40
|
+
<tt>.spackle</tt> file in your project's root directory.
|
41
|
+
|
42
|
+
If Spackle is useful to you, I'd love to hear about it.
|
43
|
+
|
44
|
+
=== PATH
|
45
|
+
|
46
|
+
Spackle installs a few utility scripts in the bin directory where
|
47
|
+
executables are installed by your system's Rubygems. If you've installed
|
48
|
+
Spackle as root, this should be fine. If you've installed Spackle as a
|
49
|
+
regular user, you need to make sure the appropriate bin directory is
|
50
|
+
in your path.
|
51
|
+
|
52
|
+
To test your configuration, run +which spackle+ in your terminal. If
|
53
|
+
you don't see any output, your PATH variable is not correctly configured
|
54
|
+
for use with user-installed gems.
|
55
|
+
|
56
|
+
See your Rubygems documentation for more information about this.
|
57
|
+
|
58
|
+
=== Spackle dotfile
|
59
|
+
|
60
|
+
Without a dotfile configured, Spackle won't do anything. This is so
|
61
|
+
you can make Spackle a dependency of your project and integrate it
|
62
|
+
into your code, yet leave its usage up to each individual developer.
|
63
|
+
|
64
|
+
Spackle reads its configuration from a <tt>.spackle</tt> file, which it looks
|
65
|
+
for in your home directory first, and in the root directory of your
|
66
|
+
project second. Spackle configuration in your project directory takes
|
67
|
+
precedence over any in your home directory, so you can override global
|
68
|
+
settings on a per-project basis if you like.
|
69
|
+
|
70
|
+
Example <tt>.spackle</tt> for Vim users.
|
71
|
+
|
72
|
+
Spackle.configure do |c|
|
73
|
+
c.set_defaults_for :vim
|
74
|
+
end
|
75
|
+
|
76
|
+
See Spackle::Configuration for more information.
|
77
|
+
|
78
|
+
=== RSpec
|
79
|
+
|
80
|
+
Add to your spec_helper.rb:
|
81
|
+
|
82
|
+
require "spackle"
|
83
|
+
Spackle.init :with => :spec_formatter
|
84
|
+
|
85
|
+
Now whenever RSpec runs, Spackle will listen in to your test results and
|
86
|
+
relay information about any errors to your editor.
|
87
|
+
|
88
|
+
=== Vim
|
89
|
+
|
90
|
+
Spackle needs a tiny Vim plugin installed to function properly with Vim.
|
91
|
+
Simply run +spackle install vim+ and Spackle will copy its plugin into
|
92
|
+
your <tt>.vim/plugins</tt> directory.
|
93
|
+
|
94
|
+
<b>Optional:</b>
|
95
|
+
Spackle also comes with a helper script for invoking Vim with a session
|
96
|
+
named after your project's parent directory. It's called <tt>spackle-vim-open</tt>.
|
97
|
+
If you'd like to use it, you'll probably want to add an alias to your
|
98
|
+
<tt>.profile</tt> or <tt>.bashrc</tt>. Example:
|
99
|
+
|
100
|
+
alias e='spackle-vim-open'
|
101
|
+
|
102
|
+
== Architecture
|
103
|
+
|
104
|
+
Spackle's architecture consists of three components.
|
105
|
+
|
106
|
+
NOTE: Some of this information looks forward to a future version of Spackle
|
107
|
+
that, at the moment, is fictional. So if you go looking for some of the things
|
108
|
+
referenced here and you can't find them, that's probably why. (Or it could be
|
109
|
+
an error in this document!)
|
110
|
+
|
111
|
+
Error Parser Adapters
|
112
|
+
* integrate with test harnesses like RSpec and Cucumber
|
113
|
+
* or integrate with Ruby's standard Error API
|
114
|
+
* or parse Ruby's standard backtrace output
|
115
|
+
* convert error output into a generic intermediary Spackle::Error format
|
116
|
+
* pass the errors to Spackle's core for reformatting and output
|
117
|
+
* found in Spackle::Spec, Spackle::Cucumber and Spackle::Ruby
|
118
|
+
|
119
|
+
Spackle Core
|
120
|
+
* glues all the pieces together
|
121
|
+
* loads user configuration
|
122
|
+
* tries to do as much as it can automagically
|
123
|
+
* tries to stay out of your way
|
124
|
+
* routes Spackle::Error objects from the Adapters, through an
|
125
|
+
Output Formatter, and finally to an output file
|
126
|
+
* triggers a callback after every test run that can send error
|
127
|
+
information to your editor
|
128
|
+
|
129
|
+
Output Formatters
|
130
|
+
* convert the generic Error format into an output-specific format
|
131
|
+
for your callback to handle
|
132
|
+
* found in Spackle::Output
|
133
|
+
|
134
|
+
Spackle's core configuration, tries to do as much automagically as it can,
|
135
|
+
and tries to stay out of the way. It aids the models by routing Errors to the
|
136
|
+
configured output formatter.
|
137
|
+
|
138
|
+
== Known Issues
|
139
|
+
|
140
|
+
* Spackle assumes you're using something UNIXy. If you're not, it likely
|
141
|
+
won't work. I have no interest in working on this, but I'll gladly
|
142
|
+
pull your patches.
|
143
|
+
* Spackle's current implementation only catches test failures from RSpec.
|
144
|
+
Other hooks are in the works.
|
145
|
+
|
146
|
+
== Credits
|
147
|
+
|
148
|
+
Spackle was inspired by https://wincent.com/blog/running-rspec-specs-from-inside-vim
|
149
|
+
|
150
|
+
== Note on Patches/Pull Requests
|
151
|
+
|
152
|
+
This section was generated by Jeweler's boilerplate, but it seems
|
153
|
+
pretty sensible.
|
154
|
+
|
155
|
+
* Fork the project.
|
156
|
+
* Make your feature addition or bug fix.
|
157
|
+
* Add tests for it. This is important so I don't break it in a
|
158
|
+
future version unintentionally.
|
159
|
+
* Commit, do not mess with rakefile, version, or history.
|
160
|
+
(if you want to have your own version, that is fine but
|
161
|
+
bump version in a commit by itself I can ignore when I pull)
|
162
|
+
* Send me a pull request. Bonus points for topic branches.
|
163
|
+
|
164
|
+
== Copyright
|
165
|
+
|
166
|
+
Copyright (c) 2009 Rick Lee-Morlang. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "spackle"
|
8
|
+
gem.summary = %Q{Spackle tells your editor about the errors in your code}
|
9
|
+
gem.description = %Q{
|
10
|
+
Spackle tells your editor about the errors in your code. No more need to
|
11
|
+
visually scan your test output for errors, filenames, and line numbers.
|
12
|
+
Just tell your editor to jump to the next error location.
|
13
|
+
}
|
14
|
+
gem.email = "rick@lee-morlang.com"
|
15
|
+
gem.homepage = "http://github.com/rleemorlang/spackle"
|
16
|
+
gem.authors = ["Rick Lee-Morlang"]
|
17
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
34
|
+
spec.rcov = true
|
35
|
+
end
|
36
|
+
|
37
|
+
task :spec => :check_dependencies
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "spackle #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle/helpers/ruby_project_root'
|
6
|
+
|
7
|
+
project_root = Spackle::Helpers::RubyProjectRoot.search Dir.pwd
|
8
|
+
|
9
|
+
if project_root.nil?
|
10
|
+
exit 1
|
11
|
+
else
|
12
|
+
puts project_root
|
13
|
+
end
|
14
|
+
|
data/bin/spackle
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle'
|
6
|
+
require 'spackle/commandline'
|
7
|
+
|
8
|
+
begin
|
9
|
+
Spackle::Commandline.parse ARGV
|
10
|
+
rescue => err
|
11
|
+
STDERR.puts err.message
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle/helpers/ruby_project_root'
|
6
|
+
|
7
|
+
# Load a Vim Quickfix file in an active vim session.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# spackle-vim-load-quickfix [servername] quickfix_file
|
11
|
+
#
|
12
|
+
# If servername is specified, try to use it as the vim
|
13
|
+
# server. Otherwise, assume the name for the vim server
|
14
|
+
# is the from ruby-project-root -basename, if
|
15
|
+
# successful. If no Ruby project root was found, use
|
16
|
+
# DEFAULT as the servername.
|
17
|
+
#
|
18
|
+
# If the server doesn't exist, we'll create a new
|
19
|
+
# gvim session.
|
20
|
+
#
|
21
|
+
|
22
|
+
def servername_from_arguments
|
23
|
+
ARGV.shift if ARGV.count == 2
|
24
|
+
end
|
25
|
+
|
26
|
+
def servername_from_project_root
|
27
|
+
project_root = Spackle::Helpers::RubyProjectRoot.search Dir.pwd
|
28
|
+
File.basename(project_root) if project_root
|
29
|
+
end
|
30
|
+
|
31
|
+
def servername
|
32
|
+
@servername ||= servername_from_arguments || servername_from_project_root || "DEFAULT"
|
33
|
+
end
|
34
|
+
|
35
|
+
def server_running?
|
36
|
+
!`gvim --serverlist`.grep(/#{servername}/i).empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
unless server_running?
|
40
|
+
system %{gvim --servername #{servername}}
|
41
|
+
sleep 1
|
42
|
+
end
|
43
|
+
|
44
|
+
system %{gvim --servername #{servername} --remote-send "<ESC>" &> /dev/null}
|
45
|
+
system %{gvim --servername #{servername} --remote-expr "LoadSpackleQuickfix('#{ARGV.first}')" &> /dev/null}
|
46
|
+
system %{gvim --servername #{servername} --remote-send "<ESC><C-W>p" &> /dev/null}
|
47
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle/helpers/ruby_project_root'
|
6
|
+
|
7
|
+
# Load a Vim Quickfix file in an active vim session.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# spackle-vim-load-quickfix [servername] quickfix_file
|
11
|
+
#
|
12
|
+
# If servername is specified, try to use it as the vim
|
13
|
+
# server. Otherwise, assume the name for the vim server
|
14
|
+
# is the from ruby-project-root -basename, if
|
15
|
+
# successful. If no Ruby project root was found, use
|
16
|
+
# DEFAULT as the servername.
|
17
|
+
#
|
18
|
+
# If the server doesn't exist, we'll create a new
|
19
|
+
# gvim session.
|
20
|
+
#
|
21
|
+
|
22
|
+
def servername_from_arguments
|
23
|
+
ARGV.count.times do |index|
|
24
|
+
if ARGV[index] == "--servername"
|
25
|
+
ARGV.delete_at index
|
26
|
+
return ARGV.delete_at_index
|
27
|
+
end
|
28
|
+
end
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def servername_from_project_root
|
33
|
+
project_root = Spackle::Helpers::RubyProjectRoot.search Dir.pwd
|
34
|
+
File.basename(project_root) if project_root
|
35
|
+
end
|
36
|
+
|
37
|
+
def servername
|
38
|
+
servername_from_arguments || servername_from_project_root || "DEFAULT"
|
39
|
+
end
|
40
|
+
|
41
|
+
def arguments
|
42
|
+
arguments = ['gvim', '--servername', servername]
|
43
|
+
unless ARGV.empty?
|
44
|
+
arguments << "--remote-silent"
|
45
|
+
arguments += ARGV
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
system *arguments
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
|
5
|
+
module Spackle
|
6
|
+
class Commandline
|
7
|
+
class << self
|
8
|
+
def install(mod)
|
9
|
+
case mod.to_sym
|
10
|
+
when :vim
|
11
|
+
src = File.join(File.dirname(__FILE__), "/../../support/vim/spackle.vim")
|
12
|
+
dest = File.expand_path "~/.vim/plugin"
|
13
|
+
raise "No such directory #{dest} -- cannot install Vim plugin" unless File.directory?(dest)
|
14
|
+
FileUtils.copy src, dest
|
15
|
+
puts "spackle.vim installed in #{dest}"
|
16
|
+
else
|
17
|
+
raise "Unrecognized module '#{mod}' -- cannot install"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def show_error(message)
|
22
|
+
puts message
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(options)
|
26
|
+
opts = OptionParser.new do |opts|
|
27
|
+
opts.banner = "Usage: spackle --install vim\n" +
|
28
|
+
" spackle [rubyscript] [args_for_script]"
|
29
|
+
|
30
|
+
opts.separator " "
|
31
|
+
opts.separator "Options:"
|
32
|
+
|
33
|
+
opts.on("-i", "--install MODULE", "Install a Spackle module.", "Choices: vim") do |mod|
|
34
|
+
install(mod)
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("-h", "--help", "-?", "this help screen") do
|
38
|
+
puts opts
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if options.empty?
|
44
|
+
puts opts
|
45
|
+
else
|
46
|
+
opts.parse!(options)
|
47
|
+
end
|
48
|
+
|
49
|
+
raise "Spackle's wrapper mode is not yet implement" unless options.empty?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Spackle
|
2
|
+
class Configuration
|
3
|
+
# The command to invoke when Spackle finds errors. It will receive
|
4
|
+
# a single argument, being the path to the Spackle errors file.
|
5
|
+
# If left unspecified, no command is invoked.
|
6
|
+
attr_accessor :callback_command
|
7
|
+
|
8
|
+
# Where to store the Spackle error files. If unspecified, Spackle will
|
9
|
+
# default to /tmp
|
10
|
+
attr_accessor :tempdir
|
11
|
+
|
12
|
+
# Which ErrorFormatter class to use when formatting errors. Specified
|
13
|
+
# as a symbol or string matching a class in spackle/error_formatters.
|
14
|
+
# i.e. config.error_formatter = :vim_quickfix
|
15
|
+
attr_accessor :error_formatter
|
16
|
+
|
17
|
+
# Filename to use when writing the formatted Spackle results. If
|
18
|
+
# unspecified, defaults to a filename based on the name of your
|
19
|
+
# project's root directory, or "default.spackle" it can't figure out
|
20
|
+
# where your root directory is
|
21
|
+
attr_accessor :spackle_file
|
22
|
+
|
23
|
+
# Configure Spackle with defaults. Currently only accepts :vim as an
|
24
|
+
# argument.
|
25
|
+
def set_defaults_for(mode)
|
26
|
+
case mode.to_sym
|
27
|
+
when :vim
|
28
|
+
self.callback_command = "spackle-vim-load-quickfix"
|
29
|
+
self.error_formatter = :vim_quickfix
|
30
|
+
else
|
31
|
+
raise ArgumentError.new("unknown Spackle mode: '#{mode}'")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Spackle
|
2
|
+
class BacktraceEntry
|
3
|
+
attr_reader :file, :line
|
4
|
+
def initialize(file, line)
|
5
|
+
@file, @line = file, line
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Error
|
10
|
+
attr_reader :message, :backtrace
|
11
|
+
|
12
|
+
def initialize(message)
|
13
|
+
@message = message
|
14
|
+
@backtrace = []
|
15
|
+
yield self if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_error(error_or_file, line = nil)
|
19
|
+
case error_or_file
|
20
|
+
when Error
|
21
|
+
@backtrace << error_or_file
|
22
|
+
when String
|
23
|
+
@backtrace << BacktraceEntry.new(error_or_file, line)
|
24
|
+
else
|
25
|
+
raise ArgumentError.new("unrecognized error input '#{error_or_file}'. Should be a filename or a Spackle::BacktraceEntry")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Spackle
|
2
|
+
module Helpers
|
3
|
+
module RubyProjectRoot
|
4
|
+
class << self
|
5
|
+
# Search recursively from the current working directory up for something
|
6
|
+
# that looks like the root directory of a Ruby project.
|
7
|
+
#
|
8
|
+
# Returns the path to the found project dir, if any. Nil otherwise.
|
9
|
+
#
|
10
|
+
# Stops looking when it reaches the top of the tree, or the user's
|
11
|
+
# home directory.
|
12
|
+
#
|
13
|
+
# Detects a project dir via any of:
|
14
|
+
# * a config/environment.rb file
|
15
|
+
# * a spec/spec_helper.rb file
|
16
|
+
# * a features/step_definitions directory
|
17
|
+
def search(directory)
|
18
|
+
directory = File.expand_path(directory)
|
19
|
+
while directory != '/'
|
20
|
+
return directory if is_project_dir?(directory)
|
21
|
+
directory = File.expand_path(directory + '/..')
|
22
|
+
end
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_project_dir?(path)
|
27
|
+
File.exists?(File.join(path, "config/environment.rb")) ||
|
28
|
+
File.exists?(File.join(path, "spec/spec_helper.rb")) ||
|
29
|
+
File.directory?(File.join(path, "features/step_definitions"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Spackle::Output
|
2
|
+
# This is the foundation of all Spackle::Output classes, but by itself
|
3
|
+
# it does nothing.
|
4
|
+
#
|
5
|
+
# Using an Output class should be simple:
|
6
|
+
# (assuming errors is an Array of Spackle::Error objects)
|
7
|
+
# puts Spackle::Output::VimQuickfix.format(errors)
|
8
|
+
#
|
9
|
+
# The child class (VimQuickfix) only needs to implement the
|
10
|
+
# format_backtrace instance method.
|
11
|
+
#
|
12
|
+
# Spackle::Output::Base is responsible for things like:
|
13
|
+
# * iterating over the backtrace collection
|
14
|
+
# * making pathnames relative
|
15
|
+
# * limiting the number of errors that are output
|
16
|
+
# * filtering the backtrace output by filename
|
17
|
+
#
|
18
|
+
# Spackle::Output::Base interacts with Spackle's Configuration
|
19
|
+
#
|
20
|
+
# If you're writing your own Output class, it should be quite
|
21
|
+
# easy to override some of the Configuration handling if your
|
22
|
+
# class requires it.
|
23
|
+
#
|
24
|
+
class Base
|
25
|
+
attr_accessor :error
|
26
|
+
def initialize(error = nil)
|
27
|
+
self.error = error || Spackle.current_error
|
28
|
+
end
|
29
|
+
|
30
|
+
def formatted_lines
|
31
|
+
error.backtrace.map do |bt|
|
32
|
+
format_backtrace_line error.message, bt.file, bt.line
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def format
|
37
|
+
formatted_lines.join("\n") + "\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.format(error = nil)
|
41
|
+
new(error || Spackle.current_error).format
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec/runner/formatter/base_formatter'
|
2
|
+
|
3
|
+
# This is just a slightly-refactored and cut down version of RSpec's
|
4
|
+
# BaseTextFormatter.
|
5
|
+
|
6
|
+
module Spackle::Spec
|
7
|
+
class BaseFormatter < ::Spec::Runner::Formatter::BaseFormatter
|
8
|
+
attr_reader :output, :options
|
9
|
+
attr_accessor :errors
|
10
|
+
|
11
|
+
def initialize(options, output)
|
12
|
+
# we ignore output, for now
|
13
|
+
Spackle.init
|
14
|
+
@options = options
|
15
|
+
self.errors = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def close
|
19
|
+
Spackle.test_finished errors
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spackle/spec/base_formatter'
|
2
|
+
|
3
|
+
module Spackle::Spec
|
4
|
+
class SpackleFormatter < BaseFormatter
|
5
|
+
def example_failed(example, counter, failure)
|
6
|
+
error = Spackle::Error.new failure.exception.message
|
7
|
+
failure.exception.backtrace.each do |frame|
|
8
|
+
file, line = frame.match(/^([^:]+):([0-9]+)/)[1,2]
|
9
|
+
error.add_error file, line
|
10
|
+
end
|
11
|
+
self.errors << error
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/spackle/spec.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'spackle/spec/spackle_formatter'
|