guard-haskell 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/guard-haskell.png)](http://badge.fury.io/rb/guard-haskell)
|
4
|
+
[![Build Status](https://secure.travis-ci.org/supki/guard-haskell.png?branch=master)](http://travis-ci.org/supki/guard-haskell)
|
5
|
+
[![Dependencies Status](https://gemnasium.com/supki/guard-haskell.png)](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
|