guard-haskell 1.0.0
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.
- checksums.yaml +15 -0
- data/.gitignore +20 -0
- data/.travis.yml +8 -0
- data/Gemfile +3 -0
- data/LICENSE +27 -0
- data/README.md +82 -0
- data/Rakefile +9 -0
- data/guard-haskell.gemspec +24 -0
- data/lib/guard/haskell.rb +102 -0
- data/lib/guard/haskell/repl.rb +71 -0
- data/lib/guard/haskell/version.rb +5 -0
- data/spec/haskell_spec.rb +243 -0
- data/spec/spec_helper.rb +11 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MmZhYzE5OTQ2MTEyZDZhYzMzNTAyNWFlOWIzNTU3ODAzZmU5ZGE2ZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YTJiMDZhMTg4NGIzY2IyZDhhODBjMjRjYTBlYzBhMDVjOTQ5NTUyNQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OGI4NjEzNTc5MmJmMGNmYmQ2MjBkN2Q1MWI0NDkxZTJiZTc3NDFjNDZmMmU3
|
10
|
+
ZmMxMGZhZTFlZDBkZjA0MTk0ZWNjMjY1OWQ3NTAwYWFiMTRlNWIzZGQ1Y2Q3
|
11
|
+
ZDE3ZGIzODFjMWIwMjBjYTBjZjM0NTg1NzQyZTk4MWNmNzU1ODU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDIwNDFkZjc1Yzc1YTkyZGE0NmU5MWIwMDJmZDE4ODRhZWRjOTliZWFjOTVh
|
14
|
+
YjFkYWVhMjZlNTgwYjI0MTg5ZDIwMWQ5NWIzYzE5NTI0MDZlMzAwYWJmZjdk
|
15
|
+
YWIyNmYyNDc3MjZmNWJjNTk1Zjc0OGRiNmM5NDhiOWYwNDQ1NGY=
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (c) 2013, Matvey B. Aksenov
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice, this
|
11
|
+
list of conditions and the following disclaimer in the documentation and/or
|
12
|
+
other materials provided with the distribution.
|
13
|
+
|
14
|
+
* Neither the name of the {organization} nor the names of its
|
15
|
+
contributors may be used to endorse or promote products derived from
|
16
|
+
this software without specific prior written permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
22
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
25
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
guard-haskell
|
2
|
+
=============
|
3
|
+
[](http://badge.fury.io/rb/guard-haskell)
|
4
|
+
[](http://travis-ci.org/supki/guard-haskell)
|
5
|
+
[](https://gemnasium.com/supki/guard-haskell)
|
6
|
+
|
7
|
+
|
8
|
+
`Guard::Haskell` automatically runs your specs
|
9
|
+
|
10
|
+
# Install
|
11
|
+
|
12
|
+
```shell
|
13
|
+
% cabal install hspec
|
14
|
+
% gem install guard
|
15
|
+
% git clone https://github.com/supki/guard-haskell
|
16
|
+
% cd guard-haskell
|
17
|
+
% gem build guard-haskell.gemspec
|
18
|
+
% gem install guard-haskell-0.1.0.0.gem
|
19
|
+
```
|
20
|
+
|
21
|
+
# Usage
|
22
|
+
|
23
|
+
## How does it work?
|
24
|
+
|
25
|
+
For explanation what `guard` is and how to use it, please refer to the [`guard manual`][0]
|
26
|
+
|
27
|
+
`guard-haskell` uses [`hspec`][1] to run specs and check their success, so it makes some assumptions about your code style:
|
28
|
+
|
29
|
+
* `hspec` is your testing framework and
|
30
|
+
|
31
|
+
* [`hspec-discover`][2] (or similar tool) organizes your specs,
|
32
|
+
i.e. there is a "top" spec (usually `test/Spec.hs`) that pulls others in
|
33
|
+
|
34
|
+
When you type in `guard`, `guard-haskell` fires up an `ghci` instance which it talks to, reloading
|
35
|
+
and rerunning (parts of) "top" spec on files modifications.
|
36
|
+
|
37
|
+
## Guardfile examples
|
38
|
+
|
39
|
+
Typical haskell project:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
guard :haskell do
|
43
|
+
watch(%r{.*\.cabal$})
|
44
|
+
watch(%r{test/.+Spec.l?hs$})
|
45
|
+
watch(%r{src/.+.l?hs$})
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Customized haskell project:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
guard :haskell, all_on_pass: true, ghci_options: ["-DTEST"] do
|
53
|
+
watch(%r{.*\.cabal$})
|
54
|
+
watch(%r{test/.+Spec.l?hs$})
|
55
|
+
watch(%r{lib/.+.l?hs$})
|
56
|
+
watch(%r{bin/.+.l?hs$})
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
## Options
|
61
|
+
|
62
|
+
`Guard::Haskell` has a bunch of options:
|
63
|
+
|
64
|
+
### `all_on_start`
|
65
|
+
|
66
|
+
Run all specs on start (default: `false`).
|
67
|
+
|
68
|
+
### `all_on_pass`
|
69
|
+
|
70
|
+
Run all specs after previously failing spec _finally_ passes (default: `false`).
|
71
|
+
|
72
|
+
### `ghci_options`
|
73
|
+
|
74
|
+
Pass custom ghci options, for example, `-XCPP` directives like `-DTEST` (default: `[]`).
|
75
|
+
|
76
|
+
### `top_spec`
|
77
|
+
|
78
|
+
"Top" spec location (default: `test/Spec.hs`).
|
79
|
+
|
80
|
+
[0]: https://github.com/guard/guard#readme
|
81
|
+
[1]: http://hspec.github.io/
|
82
|
+
[2]: http://hspec.github.io/hspec-discover.html
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'guard/haskell/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'guard-haskell'
|
8
|
+
s.version = Guard::HaskellVersion::VERSION
|
9
|
+
s.author = 'Matvey Aksenov'
|
10
|
+
s.email = 'matvey.aksenov@gmail.com'
|
11
|
+
s.summary = 'Guard gem for Haskell'
|
12
|
+
s.description = 'Guard::Haskell automatically runs your specs'
|
13
|
+
s.homepage = 'https://github.com/supki/guard-haskell#readme'
|
14
|
+
s.license = 'BSD3'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.test_files = s.files.grep(%r{^spec/})
|
18
|
+
s.require_path = 'lib'
|
19
|
+
|
20
|
+
s.add_dependency 'guard', '>= 2.1.1'
|
21
|
+
s.add_development_dependency 'bundler', '>= 1.3.5'
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
s.add_development_dependency 'rspec'
|
24
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'guard/plugin'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class ::String
|
6
|
+
def strip_lowercase_directories
|
7
|
+
matches = self.match(/^\p{Lower}[^\/]+\/(.+)/)
|
8
|
+
if matches
|
9
|
+
matches[1].strip_lowercase_directories
|
10
|
+
else
|
11
|
+
self
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def path_to_module_name
|
16
|
+
self.gsub(/\//, ".")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ::Guard
|
21
|
+
class Haskell < ::Guard::Plugin
|
22
|
+
|
23
|
+
require 'guard/haskell/repl'
|
24
|
+
|
25
|
+
attr_reader :repl, :top_spec, :ghci_options, :targets
|
26
|
+
attr_reader :all_on_start, :all_on_pass
|
27
|
+
|
28
|
+
def initialize options = {}
|
29
|
+
super
|
30
|
+
@last_run = :success # try to prove it wasn't :-)
|
31
|
+
@top_spec = options[:top_spec] || "test/Spec.hs"
|
32
|
+
@ghci_options = options[:ghci_options] || []
|
33
|
+
@all_on_start = options[:all_on_start] || false
|
34
|
+
@all_on_pass = options[:all_on_pass] || false
|
35
|
+
@repl = Repl.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def start
|
39
|
+
repl.start(ghci_options)
|
40
|
+
repl.init(top_spec)
|
41
|
+
|
42
|
+
@targets = ::Set.new(::Dir.glob("**/*.{hs,lhs}"))
|
43
|
+
|
44
|
+
if all_on_start
|
45
|
+
run_all
|
46
|
+
success?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def stop
|
51
|
+
repl.exit
|
52
|
+
end
|
53
|
+
|
54
|
+
def reload
|
55
|
+
stop
|
56
|
+
start
|
57
|
+
end
|
58
|
+
|
59
|
+
def run_all
|
60
|
+
repl.run
|
61
|
+
end
|
62
|
+
|
63
|
+
def run pattern
|
64
|
+
if @last_run == :success
|
65
|
+
repl.run(pattern)
|
66
|
+
else
|
67
|
+
repl.rerun
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def success?
|
72
|
+
if repl.success?
|
73
|
+
if @last_run == :failure
|
74
|
+
@last_run = :success
|
75
|
+
if all_on_pass
|
76
|
+
run_all
|
77
|
+
success?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
Notifier.notify('Success')
|
81
|
+
else
|
82
|
+
@last_run = :failure
|
83
|
+
Notifier.notify('Failure', image: :failed)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def run_on_additions paths
|
88
|
+
unless paths.all? { |path| targets.include? path }
|
89
|
+
@targets += paths
|
90
|
+
repl.init(top_spec)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def run_on_modifications paths
|
95
|
+
case paths.first
|
96
|
+
when /(.+)Spec\.l?hs$/, /(.+)\.l?hs$/
|
97
|
+
run($1.strip_lowercase_directories.path_to_module_name)
|
98
|
+
success?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'io/wait'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
class ::Guard::Haskell::Repl
|
5
|
+
attr_reader :stdin, :reader, :thread, :success
|
6
|
+
|
7
|
+
def start ghci_options
|
8
|
+
cmd = ["ghci"]
|
9
|
+
Dir["*"].each { |x| cmd << "-i#{x}" }
|
10
|
+
sandbox = ::Dir[".cabal-sandbox/*packages.conf.d"].first
|
11
|
+
cmd << "-package-db=#{sandbox}" if sandbox
|
12
|
+
cmd.concat(ghci_options)
|
13
|
+
|
14
|
+
@stdin, stdout, @thread = ::Open3.popen2e(*cmd)
|
15
|
+
@reader = ::Thread.new do
|
16
|
+
loop do
|
17
|
+
n = stdout.nread
|
18
|
+
if n > 0
|
19
|
+
out = stdout.read(n)
|
20
|
+
print out
|
21
|
+
if @running
|
22
|
+
case out
|
23
|
+
when /\d+ examples?, 0 failures/
|
24
|
+
@success = true
|
25
|
+
@running = false
|
26
|
+
when /\d+ examples?, \d+ failures?/,
|
27
|
+
/Failed, modules loaded:/,
|
28
|
+
/\*{3} Exception:/,
|
29
|
+
/phase `C preprocessor' failed/
|
30
|
+
@success = false
|
31
|
+
@running = false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
else
|
35
|
+
sleep(0.1)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def init spec
|
42
|
+
_repl ":load #{spec}\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
def exit
|
46
|
+
::Process::kill "TERM", thread.pid
|
47
|
+
::Thread.kill(reader)
|
48
|
+
end
|
49
|
+
|
50
|
+
def run pattern = nil
|
51
|
+
if pattern.nil?
|
52
|
+
_repl ":reload\n:main --color\n"
|
53
|
+
else
|
54
|
+
_repl ":reload\n:main --color --match #{pattern}\n"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def rerun
|
59
|
+
_repl ":reload\n:main --color --rerun\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
def success?
|
63
|
+
while @running do sleep(0.01) end
|
64
|
+
@success
|
65
|
+
end
|
66
|
+
|
67
|
+
def _repl command
|
68
|
+
@running = true
|
69
|
+
stdin.write command
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'guard/notifier'
|
3
|
+
|
4
|
+
describe "monkey patching" do
|
5
|
+
describe ::String do
|
6
|
+
describe "#strip_lowercase_directories" do
|
7
|
+
it "works on empty string" do
|
8
|
+
expect("".strip_lowercase_directories).to eq("")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "works on string without lowercase directory prefixes" do
|
12
|
+
expect("Foo".strip_lowercase_directories).to eq("Foo")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "works on string with lowercase directory prefix" do
|
16
|
+
expect("foo/Bar".strip_lowercase_directories).to eq("Bar")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "works on string with multiple lowercase directory prefixes" do
|
20
|
+
expect("foo/bar/Baz".strip_lowercase_directories).to eq("Baz")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#path_to_module_name" do
|
25
|
+
it "works on string without path separators" do
|
26
|
+
expect("Foo".path_to_module_name).to eq("Foo")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "works on string with path separators" do
|
30
|
+
expect("Foo/Bar/Baz".path_to_module_name).to eq("Foo.Bar.Baz")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ::Guard::Haskell do
|
37
|
+
let(:guard) do
|
38
|
+
::Guard::Haskell.new
|
39
|
+
end
|
40
|
+
|
41
|
+
before :each do
|
42
|
+
::Guard.stub(:add_group)
|
43
|
+
::Guard::Haskell::Repl.any_instance.stub(:start)
|
44
|
+
::Guard::Haskell::Repl.any_instance.stub(:init)
|
45
|
+
end
|
46
|
+
|
47
|
+
describe ".initialize" do
|
48
|
+
it "has :all_on_start option" do
|
49
|
+
expect(guard.instance_variable_defined?(:@all_on_start)).to be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "has :all_on_pass option" do
|
53
|
+
expect(guard.instance_variable_defined?(:@all_on_pass)).to be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "has :ghci_options option" do
|
57
|
+
expect(guard.instance_variable_defined?(:@ghci_options)).to be_true
|
58
|
+
end
|
59
|
+
|
60
|
+
it "has :top_spec option" do
|
61
|
+
expect(guard.instance_variable_defined?(:@top_spec)).to be_true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#start" do
|
66
|
+
it "starts repl" do
|
67
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:init).with("test/Spec.hs")
|
68
|
+
|
69
|
+
guard.start
|
70
|
+
end
|
71
|
+
|
72
|
+
it "does not run all specs on start by default" do
|
73
|
+
expect(guard).not_to receive(:run_all)
|
74
|
+
expect(guard).not_to receive(:success?)
|
75
|
+
|
76
|
+
guard.start
|
77
|
+
end
|
78
|
+
|
79
|
+
it "runs all specs on start with :all_on_start option enabled" do
|
80
|
+
custom_guard = ::Guard::Haskell.new(all_on_start: true)
|
81
|
+
|
82
|
+
expect(custom_guard).to receive(:run_all)
|
83
|
+
expect(custom_guard).to receive(:success?)
|
84
|
+
|
85
|
+
custom_guard.start
|
86
|
+
end
|
87
|
+
|
88
|
+
it "starts repl with custom spec specified with :top_spec option" do
|
89
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:init).with("test/CustomSpec.hs")
|
90
|
+
|
91
|
+
custom_guard = ::Guard::Haskell.new(top_spec: "test/CustomSpec.hs")
|
92
|
+
custom_guard.start
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#stop" do
|
97
|
+
it "stops repl" do
|
98
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:exit)
|
99
|
+
|
100
|
+
guard.start
|
101
|
+
guard.stop
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#reload" do
|
106
|
+
it "restarts repl" do
|
107
|
+
expect(guard).to receive(:stop)
|
108
|
+
expect(guard).to receive(:start)
|
109
|
+
guard.reload
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#run" do
|
114
|
+
it "runs specs matching pattern if last run was a success" do
|
115
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Foo")
|
116
|
+
guard.instance_variable_set(:@last_run, :success)
|
117
|
+
|
118
|
+
guard.start
|
119
|
+
guard.run("Foo")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "reruns previous specs if last run was a failure" do
|
123
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:rerun)
|
124
|
+
guard.instance_variable_set(:@last_run, :failure)
|
125
|
+
|
126
|
+
guard.start
|
127
|
+
guard.run("Foo")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#success" do
|
132
|
+
it "notifies on success" do
|
133
|
+
::Guard::Haskell::Repl.any_instance.stub(:success?) { true }
|
134
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
135
|
+
expect(::Guard::Notifier).to receive(:notify).with('Success')
|
136
|
+
guard.instance_variable_set(:@last_run, :failure)
|
137
|
+
|
138
|
+
guard.start
|
139
|
+
guard.success?
|
140
|
+
expect(guard.instance_variable_get(:@last_run)).to eq(:success)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "notifies on failure" do
|
144
|
+
::Guard::Haskell::Repl.any_instance.stub(:success?) { false }
|
145
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
146
|
+
expect(::Guard::Notifier).to receive(:notify).with('Failure', image: :failed)
|
147
|
+
guard.instance_variable_set(:@last_run, :success)
|
148
|
+
|
149
|
+
guard.start
|
150
|
+
guard.success?
|
151
|
+
expect(guard.instance_variable_get(:@last_run)).to eq(:failure)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "does not run all specs on success after failure by default" do
|
155
|
+
::Guard::Haskell::Repl.any_instance.stub(:success?) { true }
|
156
|
+
guard.instance_variable_set(:@last_run, :failure)
|
157
|
+
|
158
|
+
expect(guard).not_to receive(:run_all)
|
159
|
+
|
160
|
+
guard.start
|
161
|
+
guard.success?
|
162
|
+
end
|
163
|
+
|
164
|
+
it "runs all specs on success after failure with :all_on_pass option" do
|
165
|
+
::Guard::Haskell::Repl.any_instance.stub(:success?) { true }
|
166
|
+
custom_guard = ::Guard::Haskell.new(all_on_pass: true)
|
167
|
+
custom_guard.instance_variable_set(:@last_run, :failure)
|
168
|
+
|
169
|
+
expect(custom_guard).to receive(:run_all)
|
170
|
+
|
171
|
+
custom_guard.start
|
172
|
+
custom_guard.success?
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "#run_on_additions" do
|
177
|
+
it "reinitializes the repl on new files" do
|
178
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:init).twice
|
179
|
+
|
180
|
+
guard.start
|
181
|
+
guard.instance_variable_set(:@targets, [])
|
182
|
+
guard.run_on_additions ["foo", "bar"]
|
183
|
+
end
|
184
|
+
|
185
|
+
it "does not reinitialize the repl if new files were seen before" do
|
186
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:init).once
|
187
|
+
|
188
|
+
guard.start
|
189
|
+
guard.instance_variable_set(:@targets, ["foo", "bar"])
|
190
|
+
guard.run_on_additions ["foo", "bar"]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "#run_on_modifications" do
|
195
|
+
it "run specs for simple haskell files" do
|
196
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Foo")
|
197
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
198
|
+
|
199
|
+
guard.start
|
200
|
+
guard.run_on_modifications(["Foo.hs"])
|
201
|
+
end
|
202
|
+
|
203
|
+
it "run specs for simple literate haskell files" do
|
204
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Foo")
|
205
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
206
|
+
|
207
|
+
guard.start
|
208
|
+
guard.run_on_modifications(["Foo.lhs"])
|
209
|
+
end
|
210
|
+
|
211
|
+
it "run specs for *complex* haskell files" do
|
212
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Bar.Baz")
|
213
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
214
|
+
|
215
|
+
guard.start
|
216
|
+
guard.run_on_modifications(["foo/Bar/Baz.hs"])
|
217
|
+
end
|
218
|
+
|
219
|
+
it "run specs for simple haskell spec files" do
|
220
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Foo")
|
221
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
222
|
+
|
223
|
+
guard.start
|
224
|
+
guard.run_on_modifications(["FooSpec.hs"])
|
225
|
+
end
|
226
|
+
|
227
|
+
it "run specs for simple literate haskell spec files" do
|
228
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Foo")
|
229
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
230
|
+
|
231
|
+
guard.start
|
232
|
+
guard.run_on_modifications(["FooSpec.lhs"])
|
233
|
+
end
|
234
|
+
|
235
|
+
it "run specs for *complex* haskell spec files" do
|
236
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:run).with("Bar.Baz")
|
237
|
+
expect_any_instance_of(::Guard::Haskell::Repl).to receive(:success?)
|
238
|
+
|
239
|
+
guard.start
|
240
|
+
guard.run_on_modifications(["foo/Bar/BazSpec.hs"])
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: guard-haskell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matvey Aksenov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: guard
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.5
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.3.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Guard::Haskell automatically runs your specs
|
70
|
+
email: matvey.aksenov@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- .gitignore
|
76
|
+
- .travis.yml
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- guard-haskell.gemspec
|
82
|
+
- lib/guard/haskell.rb
|
83
|
+
- lib/guard/haskell/repl.rb
|
84
|
+
- lib/guard/haskell/version.rb
|
85
|
+
- spec/haskell_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
homepage: https://github.com/supki/guard-haskell#readme
|
88
|
+
licenses:
|
89
|
+
- BSD3
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.1.11
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: Guard gem for Haskell
|
111
|
+
test_files:
|
112
|
+
- spec/haskell_spec.rb
|
113
|
+
- spec/spec_helper.rb
|