lab42_speculate 0.0.3
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/speculate +6 -0
- data/lib/speculate.rb +57 -0
- data/lib/speculate/args.rb +76 -0
- data/lib/speculate/dirs.rb +36 -0
- data/lib/speculate/generator.rb +29 -0
- data/lib/speculate/parser.rb +61 -0
- data/lib/speculate/spec_pair.rb +26 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b3427d6436310d4254e6b44eab9bf4bb987e7baf944c30844e6c5ba3d321f4f5
|
4
|
+
data.tar.gz: b470196d41cc3f1ce0a842c4432ab413f961db0c2f947597beb2517cb179ee54
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 151f993021994a91eb565ea2bedf2d56ccded40629fbb1211ab2ac69b522a5dff72255f1a8aa6a1ce9049abb3a63c5ccb457c728f8a89022d55fa8e86d9e09f5
|
7
|
+
data.tar.gz: f0c0c60a70a94de2ae905b638192b10a04bde6f5890acd4303fff66a3c50f3f0bceecabf129be71ae58bd3a6dc0eccfe570b3e0e953a02a25f71182003deacc4
|
data/bin/speculate
ADDED
data/lib/speculate.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Speculate extend self
|
2
|
+
require_relative 'speculate/args'
|
3
|
+
require_relative 'speculate/dirs'
|
4
|
+
require_relative 'speculate/generator'
|
5
|
+
|
6
|
+
BASE_DIR = 'spec/speculations'
|
7
|
+
|
8
|
+
attr_reader :args
|
9
|
+
|
10
|
+
def base_dir
|
11
|
+
@__base_dir__ ||= args.fetch!(:dest, BASE_DIR)
|
12
|
+
end
|
13
|
+
|
14
|
+
def speculations
|
15
|
+
@__speculations__ ||= _speculations
|
16
|
+
end
|
17
|
+
|
18
|
+
def speculations_dir
|
19
|
+
@__speculations_dir__ ||= args.fetch!(:dir, 'spec/speculations')
|
20
|
+
end
|
21
|
+
|
22
|
+
def speculations_glob
|
23
|
+
@__speculations_glob__ ||= args.fetch!(:glob, '**/*.md')
|
24
|
+
end
|
25
|
+
|
26
|
+
def run args
|
27
|
+
@args = Args.new args
|
28
|
+
if @args.flag!(:force)
|
29
|
+
_force speculations
|
30
|
+
end
|
31
|
+
speculations
|
32
|
+
.filter(&:outdated?)
|
33
|
+
.each(&Generator.method(:generate))
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def _force speculations
|
40
|
+
speculations.each do |speculation|
|
41
|
+
puts "touching #{speculation.speculation.path} as :force was passed in"
|
42
|
+
FileUtils.touch speculation.speculation
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def _speculations
|
47
|
+
speculations = Dir.glob(File.join(speculations_dir, speculations_glob))
|
48
|
+
if speculations.any?
|
49
|
+
puts "Speculations found: #{speculations}"
|
50
|
+
else
|
51
|
+
puts "No Speculations found!!!! :O :O :O"
|
52
|
+
return []
|
53
|
+
end
|
54
|
+
speculations.map{ |speculation| Dirs.speculation_to_dir(speculation, base_dir) }
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Speculate::Args
|
2
|
+
|
3
|
+
FLAG_RGX = %r{\A:}
|
4
|
+
KEYWORD_RGX = %r{:\z}
|
5
|
+
|
6
|
+
attr_reader :args
|
7
|
+
|
8
|
+
def empty?; args.empty? end
|
9
|
+
|
10
|
+
def fetch symbol, default=nil, &block
|
11
|
+
index = args.index("#{symbol}:")
|
12
|
+
return default unless index
|
13
|
+
args.fetch( index.succ, default ).tap do |value|
|
14
|
+
return block.(value) if block
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def fetch! symbol, default=nil, &block
|
19
|
+
index = args.index("#{symbol}:")
|
20
|
+
return default unless index
|
21
|
+
args.delete_at index
|
22
|
+
args.fetch( index ) {
|
23
|
+
return default
|
24
|
+
}.tap{ |value|
|
25
|
+
args.delete_at index
|
26
|
+
return block.(value) if block
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def flag? value
|
31
|
+
args.index ":#{value}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def flag! value
|
35
|
+
flag?(value).tap do |idx|
|
36
|
+
return unless idx
|
37
|
+
args.delete_at(idx)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def positionals
|
42
|
+
args.inject [false, []] do |(last_was_keyword, result), ele|
|
43
|
+
if last_was_keyword
|
44
|
+
[false, result]
|
45
|
+
else
|
46
|
+
case ele
|
47
|
+
when KEYWORD_RGX
|
48
|
+
[true, result]
|
49
|
+
when FLAG_RGX
|
50
|
+
[false, result]
|
51
|
+
else
|
52
|
+
[false, result << ele]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end.last
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_a
|
59
|
+
args.dup
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def initialize with
|
66
|
+
@args = with.dup
|
67
|
+
end
|
68
|
+
|
69
|
+
def _flag arg
|
70
|
+
FLAG_RGX.match? arg
|
71
|
+
end
|
72
|
+
|
73
|
+
def _keyword? arg
|
74
|
+
KEYWORD_RGX.match arg
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require_relative './spec_pair'
|
4
|
+
module Speculate::Dirs extend self
|
5
|
+
Error = Class.new RuntimeError
|
6
|
+
|
7
|
+
DEFAULT_BASENAME = "__default"
|
8
|
+
SPECULATION_RGX = %r{\ASPECULATE[-_]*(.*)\.md\z}
|
9
|
+
|
10
|
+
attr_reader :base_dir
|
11
|
+
|
12
|
+
def speculation_to_dir speculation_file, base_dir
|
13
|
+
@base_dir = base_dir
|
14
|
+
|
15
|
+
_assure_dir
|
16
|
+
speculation_file, spec_path = _assure_speculation speculation_file
|
17
|
+
|
18
|
+
Speculate::SpecPair.new speculation_file, spec_path
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def _assure_dir
|
25
|
+
FileUtils.mkdir_p(base_dir)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _assure_speculation speculation_file
|
29
|
+
|
30
|
+
basename = File.basename(speculation_file).sub(%r{\..*\z}i, "").downcase
|
31
|
+
specname = File.join(base_dir, "#{basename}_spec.rb")
|
32
|
+
|
33
|
+
[speculation_file, specname]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative './parser.rb'
|
2
|
+
module Speculate::Generator extend self
|
3
|
+
Error = Class.new RuntimeError
|
4
|
+
|
5
|
+
def generate pair
|
6
|
+
unless pair.outdated?
|
7
|
+
raise Error,
|
8
|
+
"Must not call generate for #{pair.speculation.path} -> #{pair.spec.path}, because it is not outdated"
|
9
|
+
end
|
10
|
+
puts "Generating: #{pair.speculation.path} -> #{pair.spec.path}"
|
11
|
+
text = Speculate::Parser.new(pair.speculation).parse
|
12
|
+
File.open(pair.spec.path, "w"){ |f|
|
13
|
+
f.puts _header(pair.speculation.path)
|
14
|
+
f.puts text
|
15
|
+
f.puts _footer
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def _footer
|
23
|
+
%{end}
|
24
|
+
end
|
25
|
+
|
26
|
+
def _header name
|
27
|
+
%{RSpec.describe #{name.inspect} do}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Speculate::Parser
|
2
|
+
Error = Class.new RuntimeError
|
3
|
+
|
4
|
+
SPECULATION_END_RGX = %r{\A\s{0,3}(?:```)|(?:~~~)\s*\z}
|
5
|
+
SPECULATION_START_RGX = %r{\A\s{0,3}(?:```)|(?:~~~)(\w+)speculate}
|
6
|
+
|
7
|
+
attr_reader :state, :stream
|
8
|
+
|
9
|
+
def parse
|
10
|
+
@state = :outer
|
11
|
+
_parse
|
12
|
+
lines
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def initialize speculation
|
19
|
+
@stream =
|
20
|
+
speculation
|
21
|
+
.each_line(chomp: true)
|
22
|
+
.lazy
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Memos
|
27
|
+
# =====
|
28
|
+
def lines
|
29
|
+
@__lines__ ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# Parser
|
34
|
+
# ======
|
35
|
+
def _parse
|
36
|
+
stream.each do |line|
|
37
|
+
case state
|
38
|
+
when :outer
|
39
|
+
_parse_outer line
|
40
|
+
when :inner
|
41
|
+
_parse_inner line
|
42
|
+
else
|
43
|
+
raise Error, "illegal state #{state}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def _parse_inner line
|
49
|
+
if SPECULATION_END_RGX =~ line
|
50
|
+
@state = :outer
|
51
|
+
else
|
52
|
+
lines << line
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def _parse_outer line
|
57
|
+
if SPECULATION_START_RGX =~ line
|
58
|
+
@state = :inner
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
class Speculate::SpecPair
|
3
|
+
|
4
|
+
attr_reader :spec, :speculation
|
5
|
+
|
6
|
+
def outdated?
|
7
|
+
speculation.mtime >= spec.mtime
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def initialize speculation_name, spec_path
|
14
|
+
@speculation = File.new speculation_name
|
15
|
+
|
16
|
+
FileUtils.touch(spec_path, mtime: speculation.mtime - 1) unless File.exists? spec_path
|
17
|
+
@spec = File.new spec_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def _spec_pair basename
|
21
|
+
specname = File.join(base_dir, "#{basename}_spec.rb")
|
22
|
+
FileUtils.touch(specname, mtime: speculation.mtime - 1) unless File.exists? specname
|
23
|
+
OpenStruct.new(speculation: speculation, spec: File.new(specname))
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lab42_speculate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Dober
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry-byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.7'
|
41
|
+
description: Extract RSpecs from Markdown
|
42
|
+
email: robert.dober@gmail.com
|
43
|
+
executables:
|
44
|
+
- speculate
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- bin/speculate
|
49
|
+
- lib/speculate.rb
|
50
|
+
- lib/speculate/args.rb
|
51
|
+
- lib/speculate/dirs.rb
|
52
|
+
- lib/speculate/generator.rb
|
53
|
+
- lib/speculate/parser.rb
|
54
|
+
- lib/speculate/spec_pair.rb
|
55
|
+
homepage: https://github.com/robertdober/speculate
|
56
|
+
licenses:
|
57
|
+
- Apache-2.0
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.7.0
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubygems_version: 3.1.2
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Extract RSpecs from Markdown
|
78
|
+
test_files: []
|