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.
@@ -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
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'futo-spec'
4
+ if ARGV.include? '--dry-run'
5
+ $dry_run = true
6
+ ARGV.delete('--dry-run')
7
+ end
8
+
9
+ fs = FutoSpec.new(ARGV[1])
10
+ fs.run($dry_run)
@@ -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,2 @@
1
+ $foo = 'bar'
2
+ BAZ = 'ish'
@@ -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
@@ -0,0 +1,4 @@
1
+ check should syntax
2
+ - author personally prefers should
3
+ - others erroneously prefer expect.to
4
+ -> should probably expect to handle both.
@@ -0,0 +1,3 @@
1
+ variable scoping
2
+ - local variable scoping / local to a block in a chizu step
3
+ - @ and $ already work
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: []