speculate_about 0.3.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d53e888a2cad71c7c20205f0f34d7ededa3df3feceef7d567f051d362a36ccb8
4
- data.tar.gz: ee00700ca0a19000b8098cb3022b462da0537477d58ee912f250aba6b02e3e7c
3
+ metadata.gz: 50dd660d1e2e984b66f854df6f71e1f280ddef2e162d2848a3cf363ffe5751a4
4
+ data.tar.gz: 56ed0de10d7ee9751ae86deb247e7f8ad8d6b90f3a2e71623d83b0d169f18f59
5
5
  SHA512:
6
- metadata.gz: 3ced515885a50ff873cc4b471fe03eab69dc3e7c4f409e4e5ff392a91bfd94a08946aae7eb866607b27ecad62104beee68d8a52230fa2e216e1a544800a4ef0e
7
- data.tar.gz: 792619744dab6387ad2e70c7fa53eb49c3b8b9f26470a5de7c92477c3cc274075d7cff720b5fb8dc0a87bf71d2af016517e72449d56298824d3f865253b64192
6
+ metadata.gz: cd78c231bd7ab5eb1146c8d1f2fb3b19bea52951c30001d373981b748a77404bd5a5b87477bef989fa9707ff1049d9d7d6a91e2c3a0fa1cdc4533351c2a214bc
7
+ data.tar.gz: dbb334195b9354655edc06a11e52a0e77bee6be0961cc545fafc19ca6f2e0de5ba2c7c818ccde14bbf0fc2b2ba14b42f10fa02b114eb3f39b679763ea8427e2e
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/speculations/cli'
3
+
4
+ Speculations::CLI.run(ARGV)
@@ -1,34 +1,15 @@
1
1
  require 'rspec'
2
-
3
- require 'speculations/parser'
4
-
2
+ require_relative 'speculations/parser'
5
3
  module SpeculateAbout
6
- def speculate_about file, alternate_syntax: false
7
- paths = _find_files(file, File.dirname( caller.first ))
8
- raise ArgumentError, "no files found for pattern #{file}" if paths.empty?
9
- paths.each do |path|
10
- code = _compile path, _readable(path), alternate_syntax: alternate_syntax
11
- ENV["SPECULATE_ABOUT_DEBUG"] ? _show(code, path) : instance_eval(code, path)
12
- end
13
- end
14
4
 
5
+ def speculate_about(infile)
6
+ raise ArgumentError, "#{infile} not found" unless File.readable? infile
7
+ ast = Speculations::Parser.new.parse_from_file(infile)
8
+ code = ast.to_code.join("\n")
9
+ ENV["SPECULATE_ABOUT_DEBUG"] ? _show(code, infile) : instance_eval(code, infile)
10
+ end
15
11
 
16
12
  private
17
-
18
- def _compile path, file, alternate_syntax: false
19
- ast = Speculations::Parser.new.parse_from_file(path, file, alternate_syntax: alternate_syntax)
20
- ast.to_code
21
- end
22
- def _readable(path)
23
- d = File.dirname(path)
24
- File.join(File.basename(d), File.basename(path))
25
- end
26
- def _find_files file, local_path
27
- [Dir.pwd, local_path]
28
- .flat_map do |dir|
29
- Dir.glob(File.join(dir, file))
30
- end
31
- end
32
13
  def _show(code, path)
33
14
  message = "Generated code for #{path}"
34
15
  _underline(message)
@@ -38,6 +19,7 @@ module SpeculateAbout
38
19
  puts message
39
20
  puts message.gsub(/./, ul)
40
21
  end
22
+
41
23
  end
42
24
 
43
25
  RSpec.configure do |conf|
@@ -1,2 +1,29 @@
1
- module Speculations
1
+ require 'fileutils'
2
+ require_relative 'speculations/parser'
3
+ module Speculations extend self
4
+
5
+ def compile(infile, outfile=nil)
6
+ raise ArgumentError, "#{infile} not found" unless File.readable? infile
7
+ outfile ||= _speculation_path(infile)
8
+ if _out_of_date?(outfile, infile)
9
+ ast = Speculations::Parser.new.parse_from_file(infile)
10
+ File.write(outfile, ast.to_code.join("\n"))
11
+ end
12
+ outfile
13
+ end
14
+
15
+ private
16
+
17
+ def _out_of_date?(outf, inf)
18
+ return true unless File.exists? outf
19
+ return File.lstat(outf).mtime <= File.lstat(inf).mtime
20
+ end
21
+
22
+ def _speculation_path(file)
23
+ dir = File.dirname(file)
24
+ dest_dir = File.join("spec", "speculations", dir)
25
+ FileUtils.mkdir_p(dest_dir) unless File.directory?(dest_dir)
26
+ rspec = File.basename(file, ".md")
27
+ File.join(dest_dir, "#{rspec}_spec.rb")
28
+ end
2
29
  end
@@ -0,0 +1,49 @@
1
+
2
+ module Speculations
3
+ module CLI extend self
4
+ def run args
5
+ loop do
6
+ case args.first
7
+ when "-h", "--help"
8
+ _usage
9
+ when "-v", "--version"
10
+ _version
11
+ else
12
+ return _compile_and_maybe_run args
13
+ end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def _compile_and_maybe_run args
20
+ require_relative "../speculations"
21
+ args = Dir.glob(["*.md", "speculations/**/*.md"]) if args.empty?
22
+ args.each do |input_file|
23
+ Speculations.compile(input_file)
24
+ end
25
+ end
26
+
27
+ def _usage
28
+ puts <<-EOF
29
+ usage:
30
+ #{$0} [options] [filenames]
31
+
32
+ options:
33
+ -h | --help display this exit with -1
34
+ -v | --version display version of the speculate_about gem exit with -2
35
+
36
+ filenames (default to all markdown files in the project directory and its speculations subdirectories)
37
+
38
+ recreate outdated speculations in `spec/speculations/`
39
+ EOF
40
+ exit -1
41
+ end
42
+
43
+ def _version
44
+ require_relative 'version'
45
+ puts VERSION
46
+ exit -2
47
+ end
48
+ end
49
+ end
@@ -1,41 +1,39 @@
1
- require_relative '../speculations'
2
- class Speculations::Parser
3
- require_relative './parser/context'
4
- require_relative './parser/state'
1
+ module Speculations
2
+ class Parser
3
+ require_relative './parser/context'
4
+ require_relative './parser/state'
5
5
 
6
- attr_reader :alternate_syntax, :filename, :input, :orig_filename, :root, :state
7
6
 
8
- def self.parsers
9
- @__parsers__ ||= {
10
- bef: State::Bef,
11
- exa: State::Exa,
12
- inc: State::Inc,
13
- out: State::Out
14
- }
15
- end
7
+ def self.parsers
8
+ @__parsers__ ||= {
9
+ candidate: State::Candidate,
10
+ in: State::In,
11
+ out: State::Out
12
+ }
13
+ end
16
14
 
17
- def parse_from_file file, orig_filename = nil, alternate_syntax: false
18
- @alternate_syntax = alternate_syntax
19
- @filename = file
20
- @orig_filename = orig_filename || file
21
- @input = File
22
- .new(file)
23
- .each_line(chomp: true)
24
- .lazy
25
- parse!
26
- end
15
+ def parse_from_file file
16
+ @filename = file
17
+ @input = File
18
+ .new(file)
19
+ .each_line(chomp: true)
20
+ .lazy
21
+ parse!
22
+ end
27
23
 
28
- private
24
+ private
29
25
 
30
- def initialize
31
- @state = :out
32
- end
26
+ def initialize
27
+ @state = :out
28
+ end
33
29
 
34
- def parse!
35
- root = node = Context.new(alternate_syntax: alternate_syntax, name: "Speculations from #{@filename}", lnb: 0, filename: @filename, orig_filename: orig_filename, parent: nil)
36
- input.each_with_index do |line, lnb|
37
- @state, node = self.class.parsers.fetch(@state).parse(line, lnb.succ, node)
30
+ def parse!
31
+ root = node = Context.new(filename: @filename)
32
+ ctxt = nil
33
+ @input.each_with_index do |line, lnb|
34
+ @state, node, ctxt = self.class.parsers.fetch(@state).parse(line, lnb.succ, node, ctxt)
35
+ end
36
+ root
38
37
  end
39
- root
40
38
  end
41
39
  end
@@ -1,91 +1,129 @@
1
- class Speculations::Parser::Context
2
- require_relative './context/include'
3
- require_relative './context/example'
4
- require_relative './context/setup'
5
-
6
- attr_reader :alternate_syntax, :filename, :level, :lnb, :name, :orig_filename, :parent, :potential_name, :setup
7
-
8
- def add_child(name:, lnb:)
9
- raise "Illegal nesting" if parent
10
- children << self.class.new(alternate_syntax: alternate_syntax, name: name, lnb: lnb, parent: self)
11
- children.last
12
- end
13
-
14
- def add_example(lnb:, line:)
15
- examples << Example.new(lnb: lnb, parent: self, line: line, name: potential_name)
16
- @potential_name = nil
17
- examples.last
18
- end
19
-
20
- def add_include(lnb:)
21
- includes << Include.new(lnb: lnb, parent: self)
22
- includes.last
23
- end
24
-
25
- def children
26
- @__children__ ||= []
27
- end
28
-
29
- def examples
30
- @__examples__ ||= []
31
- end
32
-
33
- def includes
34
- @__includes__ ||= []
35
- end
36
-
37
- def map_lines(*lines, indent: 0)
38
- prefix = " " * (level + indent)
39
- lines.flatten.map{ |line| "#{prefix}#{line.strip}" }.join("\n")
40
- end
41
-
42
- def set_name(potential_name)
43
- @potential_name = potential_name
44
- end
45
-
46
- def set_setup(lnb:)
47
- @setup = Setup.new(lnb: lnb, parent: self)
48
- end
49
-
50
- def to_code
51
- [
52
- _header,
53
- includes.map(&:to_code),
54
- setup&.to_code,
55
- examples.map(&:to_code),
56
- children.map(&:to_code),
57
- _footer
58
- ].flatten.compact.join("\n")
59
- end
60
-
61
- private
62
-
63
- def initialize(alternate_syntax: false, lnb:, name:, filename: nil, orig_filename: nil, parent: nil)
64
- _init_from_parent filename, orig_filename, parent
65
- @alternate_syntax = alternate_syntax
66
- @level = parent ? parent.level.succ : 1
67
- @lnb = lnb
68
- @setup = nil
69
- @name = name
70
- @parent = parent
71
- end
72
-
73
- def _header
74
- map_lines(%{context "#{name}" do}, indent: -1)
1
+ module Speculations
2
+ class Parser
3
+ class Context
4
+ require_relative './context/include'
5
+ require_relative './context/example'
6
+
7
+ DISCLAIMER = <<-EOD
8
+ # DO NOT EDIT!!!
9
+ # This file was generated from FILENAME with the speculate_about gem, if you modify this file
10
+ # one of two bad things will happen
11
+ # - your documentation specs are not correct
12
+ # - your modifications will be overwritten by the speculate rake task
13
+ # YOU HAVE BEEN WARNED
14
+ EOD
15
+
16
+ attr_reader :filename, :level, :lnb, :title, :parent, :root, :tree_level
17
+
18
+ def new_context(title:, lnb:, level: )
19
+ new_child = self.class.new(title: title, lnb: lnb, parent: self, level: level)
20
+ _realign_levels(new_child)
21
+ end
22
+
23
+ def new_example(lnb:, title:)
24
+ examples << Example.new(lnb: lnb, parent: self, title: title)
25
+ examples.last
26
+ end
27
+
28
+ def new_include(lnb:)
29
+ includes << Include.new(lnb: lnb, parent: self)
30
+ includes.last
31
+ end
32
+
33
+ def parent_of_level needed_min_level
34
+ # I would love to write
35
+ # self.enum_by(:parent).find{ |ctxt| ctxt.level <= needed_min_level }
36
+ current = self
37
+ while current.level > needed_min_level
38
+ current = current.parent
39
+ end
40
+ current
41
+ end
42
+
43
+ def children
44
+ @__children__ ||= []
45
+ end
46
+
47
+ def examples
48
+ @__examples__ ||= []
49
+ end
50
+
51
+ def includes
52
+ @__includes__ ||= []
53
+ end
54
+
55
+ def map_lines(*lines, indent: 0)
56
+ prefix = " " * (tree_level + indent).succ
57
+ lines.flatten.map{ |line| "#{prefix}#{line.strip}" }
58
+ end
59
+
60
+ def to_code
61
+ [
62
+ _header,
63
+ includes.map(&:to_code),
64
+ examples.map(&:to_code),
65
+ children.map(&:to_code),
66
+ _footer
67
+ ].flatten.compact
68
+ end
69
+
70
+ def with_new_parent new_parent
71
+ @parent = new_parent
72
+ @tree_level += 1
73
+ self
74
+ end
75
+
76
+
77
+ private
78
+
79
+ def initialize(lnb: 0, title: nil, filename: nil, parent: nil, level: 0)
80
+ @filename = filename
81
+ @level = level
82
+ @lnb = lnb
83
+ @title = title
84
+ @parent = parent
85
+ if parent
86
+ _init_from_parent
87
+ else
88
+ @root = self
89
+ @tree_level = 0
90
+ end
91
+ end
92
+
93
+ def _header
94
+ if parent
95
+ map_lines(%{# #{filename}:#{lnb}}, %{context "#{title}" do}, indent: -1)
96
+ else
97
+ _root_header
98
+ end
99
+ end
100
+
101
+ def _root_header
102
+ map_lines(DISCLAIMER.gsub("FILENAME", filename.inspect).split("\n"), %{RSpec.describe #{filename.inspect} do}, indent: -1)
103
+ end
104
+
105
+ def _init_from_parent
106
+ @root = parent.root
107
+ @filename = parent.filename
108
+ @tree_level = parent.tree_level.succ
109
+ end
110
+
111
+ def _footer
112
+ map_lines("end", indent: -1)
113
+ end
114
+
115
+ def _realign_levels new_parent
116
+ if children.empty? || children.first.level == new_parent.level
117
+ children << new_parent
118
+ return new_parent
119
+ end
120
+ children.each do |child|
121
+ new_parent.children << child.with_new_parent(new_parent)
122
+ end
123
+ @__children__ = [new_parent]
124
+ new_parent
125
+ end
126
+
127
+ end
75
128
  end
76
-
77
- def _init_from_parent filename, orig_filename, parent
78
- _set_filename filename, orig_filename, parent
79
- @orig_filename = parent ? parent.orig_filename : orig_filename
80
- end
81
-
82
- def _set_filename filename, orig_filename, parent
83
- @filename = parent ? parent.filename : filename
84
- raise ArgumentError, "no filename given in root context" unless @filename
85
- end
86
-
87
- def _footer
88
- map_lines("end", indent: -1)
89
- end
90
-
91
129
  end
@@ -1,8 +1,7 @@
1
1
  class Speculations::Parser::Context::Example
2
2
 
3
- attr_reader :lnb, :name, :parent
3
+ attr_reader :lnb, :title, :parent
4
4
 
5
- NAMED_EXAMPLE = %r{\A[`~]{3,}ruby\s+:example\s+(.*)}
6
5
 
7
6
  def add_line line
8
7
  lines << line
@@ -15,34 +14,24 @@ class Speculations::Parser::Context::Example
15
14
 
16
15
  def to_code
17
16
  parent.map_lines(_example_head) +
18
- "\n" +
19
17
  parent.map_lines(lines, indent: 1) +
20
- "\n" +
21
18
  parent.map_lines("end")
22
19
  end
23
20
 
24
21
 
25
22
  private
26
23
 
27
- def initialize(lnb:, line:, parent:, name: nil)
24
+ def initialize(lnb:, parent:, title:)
28
25
  @lnb = lnb
29
26
  @parent = parent
30
- @name = _compute_name(lnb: lnb, line: line, parent: parent, name: name)
27
+ @title = _compute_title(title)
31
28
  end
32
29
 
33
- def _compute_name(lnb:, parent:, line:, name:)
34
- _, name1 = NAMED_EXAMPLE.match(line).to_a
35
-
36
- if name1&.empty? == false # SIC
37
- "#{name1} (#{parent.orig_filename}:#{lnb.succ})"
38
- elsif name
39
- "#{name} (#{parent.orig_filename}:#{lnb.succ})"
40
- else
41
- "Example from #{parent.orig_filename}:#{lnb.succ}"
42
- end
30
+ def _compute_title(title)
31
+ "#{title} (#{parent.root.filename}:#{lnb})"
43
32
  end
44
33
 
45
34
  def _example_head
46
- %{it "#{name}" do}
35
+ %{it "#{title}" do}
47
36
  end
48
37
  end
@@ -12,7 +12,7 @@ class Speculations::Parser::Context::Include
12
12
  end
13
13
 
14
14
  def to_code
15
- parent.map_lines(lines)
15
+ parent.map_lines("# #{parent.filename}:#{lnb}", lines)
16
16
  end
17
17
 
18
18
  private
@@ -1,49 +1,8 @@
1
1
  module Speculations::Parser::State extend self
2
- require_relative './state/bef'
3
- require_relative './state/exa'
4
- require_relative './state/inc'
2
+ require_relative './state/candidate'
3
+ require_relative './state/in'
5
4
  require_relative './state/out'
5
+ require_relative './state/triggers'
6
6
 
7
- BEFORE_RGX = %r[\A\s{0,3}```.*\s:before]
8
- CONTEXT_RGX = %r[\A\s{0,3}\#{1,7}\s+Context\s+(.*)]
9
- EOBLOCK_RGX = %r[\A\s{0,3}```\s*\z]
10
- EXAMPLE_RGX = %r[\A\s{0,3}```.*\s:example]
11
- INCLUDE_RGX = %r[\A\s{0,3}```.*\s:include]
12
- NAME_RGX = %r[\A\s{0,3}Example:?\s+(.*)]i
13
- RUBY_RGX = %r[\A\s{0,3}```ruby]
14
- WS_RGX = %r[\A\s*\z]
15
-
16
- def before_match line
17
- BEFORE_RGX =~ line
18
- end
19
-
20
- def context_match line
21
- if match = CONTEXT_RGX.match(line)
22
- match.captures.first
23
- end
24
- end
25
-
26
- def eoblock_match line
27
- EOBLOCK_RGX =~ line
28
- end
29
-
30
- def example_match line
31
- EXAMPLE_RGX =~ line
32
- end
33
-
34
- def include_match line
35
- INCLUDE_RGX =~ line
36
- end
37
-
38
- def potential_name line
39
- NAME_RGX.match(line)
40
- end
41
-
42
- def ruby_match line
43
- RUBY_RGX =~ line
44
- end
45
-
46
- def ws_match line
47
- WS_RGX =~ line
48
- end
7
+ extend Triggers
49
8
  end
@@ -0,0 +1,32 @@
1
+ module Speculations
2
+ class Parser
3
+ module State
4
+ module Candidate extend self
5
+ def parse line, lnb, node, ctxt
6
+ case
7
+ when State.blank_line(line)
8
+ [:candidate, node, ctxt]
9
+ when match = State.context_match(line)
10
+ level = match[1].size
11
+ new_parent = node.parent_of_level(level.pred)
12
+ node = new_parent.new_context(title: match[2], lnb: lnb, level: level)
13
+ [:out, node]
14
+ when match = State.maybe_example(line)
15
+ [:candidate, node, match[:title]]
16
+ when match = State.maybe_include(line)
17
+ [:candidate, node, :inc]
18
+ when match = State.ruby_code_block(line)
19
+ if ctxt == :inc
20
+ node = node.new_include(lnb: lnb)
21
+ else
22
+ node = node.new_example(title: ctxt, lnb: lnb)
23
+ end
24
+ [:in, node]
25
+ else
26
+ [:out, node]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,14 +1,14 @@
1
1
  module Speculations
2
2
  class Parser
3
3
  module State
4
- module Bef extend self
4
+ module In extend self
5
5
 
6
- def parse line, _lnb, node
6
+ def parse line, _lnb, node, ctxt
7
7
  case
8
8
  when State.eoblock_match(line)
9
9
  [:out, node.parent]
10
10
  else
11
- [:bef, node.add_line(line)]
11
+ [:in, node.add_line(line)]
12
12
  end
13
13
  end
14
14
  end
@@ -3,63 +3,26 @@ module Speculations
3
3
  module State
4
4
  module Out extend self
5
5
 
6
- def parse line, lnb, node
7
- if node.alternate_syntax
8
- _parse_alternate line, lnb, node
9
- else
10
- _parse_classical line, lnb, node
11
- end
12
- end
13
-
14
- private
15
-
16
- def _parse_alternate line, lnb, node
6
+ def parse line, lnb, node, _ctxt
17
7
  case
18
- when name = State.context_match(line)
19
- node = node.parent if node.parent
20
- new_node = node.add_child(name: name, lnb: lnb)
21
- new_node.set_name(nil)
22
- [:out, new_node]
23
- when State.ws_match(line)
24
- [:out, node]
25
- when name = State.potential_name(line)
26
- node.set_name(name[1])
27
- [:out, node]
28
- when State.ruby_match(line)
29
- if node.potential_name
30
- node = node.add_example(lnb: lnb, line: line)
31
- [:exa, node]
32
- else
33
- node = node.add_include(lnb: lnb)
34
- [:inc, node]
35
- end
8
+ when match = State.context_match(line)
9
+ make_new_context(lnb: lnb, node: node, match: match)
10
+ when match = State.maybe_example(line)
11
+ [:candidate, node, match[:title]]
12
+ when match = State.maybe_include(line)
13
+ [:candidate, node, :inc]
36
14
  else
37
- node.set_name(nil)
38
15
  [:out, node]
39
16
  end
40
17
  end
41
18
 
42
- def _parse_classical line, lnb, node
43
- case
44
- when name = State.context_match(line)
45
- node = node.parent if node.parent
46
- new_node = node.add_child(name: name, lnb: lnb)
47
- [:out, new_node]
48
- when State.before_match(line)
49
- node = node.set_setup(lnb: lnb)
50
- [:bef, node]
51
- when State.example_match(line)
52
- node = node.add_example(lnb: lnb, line: line)
53
- [:exa, node]
54
- when State.include_match(line)
55
- node = node.add_include(lnb: lnb)
56
- [:inc, node]
57
- when name = State.potential_name(line)
58
- node.set_name(name[1])
59
- [:out, node]
60
- else
61
- [:out, node]
62
- end
19
+ private
20
+
21
+ def make_new_context(lnb:, match:, node:)
22
+ level = match[:level].size
23
+ new_parent = node.parent_of_level(level.pred)
24
+ node = new_parent.new_context(title: match[:title], lnb: lnb, level: level)
25
+ [:out, node]
63
26
  end
64
27
 
65
28
  end
@@ -0,0 +1,35 @@
1
+ module Speculations::Parser::State::Triggers
2
+
3
+ BLANK_RGX = %r{\A\s*\z}
4
+ CONTEXT_RGX = %r[\A\s{0,3}(?<level>\#{1,7})\s+Context:?\s+(?<title>.*)]
5
+ EOBLOCK_RGX = %r[\A\s{0,3}```\s*\z]
6
+ GIVEN_RGX = %r[\A\s{0,3}(?:Given|When)\b]
7
+ EXAMPLE_RGX = %r[\A\s{0,3}Example:?\s+(<?title>.*)]
8
+ RUBY_RGX = %r[\A\s{0,3}```ruby]
9
+ THEN_RGX = %r[\A\s{0,3}(?:Then|But|And|Also)\b\s*(?<title>.*)]
10
+
11
+ def blank_line line
12
+ BLANK_RGX.match(line)
13
+ end
14
+
15
+ def context_match line
16
+ CONTEXT_RGX.match(line)
17
+ end
18
+
19
+ def eoblock_match line
20
+ EOBLOCK_RGX.match(line)
21
+ end
22
+
23
+ def maybe_example line
24
+ EXAMPLE_RGX.match(line) ||
25
+ THEN_RGX.match(line)
26
+ end
27
+
28
+ def maybe_include line
29
+ GIVEN_RGX.match(line)
30
+ end
31
+
32
+ def ruby_code_block line
33
+ RUBY_RGX.match(line)
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
- module SpeculateAbout
2
- VERSION = "0.3.0"
1
+ module Speculations
2
+ VERSION = "0.5.1"
3
3
  end
metadata CHANGED
@@ -1,48 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speculate_about
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Dober
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-14 00:00:00.000000000 Z
11
+ date: 2021-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rspec
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '3.9'
33
+ version: '3.10'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '3.9'
40
+ version: '3.10'
27
41
  description: Allows Markdown or other text files to be used as literal specs, à la
28
42
  Elixr doctest, but from any file.
29
43
  email: robert.dober@gmail.com
30
- executables: []
44
+ executables:
45
+ - speculate
31
46
  extensions: []
32
47
  extra_rdoc_files: []
33
48
  files:
49
+ - bin/speculate
34
50
  - lib/speculate_about.rb
35
51
  - lib/speculations.rb
52
+ - lib/speculations/cli.rb
36
53
  - lib/speculations/parser.rb
37
54
  - lib/speculations/parser/context.rb
38
55
  - lib/speculations/parser/context/example.rb
39
56
  - lib/speculations/parser/context/include.rb
40
- - lib/speculations/parser/context/setup.rb
41
57
  - lib/speculations/parser/state.rb
42
- - lib/speculations/parser/state/bef.rb
43
- - lib/speculations/parser/state/exa.rb
44
- - lib/speculations/parser/state/inc.rb
58
+ - lib/speculations/parser/state/candidate.rb
59
+ - lib/speculations/parser/state/in.rb
45
60
  - lib/speculations/parser/state/out.rb
61
+ - lib/speculations/parser/state/triggers.rb
46
62
  - lib/speculations/version.rb
47
63
  homepage: https://github.com/robertdober/speculate
48
64
  licenses:
@@ -63,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
79
  - !ruby/object:Gem::Version
64
80
  version: '0'
65
81
  requirements: []
66
- rubygems_version: 3.1.2
82
+ rubygems_version: 3.2.3
67
83
  signing_key:
68
84
  specification_version: 4
69
85
  summary: Extract RSpecs from Markdown
@@ -1,28 +0,0 @@
1
- class Speculations::Parser::Context::Setup
2
-
3
- attr_reader :lnb, :parent
4
-
5
- def add_line line
6
- lines << line
7
- self
8
- end
9
-
10
- def lines
11
- @__lines__ ||= []
12
- end
13
-
14
- def to_code
15
- parent.map_lines("before do") +
16
- "\n" +
17
- parent.map_lines(lines, indent: 1) +
18
- "\n" +
19
- parent.map_lines("end")
20
- end
21
-
22
-
23
- private
24
-
25
- def initialize(lnb:, parent:)
26
- @parent = parent
27
- end
28
- end
@@ -1,17 +0,0 @@
1
- module Speculations
2
- class Parser
3
- module State
4
- module Exa extend self
5
-
6
- def parse line, _lnb, node
7
- case
8
- when State.eoblock_match(line)
9
- [:out, node.parent]
10
- else
11
- [:exa, node.add_line(line)]
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- module Speculations
2
- class Parser
3
- module State
4
- module Inc extend self
5
-
6
- def parse line, _lnb, node
7
- case
8
- when State.eoblock_match(line)
9
- [:out, node.parent]
10
- else
11
- [:inc, node.add_line(line)]
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end