smlspec 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +16 -2
- data/README.md +43 -1
- data/Rakefile +2 -0
- data/TODO.md +21 -4
- data/bin/smlspec +23 -13
- data/build/smlspec-0.0.4.gem +0 -0
- data/features/running_tests.feature +20 -0
- data/features/step_definitions/smlspec_steps.rb +54 -0
- data/features/support/env.rb +2 -0
- data/lib/formats_tests.rb +2 -2
- data/lib/looks_for_mosml.rb +12 -0
- data/lib/test.rb +24 -0
- data/lib/test_output.rb +25 -0
- data/lib/test_output_presenter.rb +68 -0
- data/scripts/cucumber_init.sh +24 -0
- data/smlspec.gemspec +4 -1
- data/spec/fixtures/formatted_tests.sml +6 -6
- data/spec/looks_for_mosml_spec.rb +18 -0
- data/spec/spec_helper.rb +1 -14
- data/spec/support/helper_methods.rb +4 -0
- data/spec/{test_output_parser_spec.rb → test_output_presenter_spec.rb} +16 -14
- data/spec/test_output_spec.rb +39 -0
- data/spec/test_spec.rb +20 -0
- metadata +44 -3
- data/lib/test_output_parser.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6991ed75c5f26034f05f335944a7ddcd524b9dd
|
4
|
+
data.tar.gz: abceb8d8cce6a840c2d823821d1b57c3e0f43dc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6a28ba4103305899aa80caa3938f584cca26106137f90394956eedd6b554c432914da159fa9b68a10c55b92ed259d99eaf550fff7efd290a80cdfa2d349f2c1
|
7
|
+
data.tar.gz: 1e8870d7795d9c5472d42164d28c69e00dc1e17201e70734c54631e0ba68f6e6d30054af0aea068d493a0d2a06e5bd2ebddf265ff336130e10006b4a55bd3188
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smlspec (0.0.
|
4
|
+
smlspec (0.0.5)
|
5
|
+
colorize
|
6
|
+
thor
|
5
7
|
|
6
8
|
GEM
|
7
9
|
remote: http://rubygems.org/
|
8
10
|
specs:
|
11
|
+
builder (3.2.2)
|
9
12
|
colorize (0.6.0)
|
13
|
+
cucumber (1.3.10)
|
14
|
+
builder (>= 2.1.2)
|
15
|
+
diff-lcs (>= 1.1.3)
|
16
|
+
gherkin (~> 2.12)
|
17
|
+
multi_json (>= 1.7.5, < 2.0)
|
18
|
+
multi_test (>= 0.0.2)
|
10
19
|
diff-lcs (1.2.5)
|
20
|
+
gherkin (2.12.2)
|
21
|
+
multi_json (~> 1.3)
|
22
|
+
multi_json (1.8.2)
|
23
|
+
multi_test (0.0.2)
|
11
24
|
rake (10.1.0)
|
12
25
|
rspec (2.14.1)
|
13
26
|
rspec-core (~> 2.14.0)
|
@@ -17,12 +30,13 @@ GEM
|
|
17
30
|
rspec-expectations (2.14.4)
|
18
31
|
diff-lcs (>= 1.1.3, < 2.0)
|
19
32
|
rspec-mocks (2.14.4)
|
33
|
+
thor (0.18.1)
|
20
34
|
|
21
35
|
PLATFORMS
|
22
36
|
ruby
|
23
37
|
|
24
38
|
DEPENDENCIES
|
25
|
-
|
39
|
+
cucumber
|
26
40
|
rake
|
27
41
|
rspec
|
28
42
|
smlspec!
|
data/README.md
CHANGED
@@ -1 +1,43 @@
|
|
1
|
-
#
|
1
|
+
# SMLspec
|
2
|
+
|
3
|
+
SML spec is a test runner for Standard ML. It lets you write very concise and short tests and still get a useful and pretty output.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
1. Install [Moscow ML](https://github.com/kfl/mosml).
|
8
|
+
2. Install the gem with `gem install smlspec`.
|
9
|
+
|
10
|
+
## Example
|
11
|
+
|
12
|
+
Write some SML code like this
|
13
|
+
|
14
|
+
```sml
|
15
|
+
fun myLength [] = 0
|
16
|
+
| myLength (_::xs) = 1 + myLength xs
|
17
|
+
|
18
|
+
val myLength_test1 = myLength [] = 0
|
19
|
+
val myLength_test2 = myLength [1, 2] = 2
|
20
|
+
val myLength_test3 = myLength ["a", "b", "c"] = 3
|
21
|
+
```
|
22
|
+
|
23
|
+
Then run `smlspec <name of file>.sml`
|
24
|
+
|
25
|
+
And you'll get output similar to this
|
26
|
+
|
27
|
+
```
|
28
|
+
...
|
29
|
+
|
30
|
+
3 tests ran, 0 red, 3 green
|
31
|
+
```
|
32
|
+
|
33
|
+
If you have failed tests you'll see something like this
|
34
|
+
|
35
|
+
```
|
36
|
+
...F
|
37
|
+
|
38
|
+
|
39
|
+
myLength_test4
|
40
|
+
|
41
|
+
|
42
|
+
4 tests ran, 1 red, 3 green
|
43
|
+
```
|
data/Rakefile
CHANGED
@@ -4,11 +4,13 @@ RSpec::Core::RakeTask.new(:spec)
|
|
4
4
|
|
5
5
|
task default: :spec
|
6
6
|
|
7
|
+
desc 'Build gem'
|
7
8
|
task :build do
|
8
9
|
system "gem build smlspec.gemspec"
|
9
10
|
Dir.glob("*.gem") {|f| system "mv #{f} build" }
|
10
11
|
end
|
11
12
|
|
13
|
+
desc 'Install gem'
|
12
14
|
task :install do
|
13
15
|
system "gem uninstall smlspec"
|
14
16
|
newest_build = Dir.glob("build/*.gem").last
|
data/TODO.md
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
# TODOS
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
## For version 0.0.5
|
4
|
+
|
5
|
+
|
6
|
+
## Others
|
7
|
+
|
8
|
+
- [ ] make tests of SmlFile isolated, could be done using dependency injection
|
9
|
+
- [ ] allow for other implementations than moscow ml
|
10
|
+
- [ ] work with "load" function
|
11
|
+
- [ ] show time it took to run tests
|
12
|
+
- [ ] refactor binary
|
13
|
+
- [ ] clean up fixtures folder
|
14
|
+
|
15
|
+
## Done
|
16
|
+
|
17
|
+
- [x] append test function to file
|
18
|
+
- [x] write test output parser
|
19
|
+
- [x] make change log
|
20
|
+
- [x] refactor TestOutputParser
|
21
|
+
- [x] make some sort in integration test
|
22
|
+
- [x] test for mosml being installed when running binary
|
23
|
+
|
data/bin/smlspec
CHANGED
@@ -1,17 +1,24 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
$:.unshift("lib")
|
3
4
|
require 'colorize'
|
4
5
|
require 'digest/md5'
|
5
|
-
|
6
|
-
$:.unshift("lib")
|
7
6
|
require 'formats_lines'
|
8
7
|
require 'formats_tests'
|
9
8
|
require 'sml_file'
|
10
|
-
require '
|
9
|
+
require 'test_output'
|
10
|
+
require 'test'
|
11
|
+
require 'test_output_presenter'
|
12
|
+
require 'looks_for_mosml'
|
11
13
|
|
12
14
|
class Runner
|
13
15
|
def self.main(input)
|
14
|
-
|
16
|
+
if LooksForMosml.installed?
|
17
|
+
new(input)
|
18
|
+
else
|
19
|
+
puts "Moscow ML most be installed"
|
20
|
+
exit 1
|
21
|
+
end
|
15
22
|
end
|
16
23
|
|
17
24
|
def initialize(input)
|
@@ -20,16 +27,19 @@ class Runner
|
|
20
27
|
|
21
28
|
@file = SmlFile.new(@input).prepare_tests
|
22
29
|
|
23
|
-
|
30
|
+
tmp_file_name = random_name
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
@file.save_as!(tmp_file_name + ".sml")
|
33
|
+
|
34
|
+
@file.compile!(random_name + ".exe")
|
35
|
+
|
36
|
+
output = TestOutput.new(@file.run.split("\n"))
|
37
|
+
puts TestOutputPresenter.parse(output)
|
38
|
+
rescue SmlFile::CannotCompile => e
|
39
|
+
output = TestOutput.new(e.message.split("\n"))
|
40
|
+
puts TestOutputPresenter.parse(output).gsub(tmp_file_name+".sml", @input)
|
41
|
+
ensure
|
42
|
+
clean_up!
|
33
43
|
end
|
34
44
|
|
35
45
|
private
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Running SML tests
|
2
|
+
In order to ensure that my SML is working
|
3
|
+
As a programmer
|
4
|
+
I want to be able to run tests
|
5
|
+
|
6
|
+
Scenario: Running tests
|
7
|
+
Given I have written an SML file with tests
|
8
|
+
When I run smlspec on the file
|
9
|
+
Then I should see the test output
|
10
|
+
|
11
|
+
Scenario: A compile error happends
|
12
|
+
Given I have an invalid SML file
|
13
|
+
When I run smlspec on the file
|
14
|
+
Then I should see a compile error message
|
15
|
+
|
16
|
+
Scenario: Running it without Moscow ML installed
|
17
|
+
Given I have written an SML file with tests
|
18
|
+
And I don't have Moscow ML installed
|
19
|
+
When I run smlspec on the file
|
20
|
+
Then I should see message saying that I don't have Moscow ML installed
|
@@ -0,0 +1,54 @@
|
|
1
|
+
Given(/^I have written an SML file with tests$/) do
|
2
|
+
File.open("tmp/integration_file.sml", "w") do |f|
|
3
|
+
f.puts "fun f _ = 3"
|
4
|
+
f.puts "val f_test1 = f 3 = 3"
|
5
|
+
f.puts "val f_test2 = f 5 = 3"
|
6
|
+
f.puts "val f_test3 = f 3 = 5"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Given(/^I have an invalid SML file$/) do
|
11
|
+
File.open("tmp/integration_file.sml", "w") do |f|
|
12
|
+
f.puts "val foo = foo"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
When(/^I run smlspec on the file$/) do
|
17
|
+
@output = `./bin/smlspec tmp/integration_file.sml`
|
18
|
+
end
|
19
|
+
|
20
|
+
Then(/^I should see the test output$/) do
|
21
|
+
lines = [
|
22
|
+
".".green + ".".green + "F".red,
|
23
|
+
"",
|
24
|
+
"",
|
25
|
+
"",
|
26
|
+
"f_test3".red,
|
27
|
+
"",
|
28
|
+
"",
|
29
|
+
"3 tests ran, 1 red, 2 green",
|
30
|
+
"",
|
31
|
+
"",
|
32
|
+
].join("\n")
|
33
|
+
|
34
|
+
lines.should eq @output
|
35
|
+
|
36
|
+
clean_tmp
|
37
|
+
end
|
38
|
+
|
39
|
+
Then(/^I should see a compile error message$/) do
|
40
|
+
expected = [
|
41
|
+
"Unable to run tests, SML says:".red,
|
42
|
+
"",
|
43
|
+
"",
|
44
|
+
'File "tmp/integration_file.sml", line 2, characters 10-13:',
|
45
|
+
'! val foo = foo<EOF>',
|
46
|
+
'! ^^^^^^^^',
|
47
|
+
'! Unbound value identifier: foo',
|
48
|
+
"",
|
49
|
+
].join("\n")
|
50
|
+
|
51
|
+
@output.should eq expected
|
52
|
+
|
53
|
+
clean_tmp
|
54
|
+
end
|
data/lib/formats_tests.rb
CHANGED
@@ -6,11 +6,11 @@ class FormatsTests
|
|
6
6
|
match = line.match(/val (.*?_test\d) = (.*?)$/)
|
7
7
|
|
8
8
|
if match
|
9
|
-
lines[i] = "val #{match[1]} =
|
9
|
+
lines[i] = "val #{match[1]} = assert \"#{match[1]}\" (#{match[2]})"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
# TODO: make this a little nicer
|
14
|
-
'fun
|
14
|
+
'fun assert desc condition = print(desc^" "^Bool.toString(condition)^"\n")' + "\n" + lines.join("\n")
|
15
15
|
end
|
16
16
|
end
|
data/lib/test.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class Test
|
2
|
+
attr_reader :status, :name
|
3
|
+
|
4
|
+
def initialize(status, name)
|
5
|
+
@status = status
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def passed?
|
10
|
+
@status
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(another_test)
|
14
|
+
fields_used_for_comparison.inject(true) do |acc, m|
|
15
|
+
acc && instance_variable_get("@#{m}") == another_test.send(m)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def fields_used_for_comparison
|
22
|
+
[:status, :name]
|
23
|
+
end
|
24
|
+
end
|
data/lib/test_output.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class TestOutput
|
2
|
+
attr_reader :message
|
3
|
+
|
4
|
+
def initialize(lines)
|
5
|
+
@lines = lines
|
6
|
+
|
7
|
+
if compile_error?
|
8
|
+
@message = lines.join("\n")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def compile_error?
|
13
|
+
@lines.any? { |line| /^!/ =~ line }
|
14
|
+
end
|
15
|
+
|
16
|
+
def tests
|
17
|
+
@lines.inject([]) do |acc, line|
|
18
|
+
acc << if /true/ =~ line
|
19
|
+
Test.new(true, line.match(/(.+) true/)[1])
|
20
|
+
else
|
21
|
+
Test.new(false, line.match(/(.+) false/)[1])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class TestOutputPresenter
|
2
|
+
def self.parse(test_results)
|
3
|
+
parser = self.new(test_results)
|
4
|
+
|
5
|
+
if test_results.compile_error?
|
6
|
+
parser.parse_error
|
7
|
+
else
|
8
|
+
parser.parse
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(test_results)
|
13
|
+
@test_results = test_results
|
14
|
+
@tests = test_results.tests unless @test_results.compile_error?
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse
|
18
|
+
output = ""
|
19
|
+
|
20
|
+
output += dots_or_fs + "\n"
|
21
|
+
if failures.count > 0
|
22
|
+
output += blank_lines(3) + "\n"
|
23
|
+
output += failed_tests + "\n"
|
24
|
+
end
|
25
|
+
output += blank_lines(2) + "\n"
|
26
|
+
output += "#{@tests.count} tests ran, #{failures.count} red, #{passed.count} green"
|
27
|
+
output += blank_lines(3)
|
28
|
+
|
29
|
+
output
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_error
|
33
|
+
[
|
34
|
+
"Unable to run tests, SML says:".red,
|
35
|
+
"",
|
36
|
+
"",
|
37
|
+
@test_results.message,
|
38
|
+
].join("\n")
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def blank_lines(n)
|
44
|
+
Array.new(n, "").join("\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
def dots_or_fs
|
48
|
+
@tests.inject("") do |acc, test|
|
49
|
+
if test.passed?
|
50
|
+
acc += ".".green
|
51
|
+
else
|
52
|
+
acc += "F".red
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def failed_tests
|
58
|
+
failures.map { |t| t.name.red }.join("\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
def failures
|
62
|
+
@tests.reject(&:passed?)
|
63
|
+
end
|
64
|
+
|
65
|
+
def passed
|
66
|
+
@tests.select(&:passed?)
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# Create the directory structure
|
4
|
+
mkdir -p features/step_definitions
|
5
|
+
mkdir -p features/support
|
6
|
+
|
7
|
+
# Create a placeholder for the step_definitions folder
|
8
|
+
touch features/step_definitions/"$(basename `pwd`)_steps.rb"
|
9
|
+
|
10
|
+
# Create the environment file
|
11
|
+
echo '$: << File.expand_path("../../lib", File.dirname(__FILE__))' > features/support/env.rb
|
12
|
+
echo "require '$(basename `pwd`)'" >> features/support/env.rb
|
13
|
+
|
14
|
+
# Uncomment to Generate sample feature
|
15
|
+
#echo "Feature: Sample Feature
|
16
|
+
#
|
17
|
+
# Scenario: Sample Scenario
|
18
|
+
# Given the world
|
19
|
+
# When your whishes come truth
|
20
|
+
# Then you are happy
|
21
|
+
#" > features/sample.feature
|
22
|
+
|
23
|
+
# Give user some output
|
24
|
+
echo "Cucumber file structure created successfully."
|
data/smlspec.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'smlspec'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.5'
|
4
4
|
s.date = '2012-12-16'
|
5
5
|
s.summary = "Runner for SML tests"
|
6
6
|
s.description = "Gem for running tests in SML files"
|
@@ -11,7 +11,10 @@ Gem::Specification.new do |s|
|
|
11
11
|
|
12
12
|
s.add_development_dependency 'rake'
|
13
13
|
s.add_development_dependency 'rspec'
|
14
|
+
s.add_development_dependency 'cucumber'
|
15
|
+
|
14
16
|
s.add_runtime_dependency 'colorize'
|
17
|
+
s.add_runtime_dependency 'thor'
|
15
18
|
|
16
19
|
s.files = `git ls-files`.split("\n")
|
17
20
|
s.test_files = `git ls-files -- {spec}/*_spec.rb`.split("\n")
|
@@ -1,14 +1,14 @@
|
|
1
|
-
fun
|
1
|
+
fun assert desc condition = print(desc^" "^Bool.toString(condition)^"\n")
|
2
2
|
fun headString "" = "" | headString s = String.extract (s, 0, SOME 1)
|
3
3
|
fun tailString "" = "" | tailString s = String.extract (s, 1, NONE)
|
4
|
-
val allDefined_test1 =
|
5
|
-
val allDefined_test2 =
|
4
|
+
val allDefined_test1 = assert "allDefined_test1" (allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7])
|
5
|
+
val allDefined_test2 = assert "allDefined_test2" (allDefined [NONE,NONE,NONE] = [])
|
6
6
|
local
|
7
7
|
fun f x = x+2
|
8
8
|
fun h x = x*2
|
9
9
|
fun g x = x div 2
|
10
10
|
in
|
11
|
-
val dollar_test1 =
|
11
|
+
val dollar_test1 = assert "dollar_test1" (g (h (f (g (h 2)))) = g $ h $ f $ g $ h 2)
|
12
12
|
end
|
13
|
-
val countdown_test2 =
|
14
|
-
val svgLine_test1 =
|
13
|
+
val countdown_test2 = assert "countdown_test2" ((countdown ~1; false) handle Domain => true | _ => false)
|
14
|
+
val svgLine_test1 = assert "svgLine_test1" (svgLine [(0,0), (100,100), (200,0)] = "<svg xmlns=\"http://www.w3.org/2000/svg\""^ "style=\"stroke: black; stroke-width: 2px;\">"^ "<line x1=\"0\" y1=\"0\" x2=\"100\" y2=\"100\" />"^ "<line x1=\"100\" y1=\"100\" x2=\"200\" y2=\"0\" />"^ "</svg>")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'looks_for_mosml'
|
3
|
+
|
4
|
+
describe LooksForMosml do
|
5
|
+
it "knows when mosml is not installed" do
|
6
|
+
CommandLine.should_receive(:run_command).with("which mosml > /dev/null").
|
7
|
+
and_return(true)
|
8
|
+
|
9
|
+
LooksForMosml.installed?.should be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "knows when mosml is not installed" do
|
13
|
+
CommandLine.should_receive(:run_command).with("which mosml > /dev/null").
|
14
|
+
and_return(false)
|
15
|
+
|
16
|
+
LooksForMosml.installed?.should be_false
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,20 +1,11 @@
|
|
1
1
|
require 'pp'
|
2
|
+
require_relative 'support/helper_methods'
|
2
3
|
|
3
|
-
# This file was generated by the `rspec --init` command. Conventionally, all
|
4
|
-
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
5
|
-
# Require this file using `require "spec_helper"` to ensure that it is only
|
6
|
-
# loaded once.
|
7
|
-
#
|
8
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
9
4
|
RSpec.configure do |config|
|
10
5
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
6
|
config.run_all_when_everything_filtered = true
|
12
7
|
config.filter_run :focus
|
13
8
|
|
14
|
-
# Run specs in random order to surface order dependencies. If you find an
|
15
|
-
# order dependency and want to debug it, you can fix the order by providing
|
16
|
-
# the seed, which is printed after each run.
|
17
|
-
# --seed 1234
|
18
9
|
config.order = 'random'
|
19
10
|
end
|
20
11
|
|
@@ -22,7 +13,3 @@ def fixture(fixture_name)
|
|
22
13
|
File.read("spec/fixtures/#{fixture_name}").chomp
|
23
14
|
end
|
24
15
|
|
25
|
-
def clean_tmp
|
26
|
-
Dir.glob("tmp/*").each {|f| FileUtils.rm_f(f) }
|
27
|
-
end
|
28
|
-
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require '
|
2
|
+
require 'test_output_presenter'
|
3
3
|
require 'colorize'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe TestOutputPresenter do
|
6
6
|
it "parses output for passed tests" do
|
7
|
-
output = [
|
8
|
-
|
9
|
-
|
10
|
-
]
|
7
|
+
output = double(:test_output, compile_error?: false, tests: [
|
8
|
+
double(:test, passed?: true, name: "foo_test1"),
|
9
|
+
double(:test, passed?: false, name: "foo_test2"),
|
10
|
+
])
|
11
11
|
|
12
12
|
parsed_output = [
|
13
13
|
".".green + "F".red,
|
@@ -22,14 +22,14 @@ describe TestOutputParser do
|
|
22
22
|
"",
|
23
23
|
].join("\n")
|
24
24
|
|
25
|
-
|
25
|
+
TestOutputPresenter.parse(output).should eq parsed_output
|
26
26
|
end
|
27
27
|
|
28
28
|
it "parses output with only passes" do
|
29
|
-
output = [
|
30
|
-
|
31
|
-
|
32
|
-
]
|
29
|
+
output = double(:test_output, compile_error?: false, tests: [
|
30
|
+
double(:test, passed?: true, name: "foo_test1"),
|
31
|
+
double(:test, passed?: true, name: "foo_test2"),
|
32
|
+
])
|
33
33
|
|
34
34
|
parsed_output = [
|
35
35
|
".".green+".".green,
|
@@ -40,17 +40,19 @@ describe TestOutputParser do
|
|
40
40
|
"",
|
41
41
|
].join("\n")
|
42
42
|
|
43
|
-
|
43
|
+
TestOutputPresenter.parse(output).should eq parsed_output
|
44
44
|
end
|
45
45
|
|
46
46
|
it "parses output from a failure" do
|
47
|
-
|
47
|
+
failure_message = [
|
48
48
|
'File "foo.sml", line 1, characters 0-3:',
|
49
49
|
'! foo',
|
50
50
|
'! ^^^',
|
51
51
|
'! Syntax error.',
|
52
52
|
].join("\n")
|
53
53
|
|
54
|
+
output = double(:test_output, compile_error?: true, message: failure_message)
|
55
|
+
|
54
56
|
parsed_output = [
|
55
57
|
"Unable to run tests, SML says:".red,
|
56
58
|
"",
|
@@ -61,6 +63,6 @@ describe TestOutputParser do
|
|
61
63
|
'! Syntax error.',
|
62
64
|
].join("\n")
|
63
65
|
|
64
|
-
|
66
|
+
TestOutputPresenter.parse(output).should eq parsed_output
|
65
67
|
end
|
66
68
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_output'
|
3
|
+
|
4
|
+
class Test; end
|
5
|
+
|
6
|
+
describe TestOutput do
|
7
|
+
before do
|
8
|
+
Test.stub(:new) { double(:test) }
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:lines) do
|
12
|
+
["foo_test1 true",
|
13
|
+
"foo_test2 false"]
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:failure_message) do
|
17
|
+
['File "foo.sml", line 1, characters 0-3:',
|
18
|
+
'! foo',
|
19
|
+
'! ^^^',
|
20
|
+
'! Syntax error.']
|
21
|
+
end
|
22
|
+
|
23
|
+
it "parses output from tests" do
|
24
|
+
Test.should_receive(:new).with(true, "foo_test1")
|
25
|
+
Test.should_receive(:new).with(false, "foo_test2")
|
26
|
+
|
27
|
+
output = TestOutput.new(lines)
|
28
|
+
|
29
|
+
output.compile_error?.should be_false
|
30
|
+
output.should have(2).tests
|
31
|
+
end
|
32
|
+
|
33
|
+
it "parses output from a compile error" do
|
34
|
+
output = TestOutput.new(failure_message)
|
35
|
+
|
36
|
+
output.compile_error?.should be_true
|
37
|
+
output.message.should eq failure_message.join("\n")
|
38
|
+
end
|
39
|
+
end
|
data/spec/test_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test'
|
3
|
+
|
4
|
+
describe Test do
|
5
|
+
it "can be passed" do
|
6
|
+
Test.new(true, "").should be_passed
|
7
|
+
end
|
8
|
+
|
9
|
+
it "can be failed" do
|
10
|
+
Test.new(false, "").should_not be_passed
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has a name" do
|
14
|
+
Test.new(false, "foo_test1").name.should eq "foo_test1"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has a status" do
|
18
|
+
Test.new(false, "foo_test1").status.should eq false
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smlspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Pedersen
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cucumber
|
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'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: colorize
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - '>='
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: Gem for running tests in SML files
|
56
84
|
email: david.pdrsn@gmail.com
|
57
85
|
executables:
|
@@ -61,6 +89,7 @@ extra_rdoc_files: []
|
|
61
89
|
files:
|
62
90
|
- .gitignore
|
63
91
|
- .rspec
|
92
|
+
- CHANGELOG.md
|
64
93
|
- Gemfile
|
65
94
|
- Gemfile.lock
|
66
95
|
- LICENSE
|
@@ -70,10 +99,18 @@ files:
|
|
70
99
|
- bin/smlspec
|
71
100
|
- build/smlspec-0.0.2.gem
|
72
101
|
- build/smlspec-0.0.3.gem
|
102
|
+
- build/smlspec-0.0.4.gem
|
103
|
+
- features/running_tests.feature
|
104
|
+
- features/step_definitions/smlspec_steps.rb
|
105
|
+
- features/support/env.rb
|
73
106
|
- lib/formats_lines.rb
|
74
107
|
- lib/formats_tests.rb
|
108
|
+
- lib/looks_for_mosml.rb
|
75
109
|
- lib/sml_file.rb
|
76
|
-
- lib/
|
110
|
+
- lib/test.rb
|
111
|
+
- lib/test_output.rb
|
112
|
+
- lib/test_output_presenter.rb
|
113
|
+
- scripts/cucumber_init.sh
|
77
114
|
- smlspec.gemspec
|
78
115
|
- spec/fixtures/broken_lines.sml
|
79
116
|
- spec/fixtures/formatted.sml
|
@@ -92,9 +129,13 @@ files:
|
|
92
129
|
- spec/fixtures/without_whitespace.sml
|
93
130
|
- spec/formats_lines_spec.rb
|
94
131
|
- spec/formats_tests_spec.rb
|
132
|
+
- spec/looks_for_mosml_spec.rb
|
95
133
|
- spec/sml_file_spec.rb
|
96
134
|
- spec/spec_helper.rb
|
97
|
-
- spec/
|
135
|
+
- spec/support/helper_methods.rb
|
136
|
+
- spec/test_output_presenter_spec.rb
|
137
|
+
- spec/test_output_spec.rb
|
138
|
+
- spec/test_spec.rb
|
98
139
|
homepage: http://github.com/davidpdrsn/smlspec
|
99
140
|
licenses:
|
100
141
|
- MIT
|
data/lib/test_output_parser.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
class TestOutputParser
|
2
|
-
def self.parse(input)
|
3
|
-
parser = self.new(input)
|
4
|
-
|
5
|
-
if input.match(/!/)
|
6
|
-
parser.parse_error
|
7
|
-
else
|
8
|
-
parser.parse
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(input)
|
13
|
-
@input = input
|
14
|
-
end
|
15
|
-
|
16
|
-
def parse
|
17
|
-
output = ""
|
18
|
-
|
19
|
-
output += dots_or_fs + "\n"
|
20
|
-
if failures > 0
|
21
|
-
output += blank_lines(3) + "\n"
|
22
|
-
output += failed_tests + "\n"
|
23
|
-
end
|
24
|
-
output += blank_lines(2) + "\n"
|
25
|
-
output += "#{total} tests ran, #{failures} red, #{passed} green" + "\n"
|
26
|
-
output += blank_lines(2)
|
27
|
-
|
28
|
-
output
|
29
|
-
end
|
30
|
-
|
31
|
-
def parse_error
|
32
|
-
[
|
33
|
-
"Unable to run tests, SML says:".red,
|
34
|
-
"",
|
35
|
-
"",
|
36
|
-
@input,
|
37
|
-
].join("\n")
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def blank_lines(n)
|
43
|
-
Array.new(n, "").join("\n")
|
44
|
-
end
|
45
|
-
|
46
|
-
def dots_or_fs
|
47
|
-
@input.split("\n").inject("") do |acc, s|
|
48
|
-
if s.include?("true")
|
49
|
-
acc += ".".green
|
50
|
-
else
|
51
|
-
acc += "F".red
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def failed_tests
|
57
|
-
@input.split("\n").select do |s|
|
58
|
-
s.include?("false")
|
59
|
-
end.inject("") do |acc, s|
|
60
|
-
s.gsub(" false", "").red
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def total
|
65
|
-
@input.split("\n").count
|
66
|
-
end
|
67
|
-
|
68
|
-
def failures
|
69
|
-
@input.split("\n").select do |s|
|
70
|
-
s.include?("false")
|
71
|
-
end.count
|
72
|
-
end
|
73
|
-
|
74
|
-
def passed
|
75
|
-
@input.split("\n").select do |s|
|
76
|
-
s.include?("true")
|
77
|
-
end.count
|
78
|
-
end
|
79
|
-
end
|