markspec 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c6f61694a82f4c891ac57a94e00479d8cd8d3207761fc77632e2045e9d0d412
4
- data.tar.gz: f9d2e3127e41cf332ceb4129c3912268bf62b75b2a52e1d3231ab45271def615
3
+ metadata.gz: c93363bd6796074773e2109ab50d0c21d62fea33bb4c6caf7ca016f18deedf2e
4
+ data.tar.gz: a369ede284c3bb65faff5173dcd57cc838e28c9c8e5344a09a525b8d7a4962ac
5
5
  SHA512:
6
- metadata.gz: 1a4356094c0be65fd875002ce17b782dcc9b80a253d320fba2fa001f2bc17f0b89d2e91e92fd48767108e301fe1cea1beea9991763d8de4c19035d6cdaeba004
7
- data.tar.gz: 5866af0a93d0e4950b31cb32db697e43341db5a3c81e7ab8b040e35a8b0bcc7c4acd2b62b12e5165bae4e737c5397efe1b33604ba992964893b7886f46a52988
6
+ metadata.gz: 458abc0bdd08ddeed905c2bbb1f719bbc13df17c1946c348803c6fb92a1ce2f61648054086956a06b63e6e7db641cd1a85e716ff696791feaea060a9660a45e0
7
+ data.tar.gz: 797bd70887fbc0e0084f75021750bcc9230e43816b2c7ff25fbb05a09a651ed3af729a754a79a9683b99816307aea92323fb135c8d311cbf4bee3f9d14043f7a
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'markspec'
4
+ require 'fileutils'
5
+ require 'yaml'
6
+ require 'open3'
7
+ require 'colorize'
8
+
9
+ files = [ARGV[0]]
10
+ files = Dir['spec/**/*.md'] if files.first.nil?
11
+
12
+ CUTTER_REGEX = /^(?<front>(```|~~~)[a-z0-9]+).+/.freeze
13
+
14
+ def preprocess_file(file)
15
+ contents = File.read file
16
+
17
+ contexts = []
18
+ blocks = []
19
+
20
+ lines = contents.split "\n"
21
+ inside_type = false
22
+ current_block = []
23
+
24
+ nlines = lines.map do |line|
25
+ # if inside_type
26
+ # puts "#{inside_type} #{line}"
27
+ # else
28
+ # puts " #{line}"
29
+ # end
30
+
31
+ if line[0..2] == inside_type
32
+ inside_type = false
33
+ blocks << current_block.join("\n")
34
+ current_block = []
35
+ elsif inside_type
36
+ current_block << line
37
+ end
38
+
39
+ if !inside_type
40
+ line.gsub(CUTTER_REGEX) do |m|
41
+ contexts << m
42
+ matched = CUTTER_REGEX.match(m)
43
+ inside_type = matched[:front][0..2]
44
+
45
+ matched[:front]
46
+ end
47
+ else
48
+ line
49
+ end
50
+ end
51
+
52
+ { raw: nlines.join("\n"), contexts: contexts, blocks: blocks }
53
+ end
54
+
55
+ # a test case
56
+ class TestCase
57
+ attr_reader :expected, :matcher, :exception, :file, :results_list
58
+
59
+ def initialize(cmds, file)
60
+ @file = file
61
+ @prep = []
62
+ @commands = []
63
+ @cmds = cmds
64
+ @results_list = []
65
+ parse!
66
+ end
67
+
68
+ def pass?
69
+ @pass ||= begin
70
+ execute!
71
+ @result ? true : false
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def execute!
78
+ tempfiles = []
79
+
80
+ @prep.each do |info|
81
+ File.write(info[:file], info[:content])
82
+ tempfiles << { temp: info[:file] }
83
+ end
84
+
85
+ actually_execute!
86
+
87
+ tempfiles.each do |info|
88
+ FileUtils.rm info[:temp]
89
+ end
90
+ end
91
+
92
+ def actually_execute!
93
+
94
+ @result = true
95
+
96
+ stdout = ''
97
+ stderr = ''
98
+ status = ''
99
+
100
+ @commands.each_with_index do |cmd, index|
101
+ begin
102
+ if cmd[:kind] == :command
103
+ block = cmd[:block]
104
+ stdout, stderr, status = Open3.capture3(block)
105
+
106
+ elsif cmd[:kind] == :expectation
107
+ matched_result = case cmd[:thing]
108
+ when /^file:(.+)(:)?/
109
+ File.read(Regexp.last_match(1)).chomp
110
+ when 'stdout'
111
+ stdout
112
+ when 'stderr'
113
+ stderr
114
+ when 'exitcode'
115
+ status.exitstatus.to_s
116
+ end
117
+
118
+ this_result = case cmd[:type]
119
+ when 'binary'
120
+ chars = cmd[:content]
121
+ .split(/\s+/)
122
+ .map { |x| x.to_i(16) }
123
+
124
+ exp_chars = matched_result.chars.map(&:ord)
125
+
126
+ @expected = exp_chars.inspect
127
+ @matcher = chars.inspect
128
+
129
+ if chars.length != exp_chars.length
130
+ false
131
+ else
132
+ exp_chars == chars
133
+ end
134
+ when 'regex'
135
+ @expected = Regexp.new(cmd[:content].chomp.uncolorize).inspect
136
+ @matcher = matched_result.inspect
137
+
138
+ Regexp.new(cmd[:content].chomp.uncolorize) =~ matched_result
139
+ else
140
+ @expected = cmd[:content].inspect
141
+ @matcher = matched_result.chomp.uncolorize.inspect
142
+
143
+ matched_result.chomp.uncolorize == cmd[:content].chomp
144
+ end
145
+
146
+ @results_list << {
147
+ pass: this_result,
148
+ index: index,
149
+ file: file
150
+ }
151
+ @result &&= this_result
152
+ end
153
+ rescue StandardError => _e
154
+ @result = false
155
+ end
156
+ end
157
+
158
+ nil
159
+ end
160
+
161
+ def parse!
162
+ @cmds.each do |annotation, block|
163
+ x = CUTTER_REGEX.match(annotation)
164
+ command = annotation.sub(/^#{x[:front]}\s+/, '')
165
+
166
+ case command
167
+ when /^file:(.+)/
168
+ @prep << { file: Regexp.last_match(1), content: block }
169
+ when /^command/
170
+ @commands << {
171
+ kind: :command,
172
+ block: block
173
+ }
174
+ when /^expected (.+)/
175
+ @commands << {
176
+ kind: :expectation,
177
+ thing: Regexp.last_match(1),
178
+ content: block || '',
179
+ type: x[:front][3..-1]
180
+ }
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ failcases = []
187
+ files.each do |file|
188
+ info = preprocess_file file
189
+ cmds = info[:contexts].zip(info[:blocks])
190
+ print "Test: #{file} - "
191
+ tc = TestCase.new(cmds, file)
192
+ failcases << tc unless tc.pass?
193
+ if tc.results_list.length.nonzero?
194
+ puts(tc.results_list.map { |x| x[:pass] ? 'pass'.green : 'fail'.red }.join(' '))
195
+ else
196
+ puts 'none'.yellow
197
+ end
198
+ end
199
+
200
+ if failcases.length.nonzero?
201
+ STDERR.puts "Failures detected: #{failcases.length} cases"
202
+ failcases.each_with_index do |c, i|
203
+ STDERR.puts
204
+ STDERR.puts "#{i+1}. bundle exec markspec #{c.file}"
205
+ STDERR.puts " expected: #{c.expected}"
206
+ STDERR.puts " got: #{c.matcher}"
207
+ end
208
+ end
File without changes
@@ -1,3 +1,3 @@
1
1
  module Markspec
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -32,4 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'bundler', '~> 2.0'
33
33
  spec.add_development_dependency 'rake', '~> 10.0'
34
34
  spec.add_development_dependency 'rspec', '~> 3.0'
35
+
36
+ spec.add_dependency 'colorize'
35
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Siaw
@@ -52,16 +52,32 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: colorize
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: a longer description
56
70
  email:
57
71
  - dsiaw@degica.com
58
- executables: []
72
+ executables:
73
+ - markspec
59
74
  extensions: []
60
75
  extra_rdoc_files: []
61
76
  files:
62
77
  - Gemfile
78
+ - exe/markspec
79
+ - lib/markspec.rb
63
80
  - lib/markspec/version.rb
64
- - lib/mdspec.rb
65
81
  - markspec.gemspec
66
82
  homepage: https://github.com/davidsiaw/markspec
67
83
  licenses: