testml-lite 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ GemSpec = Gem::Specification.new do |gem|
4
+ gem.name = 'testml-lite'
5
+ gem.version = '0.0.1'
6
+ gem.license = 'MIT'
7
+ gem.required_ruby_version = '>= 1.9.1'
8
+
9
+ gem.authors << 'Ingy döt Net'
10
+ gem.email = 'ingy@ingy.net'
11
+ gem.summary = 'Acmeist Unit Test Framework'
12
+ gem.description = <<-'.'
13
+ TestML is an Acmeist testing framework. TestML::Lite is smaller bootstrap
14
+ version of TestML.
15
+ .
16
+ gem.homepage = 'http://testml.org'
17
+
18
+ gem.files = `git ls-files`.lines.map{|l|l.chomp}
19
+ end
@@ -0,0 +1,3 @@
1
+ - version: 0.0.1
2
+ date: Tue Dec 18 19:54:09 PST 2012
3
+ changes: First release
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ (The MIT License)
2
+
3
+ Copyright © 2012 Ingy döt Net
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the ‘Software’), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ = testml-lite - Lite Version of TestML for Ruby
2
+
3
+ TestML is an Acmeist Unit Test language/framework. TestML::Lite is a lighter,
4
+ bootstrapping implementation of that.
5
+
6
+ = Synopsis
7
+
8
+ require 'testml/lite'
9
+
10
+ = Copyright
11
+
12
+ Copyright (c) 2012 Ingy döt Net. See LICENSE for further details.
@@ -0,0 +1,64 @@
1
+ # Load Gem constants from the gemspec
2
+ GemSpecFile = '.gemspec'
3
+ load GemSpecFile
4
+ GemName = GemSpec.name
5
+ GemVersion = GemSpec.version
6
+ GemDir = "#{GemName}-#{GemVersion}"
7
+ GemFile = "#{GemDir}.gem"
8
+ DevNull = '2>/dev/null'
9
+
10
+ # Require the Rake libraries
11
+ require 'rake'
12
+ require 'rake/testtask'
13
+ require 'rake/clean'
14
+
15
+ task :default => 'help'
16
+
17
+ CLEAN.include GemDir, GemFile, 'data.tar.gz', 'metadata.gz'
18
+
19
+ desc 'Run the tests'
20
+ task :test do
21
+ Rake::TestTask.new do |t|
22
+ t.verbose = true
23
+ t.test_files = FileList['test/*.rb']
24
+ end
25
+ end
26
+
27
+ desc 'Build the gem'
28
+ task :build => [:clean, :test] do
29
+ sh "gem build #{GemSpecFile}"
30
+ end
31
+
32
+ desc 'Install the gem'
33
+ task :install => [:build] do
34
+ sh "gem install #{GemFile}"
35
+ end
36
+
37
+ desc 'Build, unpack and inspect the gem'
38
+ task :distdir => [:build] do
39
+ sh "tar xf #{GemFile} #{DevNull}"
40
+ Dir.mkdir GemDir
41
+ Dir.chdir GemDir
42
+ sh "tar xzf ../data.tar.gz #{DevNull}"
43
+ puts "\n>>> Entering sub-shell for #{GemDir}..."
44
+ system ENV['SHELL']
45
+ end
46
+
47
+ desc 'Build and push the gem'
48
+ task :release => [:build] do
49
+ sh "gem push #{GemFile}"
50
+ end
51
+
52
+ desc 'Print a description of the gem'
53
+ task :desc do
54
+ puts "Gem: '#{GemName}' (version #{GemVersion})"
55
+ puts
56
+ puts GemSpec.description.gsub /^/, ' '
57
+ end
58
+
59
+ desc 'List the Rakefile tasks'
60
+ task :help do
61
+ puts 'The following rake tasks are available:'
62
+ puts
63
+ puts `rake -T`.gsub /^/, ' '
64
+ end
@@ -0,0 +1,218 @@
1
+ # Make sure tests have access to the application libs and the testing libs.
2
+ $:.unshift Dir.getwd + '/lib'
3
+ $:.unshift Dir.getwd + '/test/lib'
4
+
5
+ require 'test/unit'
6
+
7
+ module TestML
8
+ def self.run &runner
9
+ name = _get_test_name
10
+ $testml_runners[name] = runner
11
+ TestML::Lite::TestCases.send(:define_method, name) do
12
+ _run_runner name
13
+ end
14
+ end
15
+
16
+ def self.data data
17
+ $testml_data[_get_test_name] = data
18
+ end
19
+
20
+ def self.require_or_skip module_
21
+ require module_
22
+ rescue exit
23
+ end
24
+ end
25
+
26
+ $testml_runners ||= {}
27
+ $testml_data ||= {}
28
+
29
+ class TestML::Lite < Test::Unit::TestCase
30
+ def data input
31
+ unless input.match /\n/
32
+ File.open(input, 'r') {|f| input = f.read}
33
+ end
34
+ @testml = _parse_tml input
35
+ end
36
+
37
+ def label text
38
+ @label = text
39
+ end
40
+
41
+ def eval expr, callback=nil
42
+ _assert_testml
43
+ expr = _parse_expr expr if expr.kind_of? String
44
+ callback ||= method 'run_test'
45
+ _get_blocks(expr).each do |block|
46
+ $error = nil
47
+ callback.call(block, expr)
48
+ raise $error if $error
49
+ end
50
+ end
51
+
52
+ def run_test block, expr
53
+ expr = _parse_expr expr if expr.kind_of? String
54
+ block = _get_blocks(expr, [block]).first or return
55
+ _evaluate expr, block
56
+ end
57
+
58
+ def assert_equal got, want, block
59
+ label = block.kind_of?(String) ? block : block[:title]
60
+ if got != want
61
+ on_fail if respond_to? 'on_fail'
62
+ File.open('/tmp/got', 'w') {|f| f.write got}
63
+ File.open('/tmp/want', 'w') {|f| f.write want}
64
+ puts `diff -u /tmp/want /tmp/got`
65
+ end
66
+ super want, got, label
67
+ end
68
+
69
+ def assert_match got, want, block
70
+ label = block.kind_of?(String) ? block : block[:title]
71
+ super want, got, label
72
+ end
73
+
74
+ def Catch any=nil
75
+ fail "Catch called, but no error occurred" unless $error
76
+ error = $error
77
+ $error = nil
78
+ return error.message
79
+ end
80
+
81
+ def _run_runner name
82
+ @test_name = name
83
+ $testml_runners[name].call(self)
84
+ end
85
+
86
+ def _assert_testml
87
+ return if defined? @testml
88
+ raise "No testml data provided" unless $testml_data[@test_name]
89
+ data $testml_data[@test_name]
90
+ end
91
+
92
+ def _evaluate expr, block
93
+ expr = ['', expr] if expr.kind_of? String
94
+ func = expr.first
95
+ args = expr[1..expr.length-1].collect do |ex|
96
+ if ex.kind_of? Array
97
+ _evaluate ex, block
98
+ elsif ex =~ /\A\*(\w+)\z/
99
+ block[:points][$1]
100
+ else
101
+ ex
102
+ end
103
+ end
104
+ # TODO @error
105
+ return if $error and func != 'Catch'
106
+ return args.first if func.empty?
107
+ args << block if func =~ /^assert_/
108
+ begin
109
+ return method(func).call(*args)
110
+ rescue => e
111
+ $error = e
112
+ end
113
+ end
114
+
115
+ def _get_blocks expr, blocks=@testml
116
+ want = expr.flatten.grep(/^\*/).collect{|ex| ex.gsub /^\*/, ''}
117
+ only = blocks.select{|block| block['ONLY']}
118
+ blocks = only unless only.empty?
119
+ final = []
120
+ blocks.each do |block|
121
+ next if block['SKIP']
122
+ ok = true
123
+ want.each do |w|
124
+ unless block[:points][w]
125
+ ok = false
126
+ break
127
+ end
128
+ end
129
+ if ok
130
+ final << block
131
+ break if block['LAST']
132
+ end
133
+ end
134
+ return final
135
+ end
136
+
137
+ def _parse_expr expr
138
+ left, op, right = [], nil, nil
139
+ side = left
140
+ while expr.length != 0
141
+ t = _get_token expr
142
+ if t =~ /^(==|~~)$/
143
+ op = t == '==' ? 'assert_equal' : 'assert_match'
144
+ left = side
145
+ side = right = []
146
+ else
147
+ side = [side] if side.size >= 2
148
+ side.unshift t
149
+ end
150
+ end
151
+ right = side if right
152
+ return left unless right
153
+ left = left.first if left.size == 1
154
+ right = right.first if right.size == 1
155
+ return [op, left, right]
156
+ end
157
+
158
+ def _get_token expr
159
+ if expr.sub! /^(\w+)\(([^\)]+)\)\.?/, ''
160
+ token, args = [$1], $2
161
+ token.concat(
162
+ args.split(/,\s*/).map {|t| t.sub /^(['"])(.*)\1$/, '\2'}
163
+ )
164
+ elsif expr.sub! /^\s*(==|~~)\s*/, ''
165
+ token = $1
166
+ elsif expr.sub! /^([\*\w]+)\.?/, ''
167
+ token = $1
168
+ end
169
+ return token
170
+ end
171
+
172
+ def _parse_tml string
173
+ string.gsub! /^#.*\n/, ''
174
+ string.gsub! /^\\/, ''
175
+ string.gsub! /^\s*\n/, ''
176
+ blocks = string.split /(^===.*?(?=^===|\z))/m
177
+ blocks.reject!{|b| b.empty?}
178
+ blocks.each do |block|
179
+ block.gsub! /\n+\z/, "\n"
180
+ end
181
+
182
+ array = []
183
+ blocks.each do |string_block|
184
+ block = {}
185
+ string_block.gsub! /^===\ +(.*?)\ *\n/, '' \
186
+ or fail "No block title! #{string_block}"
187
+ block[:title] = $1
188
+ while !string_block.empty? do
189
+ if string_block.gsub! /\A---\ +(\w+):\ +(.*)\n/, '' or
190
+ string_block.gsub! /\A---\ +(\w+)\n(.*?)(?=^---|\z)/m, ''
191
+ key, value = $1, $2
192
+ else
193
+ raise "Failed to parse TestML string:\n#{string_block}"
194
+ end
195
+ block[:points] ||= {}
196
+ block[:points][key] = value
197
+
198
+ if key =~ /^(ONLY|SKIP|LAST)$/
199
+ block[key] = true
200
+ end
201
+ end
202
+ array << block
203
+ end
204
+ return array
205
+ end
206
+ end
207
+
208
+ # Find the first call stack entry that looks like: .../test/xxx-yyy.rb
209
+ # and return 'test_xxx_yyy' as the test name.
210
+ def _get_test_name
211
+ name = caller.map { |s|
212
+ s.split(':').first
213
+ }.grep(/(^|\/)test\/[-\w]+\.rb$/).first or fail
214
+ name.gsub!(/^(?:.*\/)?test\/([-\w+]+)\.rb$/, '\1').gsub(/[^\w]+/, '_')
215
+ return "test_#{name}"
216
+ end
217
+
218
+ module TestML::Lite::TestCases;end
@@ -0,0 +1,15 @@
1
+ require './lib/testml/lite'
2
+
3
+ class TestTestMLLite < TestML::Lite
4
+ include TestML::Lite::TestCases
5
+
6
+ def json_load json
7
+ require 'json'
8
+ JSON.load json
9
+ end
10
+
11
+ def yaml_dump object
12
+ require 'yaml'
13
+ YAML.dump(object).sub(/\A---\n/, '')
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ require './test/lib/test_testml_lite'
2
+
3
+ TestML.require_or_skip 'json'
4
+ TestML.require_or_skip 'yaml'
5
+
6
+ TestML.run do |t|
7
+ t.eval '*json.json_load.yaml_dump == *yaml'
8
+ end
9
+
10
+ TestML.data <<'...'
11
+ === Array
12
+ --- json: [1,2,3]
13
+ --- yaml
14
+ - 1
15
+ - 2
16
+ - 3
17
+ ...
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: testml-lite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ingy döt Net
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-20 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'TestML is an Acmeist testing framework. TestML::Lite is smaller bootstrap
15
+
16
+ version of TestML.
17
+
18
+ '
19
+ email: ingy@ingy.net
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - .gemspec
25
+ - CHANGELOG.yaml
26
+ - Gemfile
27
+ - LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - lib/testml/lite.rb
31
+ - test/lib/test_testml_lite.rb
32
+ - test/test1.rb
33
+ homepage: http://testml.org
34
+ licenses:
35
+ - MIT
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.9.1
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 1.8.23
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Acmeist Unit Test Framework
58
+ test_files: []