futo-spec 0.2.1
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 +7 -0
- data/bin/futo +10 -0
- data/lib/futo-spec.rb +301 -0
- data/lib/spec/_glue/chizu/self.chizu +39 -0
- data/lib/spec/_glue/initialize/basics.setup.rb +2 -0
- data/lib/spec/basics.futo +16 -0
- data/lib/spec/edge_cases.futo +17 -0
- data/lib/spec/rspec.futo +4 -0
- data/lib/spec/todos.futo +3 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cd4211c90f029d68c7e7b1647d8956f7a5ab650404e49b0353afbd174ac2e41a
|
4
|
+
data.tar.gz: f190309bd7c5651f34cb148b8f543df54fbcc24ab1c48bcf197934c0f5fbca58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8be475a8f8b8b1df8ccf73e34062cbaf471f5b82500f90289e01db8a6f6f96e87e1e591a772f150296936dcf34b0acd1ba48a29519a7b2c49a41118aaeb82569
|
7
|
+
data.tar.gz: 2fb890864d848a81f465d38be8f4a6ef0eb0f3bd6e837a7c703bf624ee50d01e57600f16e46fd2c7925d73dbf5785ec1eacc3d792fe1acdea4e2a86ef2597801
|
data/bin/futo
ADDED
data/lib/futo-spec.rb
ADDED
@@ -0,0 +1,301 @@
|
|
1
|
+
require 'paint/pa'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
require 'find'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
|
7
|
+
BULLET_POINTS_REGEX = /[\->]*/
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.expect_with :rspec do |c|
|
11
|
+
c.syntax = :should
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class FutoBullet
|
17
|
+
attr_accessor :label, :associated_commands
|
18
|
+
def initialize(h)
|
19
|
+
@label = h
|
20
|
+
@associated_commands = Array.new
|
21
|
+
end
|
22
|
+
def to_s; return @label; end
|
23
|
+
end
|
24
|
+
|
25
|
+
class FutoCase
|
26
|
+
attr_accessor :description, :bullet_points
|
27
|
+
def initialize(h, b_arr)
|
28
|
+
@description = h
|
29
|
+
@bullet_points = b_arr
|
30
|
+
end
|
31
|
+
def to_s; return @description; end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ChizuEntry
|
35
|
+
attr_accessor :kkey, :associated_commands
|
36
|
+
def initialize(h, c_arr)
|
37
|
+
@kkey = h
|
38
|
+
@associated_commands = c_arr
|
39
|
+
end
|
40
|
+
def to_s; return @kkey; end
|
41
|
+
end
|
42
|
+
|
43
|
+
class FutoSpec
|
44
|
+
include RSpec::Matchers
|
45
|
+
attr_accessor :cases, :chizu, :unmatched
|
46
|
+
|
47
|
+
def initialize(specified_file=nil)
|
48
|
+
@cases = Array.new
|
49
|
+
@chizu = Array.new
|
50
|
+
@unmatched = Array.new
|
51
|
+
|
52
|
+
test_case_lines = nil
|
53
|
+
unless specified_file
|
54
|
+
test_case_lines = discover_and_process_futo_files
|
55
|
+
else
|
56
|
+
test_case_lines = process_specific_file(specified_file)
|
57
|
+
end
|
58
|
+
|
59
|
+
look_for_envrb_and_parse
|
60
|
+
find_and_load_chizu_files
|
61
|
+
create_test_cases_and_load_bullet_points(test_case_lines)
|
62
|
+
load_commands_into_test_cases_from_chizu
|
63
|
+
end
|
64
|
+
|
65
|
+
def look_for_envrb_and_parse
|
66
|
+
if Dir.children("#{Dir.pwd}/futo-spec").include? '_glue'
|
67
|
+
if Dir.children("#{Dir.pwd}/futo-spec/_glue").include? 'env.rb'
|
68
|
+
puts 'found futo-spec/_glue/env.rb'
|
69
|
+
load 'futo-spec/_glue/env.rb'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def discover_and_process_futo_files
|
75
|
+
futo_files = []
|
76
|
+
test_case_lines = []
|
77
|
+
|
78
|
+
Find.find('./futo-spec/') do |ff|
|
79
|
+
if ff.end_with? '.futo' or ff.end_with? 'spec'
|
80
|
+
futo_files << ff
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
futo_files.each { |ff| test_case_lines += process_specific_file(ff) }
|
85
|
+
return test_case_lines
|
86
|
+
end
|
87
|
+
|
88
|
+
def specific_line_requested(desc)
|
89
|
+
spl = desc.split(':')
|
90
|
+
desc_file = spl.first
|
91
|
+
idx = spl.last.to_i - 1 # line numbers are 1-indexed
|
92
|
+
|
93
|
+
File.open(desc_file) do |file|
|
94
|
+
all_lines = file.readlines(chomp:true)
|
95
|
+
specified_line = all_lines[idx]
|
96
|
+
return specified_line
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def process_specific_file(spec)
|
101
|
+
if spec.include? ':'
|
102
|
+
return specific_line_requested(spec)
|
103
|
+
else
|
104
|
+
File.open(spec) do |file|
|
105
|
+
file_lines = file.readlines(chomp:true)
|
106
|
+
return file_lines
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_case_to_spec
|
112
|
+
@cases << FutoCase.new(@new_case_label, @new_case_bullets)
|
113
|
+
end
|
114
|
+
|
115
|
+
def begin_new_case
|
116
|
+
@new_case_label = ''
|
117
|
+
@new_case_bullets = Array.new
|
118
|
+
end
|
119
|
+
|
120
|
+
def new_bullet(line)
|
121
|
+
label = line.sub(BULLET_POINTS_REGEX, '').lstrip
|
122
|
+
#puts label
|
123
|
+
@new_case_bullets << FutoBullet.new(label)
|
124
|
+
end
|
125
|
+
|
126
|
+
def new_label(line)
|
127
|
+
@new_case_label = line
|
128
|
+
end
|
129
|
+
|
130
|
+
def is_newline?(line)
|
131
|
+
return line == ''
|
132
|
+
end
|
133
|
+
|
134
|
+
def is_initialize?(line)
|
135
|
+
return line.start_with?('** initialize with:') ||
|
136
|
+
line.start_with?('**')
|
137
|
+
end
|
138
|
+
|
139
|
+
def init_test(line)
|
140
|
+
prefix = line.split(':').last.lstrip
|
141
|
+
fn = "./initialize/#{prefix}.initialize.rb"
|
142
|
+
if File.exist?(fn)
|
143
|
+
load(fn)
|
144
|
+
else
|
145
|
+
pa "failed to find setup file #{fn} for line: #{line}", :red
|
146
|
+
end
|
147
|
+
puts
|
148
|
+
end
|
149
|
+
|
150
|
+
def is_bullet?(line)
|
151
|
+
return line.start_with?('-') || line.start_with?('>')
|
152
|
+
end
|
153
|
+
|
154
|
+
def create_test_cases_and_load_bullet_points(test_case_lines)
|
155
|
+
begin_new_case
|
156
|
+
|
157
|
+
test_case_lines.each do |line|
|
158
|
+
l0 = line.gsub('(DONE)','').gsub('(done)','')
|
159
|
+
ll = l0.lstrip.rstrip
|
160
|
+
if is_newline? ll
|
161
|
+
add_case_to_spec
|
162
|
+
begin_new_case
|
163
|
+
else
|
164
|
+
if is_initialize? ll
|
165
|
+
init_test(ll)
|
166
|
+
elsif is_bullet? ll
|
167
|
+
new_bullet(ll)
|
168
|
+
else
|
169
|
+
new_label(ll)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# catch anything left over
|
175
|
+
add_case_to_spec
|
176
|
+
end
|
177
|
+
|
178
|
+
def single_quoted_line?(line)
|
179
|
+
single = false
|
180
|
+
line.chars.each do |char|
|
181
|
+
if char == '"'
|
182
|
+
break
|
183
|
+
end
|
184
|
+
if char == "'"
|
185
|
+
single = true
|
186
|
+
break
|
187
|
+
end
|
188
|
+
end
|
189
|
+
return single
|
190
|
+
end
|
191
|
+
|
192
|
+
def find_and_load_chizu_files
|
193
|
+
chizu_files = []
|
194
|
+
|
195
|
+
Find.find('futo-spec/_glue/chizu/') do |ff|
|
196
|
+
chizu_files << ff if ff.end_with? 'chizu'
|
197
|
+
chizu_files << ff if ff.end_with? 'rb'
|
198
|
+
end
|
199
|
+
|
200
|
+
chizu_files.each {|ff| load_chizu ff}
|
201
|
+
end
|
202
|
+
|
203
|
+
def load_chizu(ff)
|
204
|
+
File.open(ff) do |file|
|
205
|
+
lines = file.readlines(chomp:true)
|
206
|
+
kkey = ''
|
207
|
+
commands = Array.new
|
208
|
+
lines.each do |ll|
|
209
|
+
using_single_quotes = single_quoted_line?(ll)
|
210
|
+
if ll.start_with? 'On'
|
211
|
+
if using_single_quotes
|
212
|
+
kkey = ll.split("'")[1]
|
213
|
+
else
|
214
|
+
kkey = ll.split('"')[1]
|
215
|
+
end
|
216
|
+
elsif ll.start_with? 'end'
|
217
|
+
@chizu << ChizuEntry.new(kkey, commands)
|
218
|
+
kkey = ''
|
219
|
+
commands = Array.new
|
220
|
+
elsif ll == "\n" || ll == ''
|
221
|
+
next
|
222
|
+
else
|
223
|
+
commands << ll.lstrip
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def is_todo?(chizu)
|
230
|
+
if chizu.associated_commands.include?('# TODO') ||
|
231
|
+
chizu.associated_commands.include?('#TODO') ||
|
232
|
+
chizu.associated_commands.include?('TODO')
|
233
|
+
return true
|
234
|
+
else
|
235
|
+
return false
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def load_commands_into_test_cases_from_chizu
|
240
|
+
@cases.each do |test_case|
|
241
|
+
test_case.bullet_points.each do |bullet|
|
242
|
+
matched = false
|
243
|
+
if @chizu.length == 0
|
244
|
+
# no chizus found, everything will be unmatched
|
245
|
+
@unmatched << bullet
|
246
|
+
else
|
247
|
+
@chizu.each do |chizu|
|
248
|
+
if is_todo? chizu
|
249
|
+
next
|
250
|
+
else
|
251
|
+
if bullet.label == chizu.kkey
|
252
|
+
matched = true
|
253
|
+
bullet.associated_commands = chizu.associated_commands
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
if ! matched
|
258
|
+
unless @unmatched.include? bullet
|
259
|
+
@unmatched << bullet
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def output_unmatched_commands
|
268
|
+
puts
|
269
|
+
pa "Missing chizu entries:", :yellow
|
270
|
+
puts
|
271
|
+
@unmatched.each do |un|
|
272
|
+
pa "On '#{un.label}' do", :yellow
|
273
|
+
pa ' # TODO', :yellow
|
274
|
+
pa 'end', :yellow
|
275
|
+
puts
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def run(dry_run=false)
|
280
|
+
exec_cases unless dry_run
|
281
|
+
output_unmatched_commands
|
282
|
+
end
|
283
|
+
|
284
|
+
def exec_cases
|
285
|
+
puts
|
286
|
+
@cases.each do |test_case|
|
287
|
+
test_case.bullet_points.each do |bullet|
|
288
|
+
#puts
|
289
|
+
pa "case: #{bullet.label}", :gray
|
290
|
+
bullet.associated_commands.each do |cmd|
|
291
|
+
pa cmd, :cyan if cmd != 'breakpoint'
|
292
|
+
begin
|
293
|
+
eval cmd
|
294
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
295
|
+
pa e, :red
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
On 'lines with bullets should map as a normal test case' do
|
2
|
+
puts "lines with bullets test case"
|
3
|
+
end
|
4
|
+
|
5
|
+
On 'lines without bullets should map as a test description' do
|
6
|
+
# TODO
|
7
|
+
end
|
8
|
+
|
9
|
+
On 'newlines \n should start a new case' do
|
10
|
+
# TODO
|
11
|
+
end
|
12
|
+
|
13
|
+
On 'when specific line requested with colon :, only specific line should run' do
|
14
|
+
# TODO
|
15
|
+
end
|
16
|
+
|
17
|
+
On 'if specific line is description not bullet point, all bullets in that case should run' do
|
18
|
+
# TODO
|
19
|
+
end
|
20
|
+
|
21
|
+
On 'what to do with long bullets or descriptions that have a <Cr for readability ?' do
|
22
|
+
# TODO
|
23
|
+
end
|
24
|
+
|
25
|
+
On 'unmatched description steps, should generate a sample chizu to copypaste' do
|
26
|
+
# TODO
|
27
|
+
end
|
28
|
+
|
29
|
+
On 'single quotes' do
|
30
|
+
# TODO
|
31
|
+
end
|
32
|
+
|
33
|
+
On 'double quotes' do
|
34
|
+
# TODO
|
35
|
+
end
|
36
|
+
|
37
|
+
On 'should be parsed as a test description *and* bullet' do
|
38
|
+
# TODO
|
39
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
basic mapping
|
2
|
+
** initialize with: basics **
|
3
|
+
- lines with bullets should map as a normal test case
|
4
|
+
- lines without bullets should map as a test description
|
5
|
+
- newlines \n should start a new case
|
6
|
+
|
7
|
+
specific line
|
8
|
+
- when specific line requested with colon :, only specific line should run
|
9
|
+
- if specific line is description not bullet point, all bullets in that case should run
|
10
|
+
|
11
|
+
wrapped / long lines
|
12
|
+
- what to do with long bullets or descriptions that have a <Cr> for readability ?
|
13
|
+
|
14
|
+
state
|
15
|
+
- lines starting with "** using setup:" load state for the whole file
|
16
|
+
- will need levels of scope for this
|
@@ -0,0 +1,17 @@
|
|
1
|
+
missing / unmatched steps
|
2
|
+
- unmatched description steps, should generate a sample chizu to copy-paste
|
3
|
+
|
4
|
+
single vs double quotes
|
5
|
+
- single quotes
|
6
|
+
- double quotes
|
7
|
+
|
8
|
+
test point with only one line, without a bullet -
|
9
|
+
|
10
|
+
desc file which starts with a blank line
|
11
|
+
|
12
|
+
single lines which start with a dash -
|
13
|
+
- should be parsed as a test description *and* bullet
|
14
|
+
|
15
|
+
unmatched should work properly
|
16
|
+
- matched should not appear in unmatched output
|
17
|
+
- see commit :2087519 for the fix; an indentation problem caused a bug
|
data/lib/spec/rspec.futo
ADDED
data/lib/spec/todos.futo
ADDED
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: futo-spec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Felipe Wolfe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-09-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: paint
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: apparition
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: selenium-webdriver
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webdrivers
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.4'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: capybara
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.3'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.9'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.9'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-expectations
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.9'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: byebug
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '11.1'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '11.1'
|
125
|
+
description: Write your test notes in bullet point format, then map to test engine
|
126
|
+
actions. Like Cucumber, but * - > instead of Gherkin.
|
127
|
+
email: sean@addlightness.tech
|
128
|
+
executables:
|
129
|
+
- futo
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- bin/futo
|
134
|
+
- lib/futo-spec.rb
|
135
|
+
- lib/spec/_glue/chizu/self.chizu
|
136
|
+
- lib/spec/_glue/initialize/basics.setup.rb
|
137
|
+
- lib/spec/basics.futo
|
138
|
+
- lib/spec/edge_cases.futo
|
139
|
+
- lib/spec/rspec.futo
|
140
|
+
- lib/spec/todos.futo
|
141
|
+
homepage: https://rubygems.org/gems/futo-spec
|
142
|
+
licenses:
|
143
|
+
- MIT
|
144
|
+
metadata: {}
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
requirements: []
|
160
|
+
rubygems_version: 3.0.6
|
161
|
+
signing_key:
|
162
|
+
specification_version: 4
|
163
|
+
summary: Test engine using bullet points. Like you're writing on an envelope.
|
164
|
+
test_files: []
|