smlspec 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7733ae5cde5260ef92f3da004238ddf60ec7c97c
4
+ data.tar.gz: 6401875e500bed297459e6fff87fda7225875ab1
5
+ SHA512:
6
+ metadata.gz: 9d0de6647e3f19011434bb55cf8c4b8e787678d28f6c014e30fe7541fcd825c397d8b528f73f00640ff9234fbbb791299a353d0ac18107bda42e3e7a7dd05755
7
+ data.tar.gz: e1920b27447bdcbba0651f835963a25315ec6239c140b670f047c282d85d07b5c933c0ee9f207ac3693744eb8ca8ead5173ac264d64f259fd05a2cf63202d48c
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ # Numerous always-ignore extensions
2
+ *.diff
3
+ *.err
4
+ *.orig
5
+ *.log
6
+ *.rej
7
+ *.swo
8
+ *.swp
9
+ *.vi
10
+ *~
11
+ *.sass-cache
12
+ .netrwhist
13
+
14
+ # OS or Editor folders
15
+ .DS_Store
16
+ Thumbs.db
17
+ .cache
18
+ .project
19
+ .settings
20
+ .tmproj
21
+ *.esproj
22
+ nbproject
23
+ *.sublime-project
24
+ *.sublime-workspace
25
+
26
+ # Dreamweaver added files
27
+ dwsync.xml
28
+
29
+ # Komodo
30
+ *.komodoproject
31
+ .komodotools
32
+
33
+ # Folders to ignore
34
+ .hg
35
+ .svn
36
+ .CVS
37
+ intermediate
38
+ publish
39
+ .idea
40
+
41
+ # build script local files
42
+ build/buildinfo.properties
43
+ build/config/buildinfo.properties
44
+
45
+ # Rails stuff
46
+ /.bundle
47
+ /db/*.sqlite3
48
+ /log/*.log
49
+ /tmp
50
+ tags
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ smlspec (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ colorize (0.6.0)
10
+ diff-lcs (1.2.5)
11
+ rake (10.1.0)
12
+ rspec (2.14.1)
13
+ rspec-core (~> 2.14.0)
14
+ rspec-expectations (~> 2.14.0)
15
+ rspec-mocks (~> 2.14.0)
16
+ rspec-core (2.14.7)
17
+ rspec-expectations (2.14.4)
18
+ diff-lcs (>= 1.1.3, < 2.0)
19
+ rspec-mocks (2.14.4)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ colorize
26
+ rake
27
+ rspec
28
+ smlspec!
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright (c) 2013 David Pedersen
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # SML test runner
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task default: :spec
6
+
7
+ task :build do
8
+ system "gem build smlspec.gemspec"
9
+ Dir.glob("*.gem") {|f| system "mv #{f} build" }
10
+ end
11
+
12
+ task :install do
13
+ system "gem uninstall smlspec"
14
+ newest_build = Dir.glob("build/*.gem").last
15
+ system "gem install ./#{newest_build}"
16
+ end
data/TODO.md ADDED
@@ -0,0 +1,6 @@
1
+ # TODOS
2
+
3
+ [ ] - make tests of SmlFile isolated, could be done using dependency injection
4
+ [x] - append test function to file
5
+ [ ] - clean up fixtures folder
6
+ [x] - write test output parser
data/bin/smlspec ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'colorize'
4
+ require 'digest/md5'
5
+
6
+ $:.unshift("lib")
7
+ require 'formats_lines'
8
+ require 'formats_tests'
9
+ require 'sml_file'
10
+ require 'test_output_parser'
11
+
12
+ class Runner
13
+ def self.main(input)
14
+ new(input)
15
+ end
16
+
17
+ def initialize(input)
18
+ @input = input || ""
19
+ check_for_correct_input
20
+
21
+ @file = SmlFile.new(@input).prepare_tests
22
+
23
+ @file.save_as!(random_name + ".sml")
24
+
25
+ begin
26
+ @file.compile!(random_name + ".exe")
27
+ puts TestOutputParser.parse(@file.run)
28
+ rescue SmlFile::CannotCompile => e
29
+ puts TestOutputParser.parse(e.message)
30
+ ensure
31
+ clean_up!
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def clean_up!
38
+ [".uo", ".ui", ".exe"].each do |s|
39
+ FileUtils.rm_f(File.basename(@file.path, ".*") + s)
40
+ end
41
+
42
+ @file.delete!
43
+ end
44
+
45
+ def random_name
46
+ Digest::MD5.hexdigest(Time.now.to_s)
47
+ end
48
+
49
+ def check_for_correct_input
50
+ if !valid_file_input
51
+ puts "Gimme an sml file, that exists!"
52
+ exit 1
53
+ end
54
+ end
55
+
56
+ def valid_file_input
57
+ @input && File.exists?(@input) && File.extname(@input) == ".sml"
58
+ end
59
+ end
60
+
61
+ Runner.main(ARGV.first)
Binary file
Binary file
@@ -0,0 +1,61 @@
1
+ class FormatsLines
2
+ attr_reader :lines
3
+
4
+ def self.format(lines)
5
+ new(lines).tap do |f|
6
+ f.remove_comments!
7
+ f.remove_leading_whitespace!
8
+ f.join_broken_lines!
9
+ end.lines
10
+ end
11
+
12
+ def initialize(lines)
13
+ @lines = lines
14
+ @keywords = %w(
15
+ abstype and andalso as case do datatype div
16
+ else end eqtype exception extract fn fun functor
17
+ handle if in include infix infixr let local mod
18
+ nonfix of op open orelse raise rec sharing sig
19
+ signature struct structure then type val where
20
+ with withtype
21
+ )
22
+ end
23
+
24
+ def remove_comments!
25
+ @lines.gsub!(/\(\*.*?\*\)\n/m, "")
26
+ self
27
+ end
28
+
29
+ def remove_leading_whitespace!
30
+ @lines.gsub!(/^\s+/, "")
31
+ self
32
+ end
33
+
34
+ def join_broken_lines!
35
+ lines = @lines.split("\n")
36
+
37
+ each_in_reverse!(lines) do |i|
38
+ join_lines!(lines, i, i-1) if i > 0 && broken_line(lines[i])
39
+ end
40
+
41
+ @lines = lines.join("\n")
42
+ self
43
+ end
44
+
45
+ private
46
+
47
+ def broken_line(line)
48
+ not(line =~ Regexp.new("^(#{@keywords.join("|")})"))
49
+ end
50
+
51
+
52
+ def join_lines!(lines, from, to)
53
+ lines[to] = lines[to] + " " + lines.delete_at(from)
54
+ end
55
+
56
+ def each_in_reverse!(array, &block)
57
+ (0..array.length-1).to_a.reverse.each do |i|
58
+ block.call(i)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ class FormatsTests
2
+ def self.format(lines)
3
+ lines = lines.split("\n")
4
+
5
+ lines.each.with_index do |line, i|
6
+ match = line.match(/val (.*?_test\d) = (.*?)$/)
7
+
8
+ if match
9
+ lines[i] = "val #{match[1]} = test \"#{match[1]}\" (#{match[2]})"
10
+ end
11
+ end
12
+
13
+ # TODO: make this a little nicer
14
+ 'fun test desc condition = print(desc^" "^Bool.toString(condition)^"\n")' + "\n" + lines.join("\n")
15
+ end
16
+ end
data/lib/sml_file.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'fileutils'
2
+
3
+ class SmlFile
4
+ class NotCompiled < Exception; end
5
+ class CannotCompile < Exception; end
6
+ class NotSaved < Exception; end
7
+
8
+ attr_reader :contents, :path
9
+
10
+ def initialize(path, contents=nil)
11
+ @path = path
12
+ @contents = contents || File.read(@path)
13
+ end
14
+
15
+ def save_as!(new_path)
16
+ if File.write(new_path, @contents)
17
+ @path = new_path
18
+ end
19
+ end
20
+
21
+ def prepare_tests
22
+ formatted_content = FormatsTests.format(FormatsLines.format(@contents))
23
+ self.class.new(nil, formatted_content)
24
+ end
25
+
26
+ def compile!(destination)
27
+ raise NotSaved unless @path
28
+
29
+ @exe_path = destination
30
+
31
+ output = `mosmlc #{@path} -o #{@exe_path}`
32
+
33
+ unless output.empty?
34
+ raise CannotCompile, output
35
+ end
36
+ end
37
+
38
+ def run
39
+ if @exe_path
40
+ `./#{@exe_path}`
41
+ else
42
+ raise NotCompiled
43
+ end
44
+ end
45
+
46
+ def delete!
47
+ FileUtils.rm_f(@path)
48
+ @path = nil
49
+ end
50
+ end
@@ -0,0 +1,79 @@
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
data/smlspec.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'smlspec'
3
+ s.version = '0.0.3'
4
+ s.date = '2012-12-16'
5
+ s.summary = "Runner for SML tests"
6
+ s.description = "Gem for running tests in SML files"
7
+ s.authors = ["David Pedersene"]
8
+ s.email = 'david.pdrsn@gmail.com'
9
+ s.homepage = 'http://github.com/davidpdrsn/smlspec'
10
+ s.license = 'MIT'
11
+
12
+ s.add_development_dependency 'rake'
13
+ s.add_development_dependency 'rspec'
14
+ s.add_development_dependency 'colorize'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {spec}/*_spec.rb`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,10 @@
1
+ fun headString "" = ""
2
+ | headString s = String.extract (s, 0, SOME 1)
3
+ fun tailString "" = "" |
4
+ tailString s = String.extract (s, 1, NONE)
5
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
6
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
7
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] =
8
+ ["a","b","foo"]
9
+ val allDefined_test4 = allDefined [] = []
10
+ val allDefined_test5 = allDefined [NONE, NONE] = []
@@ -0,0 +1,20 @@
1
+ fun headString "" = "" | headString s = String.extract (s, 0, SOME 1)
2
+ fun tailString "" = "" | tailString s = String.extract (s, 1, NONE)
3
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
4
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
5
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] = ["a","b","foo"]
6
+ val allDefined_test4 = allDefined [] = []
7
+ val allDefined_test5 = allDefined [NONE, NONE] = []
8
+ local
9
+ fun f x = x+2
10
+ fun h x = x*2
11
+ fun g x = x div 2
12
+ in
13
+ val dollar_test1 = g (h (f (g (h 2)))) = g $ h $ f $ g $ h 2
14
+ end
15
+ val countdown_test2 = (countdown ~1; false) handle Domain => true | _ => false
16
+ val countdown_test3 = countdown 0 = [0]
17
+ val lines_test1 = lines [(0,0), (100,100), (200,0)] = "line one"^ "line two"
18
+ val 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>"
19
+ val optimiseMark_test6 = optimise' [Move 5, Repeat (0, [Move 5])] = [Move 5]
20
+ val optimiseMark_test7 = optimise' [Move 5, Turn, Turn, Repeat(0, [Move 5]), Turn, Turn, Move 37] = [Move 5, Turn, Turn, Turn, Turn, Move 37]
@@ -0,0 +1,14 @@
1
+ fun test desc condition = print(desc^" "^Bool.toString(condition)^"\n")
2
+ fun headString "" = "" | headString s = String.extract (s, 0, SOME 1)
3
+ fun tailString "" = "" | tailString s = String.extract (s, 1, NONE)
4
+ val allDefined_test1 = test "allDefined_test1" (allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7])
5
+ val allDefined_test2 = test "allDefined_test2" (allDefined [NONE,NONE,NONE] = [])
6
+ local
7
+ fun f x = x+2
8
+ fun h x = x*2
9
+ fun g x = x div 2
10
+ in
11
+ val dollar_test1 = test "dollar_test1" (g (h (f (g (h 2)))) = g $ h $ f $ g $ h 2)
12
+ end
13
+ val countdown_test2 = test "countdown_test2" ((countdown ~1; false) handle Domain => true | _ => false)
14
+ val svgLine_test1 = test "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,7 @@
1
+ fun headString "" = "" | headString s = String.extract (s, 0, SOME 1)
2
+ fun tailString "" = "" | tailString s = String.extract (s, 1, NONE)
3
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
4
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
5
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] = ["a","b","foo"]
6
+ val allDefined_test4 = allDefined [] = []
7
+ val allDefined_test5 = allDefined [NONE, NONE] = []
@@ -0,0 +1 @@
1
+ val _ = print "foo"
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ fun foo _ = 3
2
+
3
+ val foo_test1 = foo 3 = 3
4
+ val foo_test2 = foo 3 = 2
@@ -0,0 +1,49 @@
1
+ (*
2
+ headString : string -> string
3
+ return the first letter in a string
4
+ if the string is empty just return an empty string
5
+ *)
6
+ fun headString "" = ""
7
+ | headString s = String.extract (s, 0, SOME 1)
8
+
9
+ (*
10
+ tailString : string -> string
11
+ return everything but the first letter of a string
12
+ if the string is empty just return an empty string
13
+ *)
14
+ fun tailString "" = ""
15
+ | tailString s = String.extract (s, 1, NONE)
16
+
17
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
18
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
19
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] =
20
+ ["a","b","foo"]
21
+ val allDefined_test4 = allDefined [] = []
22
+ val allDefined_test5 = allDefined [NONE, NONE] = []
23
+
24
+ local
25
+ fun f x = x+2
26
+ fun h x = x*2
27
+ fun g x = x div 2
28
+ in
29
+ val dollar_test1 = g (h (f (g (h 2)))) = g $ h $ f $ g $ h 2
30
+ end
31
+
32
+ val countdown_test2 = (countdown ~1; false) handle Domain => true | _ => false
33
+ val countdown_test3 = countdown 0 = [0]
34
+
35
+ val lines_test1 = lines [(0,0), (100,100), (200,0)] =
36
+ "line one"^
37
+ "line two"
38
+
39
+ val svgLine_test1 = svgLine [(0,0), (100,100), (200,0)] =
40
+ "<svg xmlns=\"http://www.w3.org/2000/svg\""^
41
+ "style=\"stroke: black; stroke-width: 2px;\">"^
42
+ "<line x1=\"0\" y1=\"0\" x2=\"100\" y2=\"100\" />"^
43
+ "<line x1=\"100\" y1=\"100\" x2=\"200\" y2=\"0\" />"^
44
+ "</svg>"
45
+
46
+ val optimiseMark_test6 = optimise' [Move 5, Repeat (0, [Move 5])] = [Move 5]
47
+ val optimiseMark_test7 = optimise' [Move 5, Turn, Turn,
48
+ Repeat(0, [Move 5]), Turn, Turn, Move 37] =
49
+ [Move 5, Turn, Turn, Turn, Turn, Move 37]
@@ -0,0 +1,49 @@
1
+ (*
2
+ headString : string -> string
3
+ return the first letter in a string
4
+ if the string is empty just return an empty string
5
+ *)
6
+ fun headString "" = ""
7
+ | headString s = String.extract (s, 0, SOME 1)
8
+
9
+ (*
10
+ tailString : string -> string
11
+ return everything but the first letter of a string
12
+ if the string is empty just return an empty string
13
+ *)
14
+ fun tailString "" = ""
15
+ | tailString s = String.extract (s, 1, NONE)
16
+
17
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
18
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
19
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] =
20
+ ["a","b","foo"]
21
+ val allDefined_test4 = allDefined [] = []
22
+ val allDefined_test5 = allDefined [NONE, NONE] = []
23
+
24
+ local
25
+ fun f x = x+2
26
+ fun h x = x*2
27
+ fun g x = x div 2
28
+ in
29
+ val dollar_test1 = g (h (f (g (h 2)))) = g $ h $ f $ g $ h 2
30
+ end
31
+
32
+ val countdown_test2 = (countdown ~1; false) handle Domain => true | _ => false
33
+ val countdown_test3 = countdown 0 = [0]
34
+
35
+ val lines_test1 = lines [(0,0), (100,100), (200,0)] =
36
+ "line one"^
37
+ "line two"
38
+
39
+ val svgLine_test1 = svgLine [(0,0), (100,100), (200,0)] =
40
+ "<svg xmlns=\"http://www.w3.org/2000/svg\""^
41
+ "style=\"stroke: black; stroke-width: 2px;\">"^
42
+ "<line x1=\"0\" y1=\"0\" x2=\"100\" y2=\"100\" />"^
43
+ "<line x1=\"100\" y1=\"100\" x2=\"200\" y2=\"0\" />"^
44
+ "</svg>"
45
+
46
+ val optimiseMark_test6 = optimise' [Move 5, Repeat (0, [Move 5])] = [Move 5]
47
+ val optimiseMark_test7 = optimise' [Move 5, Turn, Turn,
48
+ Repeat(0, [Move 5]), Turn, Turn, Move 37] =
49
+ [Move 5, Turn, Turn, Turn, Turn, Move 37]
@@ -0,0 +1,13 @@
1
+ fun headString "" = "" | headString s = String.extract (s, 0, SOME 1)
2
+ fun tailString "" = "" | tailString s = String.extract (s, 1, NONE)
3
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
4
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
5
+ local
6
+ fun f x = x+2
7
+ fun h x = x*2
8
+ fun g x = x div 2
9
+ in
10
+ val dollar_test1 = g (h (f (g (h 2)))) = g $ h $ f $ g $ h 2
11
+ end
12
+ val countdown_test2 = (countdown ~1; false) handle Domain => true | _ => false
13
+ val 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,15 @@
1
+ (*
2
+ headString : string -> string
3
+ return the first letter in a string
4
+ if the string is empty just return an empty string
5
+ *)
6
+ fun headString "" = ""
7
+ | headString s = String.extract (s, 0, SOME 1)
8
+
9
+ (*
10
+ tailString : string -> string
11
+ return everything but the first letter of a string
12
+ if the string is empty just return an empty string
13
+ *)
14
+ fun tailString "" = ""
15
+ | tailString s = String.extract (s, 1, NONE)
@@ -0,0 +1,9 @@
1
+ fun headString "" = ""
2
+ | headString s = String.extract (s, 0, SOME 1)
3
+
4
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
5
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
6
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] =
7
+ ["a","b","foo"]
8
+ val allDefined_test4 = allDefined [] = []
9
+ val allDefined_test5 = allDefined [NONE, NONE] = []
@@ -0,0 +1,5 @@
1
+ fun headString "" = ""
2
+ | headString s = String.extract (s, 0, SOME 1)
3
+
4
+ fun tailString "" = ""
5
+ | tailString s = String.extract (s, 1, NONE)
@@ -0,0 +1,8 @@
1
+ fun headString "" = ""
2
+ | headString s = String.extract (s, 0, SOME 1)
3
+ val allDefined_test1 = allDefined [NONE,SOME 7,SOME 3,NONE, SOME 7] = [7,3,7]
4
+ val allDefined_test2 = allDefined [NONE,NONE,NONE] = []
5
+ val allDefined_test3 = allDefined [SOME "a", NONE, SOME "b", SOME "foo"] =
6
+ ["a","b","foo"]
7
+ val allDefined_test4 = allDefined [] = []
8
+ val allDefined_test5 = allDefined [NONE, NONE] = []
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'formats_lines'
3
+
4
+ describe FormatsLines do
5
+ it "formats lines" do
6
+ unformatted = fixture("unformatted.sml")
7
+ formatted = fixture("formatted.sml")
8
+
9
+ FormatsLines.format(unformatted).should eq formatted
10
+ end
11
+
12
+ it "doesn't die when given one that that should be joined" do
13
+ FormatsLines.format("foo _ = 3").should eq "foo _ = 3"
14
+ end
15
+
16
+ it "removes comments" do
17
+ formatter = FormatsLines.new(fixture("with_comments.sml"))
18
+ fixed = fixture("without_comments.sml")
19
+
20
+ formatter.remove_comments!
21
+
22
+ formatter.lines.should eq fixed
23
+ end
24
+
25
+ it "remove leading whitespace where necessary" do
26
+ formatter = FormatsLines.new(fixture("with_whitespace.sml"))
27
+ fixed = fixture("without_whitespace.sml")
28
+
29
+ formatter.remove_leading_whitespace!
30
+
31
+ formatter.lines.should eq fixed
32
+ end
33
+
34
+ it "joins lines that have been broken" do
35
+ formatter = FormatsLines.new(fixture("broken_lines.sml"))
36
+ fixed = fixture("joined_lines.sml")
37
+
38
+ formatter.join_broken_lines!
39
+
40
+ formatter.lines.should eq fixed
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ require 'formats_tests'
3
+
4
+ describe FormatsTests do
5
+ it "formats tests" do
6
+ unformatted = fixture("unformatted_tests.sml")
7
+ formatted = fixture("formatted_tests.sml")
8
+
9
+ FormatsTests.format(unformatted).should eq formatted
10
+ end
11
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+ require 'formats_lines'
3
+ require 'formats_tests'
4
+ require 'sml_file'
5
+
6
+ describe SmlFile do
7
+ before(:each) { clean_tmp }
8
+ after(:each) { clean_tmp }
9
+
10
+ let(:file) { SmlFile.new("spec/fixtures/unformatted_tests.sml") }
11
+
12
+ describe "#save_as!" do
13
+ before { file.save_as!("tmp/saved_as.sml") }
14
+
15
+ it "saves the file to the specified folder" do
16
+ File.read("tmp/saved_as.sml").should eq file.contents
17
+ end
18
+
19
+ it "updates the path" do
20
+ file.path.should eq "tmp/saved_as.sml"
21
+ end
22
+ end
23
+
24
+ describe "#prepare_tests" do
25
+ it "prepares the tests" do
26
+ file_with_tests_prepared = file.prepare_tests
27
+
28
+ file_with_tests_prepared.contents.should eq fixture("formatted_tests.sml")
29
+ end
30
+ end
31
+
32
+ describe "#compile!" do
33
+ it "compiles the file into the specified destination" do
34
+ file = SmlFile.new("spec/fixtures/simple.sml")
35
+ file.compile!("tmp/foo.exe")
36
+
37
+ File.exists?("tmp/foo.exe").should be_true
38
+ end
39
+
40
+ it "throws an exception with the compile error if it doesn't compile" do
41
+ file = SmlFile.new("spec/fixtures/formatted.sml")
42
+
43
+ expect do
44
+ file.compile!("tmp/foo.exe")
45
+ end.to raise_error(SmlFile::CannotCompile, /File "spec\/fixtures\/formatted\.sml"/)
46
+ end
47
+
48
+ it "doens't compile files that haven't been saved to disk" do
49
+ file_with_tests_prepared = file.prepare_tests
50
+
51
+ expect do
52
+ file_with_tests_prepared.compile!("tmp/foo.exe")
53
+ end.to raise_error SmlFile::NotSaved
54
+ end
55
+ end
56
+
57
+ describe "#run" do
58
+ let(:file) { SmlFile.new("spec/fixtures/simple.sml") }
59
+
60
+ it "returns the output of running the file" do
61
+ file.compile!("tmp/foo.exe")
62
+
63
+ file.run.should eq "foo"
64
+ end
65
+
66
+ it "doesn't run without first having been compiled" do
67
+ expect do
68
+ file.run
69
+ end.to raise_error SmlFile::NotCompiled
70
+ end
71
+ end
72
+
73
+ describe "#delete!" do
74
+ it "deletes the file" do
75
+ File.write("tmp/tmp.sml", "")
76
+ f = SmlFile.new("tmp/tmp.sml")
77
+
78
+ expect do
79
+ f.delete!
80
+ end.to change { File.exists?("tmp/tmp.sml") }
81
+ f.path.should be_nil
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,28 @@
1
+ require 'pp'
2
+
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
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
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
+ config.order = 'random'
19
+ end
20
+
21
+ def fixture(fixture_name)
22
+ File.read("spec/fixtures/#{fixture_name}").chomp
23
+ end
24
+
25
+ def clean_tmp
26
+ Dir.glob("tmp/*").each {|f| FileUtils.rm_f(f) }
27
+ end
28
+
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'test_output_parser'
3
+ require 'colorize'
4
+
5
+ describe TestOutputParser do
6
+ it "parses output for passed tests" do
7
+ output = [
8
+ "foo_test1 true",
9
+ "foo_test2 false",
10
+ ].join("\n")
11
+
12
+ parsed_output = [
13
+ ".".green + "F".red,
14
+ "",
15
+ "",
16
+ "",
17
+ "foo_test2".red,
18
+ "",
19
+ "",
20
+ "2 tests ran, 1 red, 1 green",
21
+ "",
22
+ "",
23
+ ].join("\n")
24
+
25
+ TestOutputParser.parse(output).should eq parsed_output
26
+ end
27
+
28
+ it "parses output with only passes" do
29
+ output = [
30
+ "foo_test1 true",
31
+ "foo_test2 true",
32
+ ].join("\n")
33
+
34
+ parsed_output = [
35
+ ".".green+".".green,
36
+ "",
37
+ "",
38
+ "2 tests ran, 0 red, 2 green",
39
+ "",
40
+ "",
41
+ ].join("\n")
42
+
43
+ TestOutputParser.parse(output).should eq parsed_output
44
+ end
45
+
46
+ it "parses output from a failure" do
47
+ output = [
48
+ 'File "foo.sml", line 1, characters 0-3:',
49
+ '! foo',
50
+ '! ^^^',
51
+ '! Syntax error.',
52
+ ].join("\n")
53
+
54
+ parsed_output = [
55
+ "Unable to run tests, SML says:".red,
56
+ "",
57
+ "",
58
+ 'File "foo.sml", line 1, characters 0-3:',
59
+ '! foo',
60
+ '! ^^^',
61
+ '! Syntax error.',
62
+ ].join("\n")
63
+
64
+ TestOutputParser.parse(output).should eq parsed_output
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smlspec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - David Pedersene
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2012-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
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
+ description: Gem for running tests in SML files
56
+ email: david.pdrsn@gmail.com
57
+ executables:
58
+ - smlspec
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - TODO.md
70
+ - bin/smlspec
71
+ - build/smlspec-0.0.2.gem
72
+ - build/smlspec-0.0.3.gem
73
+ - lib/formats_lines.rb
74
+ - lib/formats_tests.rb
75
+ - lib/sml_file.rb
76
+ - lib/test_output_parser.rb
77
+ - smlspec.gemspec
78
+ - spec/fixtures/broken_lines.sml
79
+ - spec/fixtures/formatted.sml
80
+ - spec/fixtures/formatted_tests.sml
81
+ - spec/fixtures/joined_lines.sml
82
+ - spec/fixtures/simple.sml
83
+ - spec/fixtures/simple.ui
84
+ - spec/fixtures/simple.uo
85
+ - spec/fixtures/simple_test_file.sml
86
+ - spec/fixtures/sml_file.sml
87
+ - spec/fixtures/unformatted.sml
88
+ - spec/fixtures/unformatted_tests.sml
89
+ - spec/fixtures/with_comments.sml
90
+ - spec/fixtures/with_whitespace.sml
91
+ - spec/fixtures/without_comments.sml
92
+ - spec/fixtures/without_whitespace.sml
93
+ - spec/formats_lines_spec.rb
94
+ - spec/formats_tests_spec.rb
95
+ - spec/sml_file_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/test_output_parser_spec.rb
98
+ homepage: http://github.com/davidpdrsn/smlspec
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.1.11
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Runner for SML tests
122
+ test_files: []