futo-spec 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []