tryouts 2.4.1 → 3.0.0.pre2

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.
@@ -0,0 +1,88 @@
1
+ # lib/tryouts/translators/rspec_translator.rb
2
+
3
+ class Tryouts
4
+ module Translators
5
+ class RSpecTranslator
6
+ def initialize
7
+ require 'rspec/core'
8
+ rescue LoadError
9
+ raise 'RSpec gem is required for RSpec translation'
10
+ end
11
+
12
+ def translate(testrun)
13
+ file_basename = File.basename(testrun.source_file, '.rb')
14
+
15
+ RSpec.describe "Tryouts: #{file_basename}" do
16
+ # Setup before all tests
17
+ if testrun.setup && !testrun.setup.empty?
18
+ before(:all) do
19
+ instance_eval(testrun.setup.code)
20
+ end
21
+ end
22
+
23
+ # Generate test cases
24
+ testrun.test_cases.each_with_index do |test_case, _index|
25
+ next if test_case.empty? || !test_case.expectations?
26
+
27
+ it test_case.description do
28
+ result = instance_eval(test_case.code) unless test_case.code.strip.empty?
29
+
30
+ test_case.expectations.each do |expectation|
31
+ expected_value = instance_eval(expectation)
32
+ expect(result).to eq(expected_value)
33
+ end
34
+ end
35
+ end
36
+
37
+ # Teardown after all tests
38
+ if testrun.teardown && !testrun.teardown.empty?
39
+ after(:all) do
40
+ instance_eval(testrun.teardown.code)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ def generate_code(testrun)
47
+ file_basename = File.basename(testrun.source_file, '.rb')
48
+ lines = []
49
+
50
+ lines << ''
51
+ lines << "RSpec.describe '#{file_basename}' do"
52
+
53
+ if testrun.setup && !testrun.setup.empty?
54
+ lines << ' before(:all) do'
55
+ testrun.setup.code.lines.each { |line| lines << " #{line.chomp}" }
56
+ lines << ' end'
57
+ lines << ''
58
+ end
59
+
60
+ testrun.test_cases.each_with_index do |test_case, _index|
61
+ next if test_case.empty? || !test_case.expectations?
62
+
63
+ lines << " it '#{test_case.description}' do"
64
+ unless test_case.code.strip.empty?
65
+ lines << ' result = begin'
66
+ test_case.code.lines.each { |line| lines << " #{line.chomp}" }
67
+ lines << ' end'
68
+ end
69
+
70
+ test_case.expectations.each do |expectation|
71
+ lines << " expect(result).to eq(#{expectation})"
72
+ end
73
+ lines << ' end'
74
+ lines << ''
75
+ end
76
+
77
+ if testrun.teardown && !testrun.teardown.empty?
78
+ lines << ' after(:all) do'
79
+ testrun.teardown.code.lines.each { |line| lines << " #{line.chomp}" }
80
+ lines << ' end'
81
+ end
82
+
83
+ lines << 'end'
84
+ lines.join("\n")
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,15 +1,5 @@
1
- # frozen_string_literal: true
1
+ # lib/tryouts/version.rb
2
2
 
3
3
  class Tryouts
4
- module VERSION
5
- def self.to_s
6
- version_file
7
- [@version_file[:MAJOR], @version_file[:MINOR], @version_file[:PATCH]].join('.')
8
- end
9
- alias_method :inspect, :to_s
10
- def self.version_file
11
- require 'yaml'
12
- @version_file ||= YAML.load_file(File.join(TRYOUTS_LIB_HOME, '..', 'VERSION.yml'))
13
- end
14
- end
4
+ VERSION = '3.0.0.pre2'
15
5
  end
data/lib/tryouts.rb CHANGED
@@ -1,23 +1,25 @@
1
- # frozen_string_literal: true
1
+ # lib/tryouts.rb
2
+
3
+
2
4
 
3
5
  require 'stringio'
4
6
 
5
7
  TRYOUTS_LIB_HOME = __dir__ unless defined?(TRYOUTS_LIB_HOME)
6
8
 
7
9
  require_relative 'tryouts/console'
8
- require_relative 'tryouts/section'
9
10
  require_relative 'tryouts/testbatch'
10
- require_relative 'tryouts/testcase'
11
11
  require_relative 'tryouts/version'
12
+ require_relative 'tryouts/prism_parser'
13
+ require_relative 'tryouts/cli'
12
14
 
13
15
  class Tryouts
14
- @debug = false
15
- @quiet = false
16
- @noisy = false
17
- @fails = false
18
- @container = Class.new
19
- @cases = []
20
- @sysinfo = nil
16
+ @debug = false
17
+ @quiet = false
18
+ @noisy = false
19
+ @fails = false
20
+ @container = Class.new
21
+ @cases = [] # rubocop:disable ThreadSafety/MutableClassInstanceVariable
22
+ @sysinfo = nil
21
23
  @testcase_io = StringIO.new
22
24
 
23
25
  module ClassMethods
@@ -39,260 +41,11 @@ class Tryouts
39
41
  Dir.glob(lib_glob).each { |dir| $LOAD_PATH.unshift(dir) }
40
42
  end
41
43
 
42
- def run_all *paths
43
- batches = paths.collect do |path|
44
- parse path
45
- end
46
-
47
- tryouts_incr = 0
48
- skipped_tests = 0
49
- failed_tests = 0
50
- skipped_batches = 0
51
- failed_batches = 0
52
-
53
- msg format('Ruby %s @ %-60s', RUBY_VERSION, Time.now), $/
54
-
55
- if Tryouts.debug?
56
- Tryouts.debug "Found #{paths.size} files:"
57
- paths.each { |path| Tryouts.debug " #{path}" }
58
- Tryouts.debug
59
- end
60
-
61
- batches.each do |batch|
62
- path = batch.path.gsub(%r{#{Dir.pwd}/?}, '')
63
- divider = '-' * 70
64
- path_pretty = format('>>>>> %-20s %s', path, '').ljust(70, '<')
65
-
66
- msg $/
67
- vmsg Console.reverse(divider)
68
- vmsg Console.reverse(path_pretty)
69
- vmsg Console.reverse(divider)
70
- vmsg $/
71
-
72
- before_handler = proc do |tc|
73
- if Tryouts.noisy
74
- tc_title = tc.desc.to_s
75
- vmsg Console.underline(format('%-58s ', tc_title))
76
- vmsg tc.test.inspect, tc.exps.inspect
77
- end
78
- end
79
-
80
- batch.run(before_handler) do |tc|
81
- tryouts_incr += 1
82
- failed_tests += 1 if tc.failed?
83
- skipped_tests += 1 if tc.skipped?
84
- codelines = tc.testrunner_output.join($/)
85
- first_exp_line = tc.exps.first
86
-
87
- Tryouts.debug Console.color(:white, "tryouts_incr is now %d" % tryouts_incr)
88
-
89
- first_exp_line = tc.exps.first
90
- location = format('%s:%d', tc.exps.path, first_exp_line)
91
-
92
- expectation = Console.color(tc.color, codelines)
93
- summary = Console.color(tc.color, "%s @ %s" % [tc.adjective, location])
94
- vmsg ' %s' % expectation
95
- if tc.failed?
96
- msg Console.reverse(summary)
97
- else
98
- msg summary
99
- end
100
- vmsg
101
-
102
- # Output the buffered testcase_io to stdout
103
- # and then reset it for the next test case.
104
- unless Tryouts.fails && !tc.failed?
105
- $stdout.puts testcase_io.string unless Tryouts.quiet
106
- $stdout.puts tc.console_output.string if Tryouts.noisy
107
- end
108
-
109
- # Reset the testcase IO buffer
110
- testcase_io.truncate(0)
111
- end
112
-
113
- failed_tests += batch.failed
114
- if Tryouts.debug?
115
- msg "Batch failed_tests: #{batch.failed} (#{batch.failed?}) #{failed_tests}"
116
- end
117
- end
118
-
119
-
120
- # Create a line of separation before the result summary
121
- msg $INPUT_RECORD_SEPARATOR # newline
122
-
123
- if tryouts_incr
124
- suffix = "tryouts passed"
125
- if skipped_tests > 0
126
- suffix = "#{suffix} (#{skipped_tests} skipped)"
127
- end
128
-
129
- actual_test_size = tryouts_incr - skipped_tests
130
- if actual_test_size > 0
131
- success_count = tryouts_incr - failed_tests - skipped_tests
132
- total_count = tryouts_incr - skipped_tests
133
- msg cformat(success_count, total_count, suffix)
134
- if Tryouts.debug?
135
- msg "tryouts_incr: %d; failed: %d; skipped: %d" % [tryouts_incr, failed_tests, skipped_tests]
136
- end
137
- end
138
- end
139
-
140
- # In what circumstance is this ever true?
141
- #
142
- adjusted_batch_size = (batches.size - skipped_batches)
143
- if batches.size > 1 && adjusted_batch_size > 0
144
- suffix = 'batches passed'
145
- suffix << " (#{skipped_batches} skipped)" if skipped_batches > 0
146
- success_count = adjusted_batch_size - failed_batches
147
- total_count = adjusted_batch_size
148
- msg cformat(success_count, total_count, suffix)
149
- end
150
-
151
- # Print out the buffered result summary
152
- $stdout.puts testcase_io.string
153
-
154
- failed_tests # returns the number of failed tests (0 if all passed)
155
- end
156
-
157
- def cformat(lval, rval, suffix = nil)
158
- Console.bright '%d of %d %s' % [lval, rval, suffix]
159
- end
160
-
161
- def run(path)
162
- batch = parse path
163
- batch.run
164
- batch
165
- end
166
-
167
- def parse(path)
168
- # debug "Loading #{path}"
169
- lines = File.readlines path
170
- skip_ahead = 0
171
- batch = TestBatch.new path, lines
172
- lines.size.times do |idx|
173
- skip_ahead -= 1 and next if skip_ahead > 0
174
-
175
- line = lines[idx].chomp
176
- # debug('%-4d %s' % [idx, line])
177
- next unless expectation? line
178
-
179
- offset = 0
180
- exps = Section.new(path, idx + 1)
181
- exps << line.chomp
182
- while idx + offset < lines.size
183
- offset += 1
184
- this_line = lines[idx + offset]
185
- break if ignore?(this_line)
186
-
187
- if expectation?(this_line)
188
- exps << this_line.chomp
189
- skip_ahead += 1
190
- end
191
- exps.last += 1
192
- end
193
-
194
- offset = 0
195
- buffer = Section.new(path)
196
- desc = Section.new(path)
197
- test = Section.new(path, idx) # test start the line before the exp.
198
- while idx - offset >= 0
199
- offset += 1
200
- this_line = lines[idx - offset].chomp
201
- buffer.unshift this_line if ignore?(this_line)
202
- buffer.unshift this_line if comment?(this_line)
203
- if test?(this_line)
204
- test.unshift(*buffer) && buffer.clear
205
- test.unshift this_line
206
- end
207
- if test_begin?(this_line)
208
- while test_begin?(lines[idx - (offset + 1)].chomp)
209
- offset += 1
210
- buffer.unshift lines[idx - offset].chomp
211
- end
212
- end
213
- next unless test_begin?(this_line) || idx - offset == 0 || expectation?(this_line)
214
-
215
- adjust = expectation?(this_line) ? 2 : 1
216
- test.first = idx - offset + buffer.size + adjust
217
- desc.unshift(*buffer)
218
- desc.last = test.first - 1
219
- desc.first = desc.last - desc.size + 1
220
- # remove empty lines between the description
221
- # and the previous expectation
222
- while !desc.empty? && desc[0].empty?
223
- desc.shift
224
- desc.first += 1
225
- end
226
- break
227
- end
228
-
229
- batch << TestCase.new(desc, test, exps)
230
- end
231
-
232
- batch
233
- end
234
-
235
- def print(str)
236
- return if Tryouts.quiet
237
-
238
- $stdout.print str
239
- $stdout.flush
240
- end
241
-
242
- def vmsg *msgs
243
- msg(*msgs) if Tryouts.noisy
244
- end
245
-
246
- def msg *msgs
247
- testcase_io.puts(*msgs) unless Tryouts.quiet
248
- end
249
-
250
- def info *msgs
251
- msgs.each do |line|
252
- $stdout.puts line
253
- end
254
- end
255
-
256
- def err *msgs
257
- msgs.each do |line|
258
- $stderr.puts Console.color :red, line
259
- end
260
- end
261
-
262
- def debug *msgs
263
- $stderr.puts(*msgs) if debug?
264
- end
265
-
266
- def eval(str, path, line)
267
- Kernel.eval str, @container.send(:binding), path, line
268
-
269
- rescue SyntaxError, LoadError => e
270
- Tryouts.err Console.color(:red, e.message),
271
- Console.color(:red, e.backtrace.first)
272
- nil
273
- end
274
-
275
- private
276
-
277
- def expectation?(str)
278
- !ignore?(str) && str.strip.match(/\A\#+\s*=>/)
279
- end
280
-
281
- def comment?(str)
282
- !str.strip.match(/^\#+/).nil? && !expectation?(str)
283
- end
284
-
285
- def test?(str)
286
- !ignore?(str) && !expectation?(str) && !comment?(str)
287
- end
288
-
289
- def ignore?(str)
290
- str.to_s.strip.chomp.empty?
291
- end
44
+ def trace(msg, indent: 0)
45
+ return unless debug?
292
46
 
293
- def test_begin?(str)
294
- !str.strip.match(/\#+\s*TEST/i).nil? ||
295
- !str.strip.match(/\A\#\#+[\s\w]+/i).nil?
47
+ prefix = (' ' * indent) + Console.color(:dim, 'TRACE')
48
+ warn "#{prefix} #{msg}"
296
49
  end
297
50
  end
298
51
 
metadata CHANGED
@@ -1,29 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tryouts
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 3.0.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-07-20 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: sysinfo
13
+ name: minitest
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '5.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '5.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
15
28
  requirement: !ruby/object:Gem::Requirement
16
29
  requirements:
17
30
  - - "~>"
18
31
  - !ruby/object:Gem::Version
19
- version: '0.10'
32
+ version: '3.0'
20
33
  type: :runtime
21
34
  prerelease: false
22
35
  version_requirements: !ruby/object:Gem::Requirement
23
36
  requirements:
24
37
  - - "~>"
25
38
  - !ruby/object:Gem::Version
26
- version: '0.10'
39
+ version: '3.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: sysinfo
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0.8'
47
+ - - "<"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0.8'
57
+ - - "<"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.0'
27
60
  description: A simple test framework for Ruby code that uses introspection to allow
28
61
  defining checks in comments.
29
62
  email: gems@solutious.com
@@ -35,20 +68,35 @@ extra_rdoc_files: []
35
68
  files:
36
69
  - LICENSE.txt
37
70
  - README.md
38
- - VERSION.yml
39
71
  - exe/try
40
72
  - exe/tryouts
41
73
  - lib/tryouts.rb
74
+ - lib/tryouts/cli.rb
75
+ - lib/tryouts/cli/formatters.rb
76
+ - lib/tryouts/cli/formatters/base.rb
77
+ - lib/tryouts/cli/formatters/compact.rb
78
+ - lib/tryouts/cli/formatters/factory.rb
79
+ - lib/tryouts/cli/formatters/output_manager.rb
80
+ - lib/tryouts/cli/formatters/quiet.rb
81
+ - lib/tryouts/cli/formatters/verbose.rb
82
+ - lib/tryouts/cli/modes/generate.rb
83
+ - lib/tryouts/cli/modes/inspect.rb
84
+ - lib/tryouts/cli/opts.rb
42
85
  - lib/tryouts/console.rb
43
- - lib/tryouts/section.rb
86
+ - lib/tryouts/file_processor.rb
87
+ - lib/tryouts/prism_parser.rb
88
+ - lib/tryouts/test_executor.rb
89
+ - lib/tryouts/test_runner.rb
44
90
  - lib/tryouts/testbatch.rb
45
91
  - lib/tryouts/testcase.rb
92
+ - lib/tryouts/translators/minitest_translator.rb
93
+ - lib/tryouts/translators/rspec_translator.rb
46
94
  - lib/tryouts/version.rb
47
95
  homepage: https://github.com/delano/tryouts
48
96
  licenses:
49
97
  - MIT
50
- metadata: {}
51
- post_install_message:
98
+ metadata:
99
+ rubygems_mfa_required: 'true'
52
100
  rdoc_options: []
53
101
  require_paths:
54
102
  - lib
@@ -56,15 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
104
  requirements:
57
105
  - - ">="
58
106
  - !ruby/object:Gem::Version
59
- version: 2.7.8
107
+ version: '3.4'
60
108
  required_rubygems_version: !ruby/object:Gem::Requirement
61
109
  requirements:
62
110
  - - ">="
63
111
  - !ruby/object:Gem::Version
64
112
  version: '0'
65
113
  requirements: []
66
- rubygems_version: 3.5.15
67
- signing_key:
114
+ rubygems_version: 3.6.7
68
115
  specification_version: 4
69
116
  summary: Ruby tests that read like documentation.
70
117
  test_files: []
data/VERSION.yml DELETED
@@ -1,4 +0,0 @@
1
- ---
2
- :MAJOR: 2
3
- :MINOR: 4
4
- :PATCH: 1
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- class Tryouts
4
- class Section < Array
5
- attr_accessor :path, :first, :last
6
-
7
- def initialize(path, start = 0)
8
- @path = path
9
- @first = start
10
- @last = start
11
- end
12
-
13
- def range
14
- @first..@last
15
- end
16
-
17
- def inspect
18
- range.to_a.zip(self).collect do |line|
19
- "%-4d %s\n" % line
20
- end.join
21
- end
22
-
23
- def to_s
24
- join($/)
25
- end
26
- end
27
- end