speculate_about 0.2.1 → 0.4.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: 585ea729bce40c7978af922d12ac5ec32384c2a4e5b1a19fd159354864344776
4
- data.tar.gz: ac750695bb18b891c1977533dce8b8932c74bb75cad89d1a1d81cd6b955cbe8f
3
+ metadata.gz: eba621014a8f6064b0d3d05c09e224c2977d0430dc2fa6483ddd8da7624e8b9d
4
+ data.tar.gz: ecbe9909ee3762d338bc423cab8aa18f86fd4ee34ab689adc7913227b2c09c7d
5
5
  SHA512:
6
- metadata.gz: e46327125543f2e112fef196d87e660e67cd3078d8a8bb61171a775130508bff51c7595be05c1a5345e167a64ec0d342e974ac450f9ddec340622561e6bd5c50
7
- data.tar.gz: f384dd4f32c12cf6c9973e520cf237712bb46e28ffe965bdf161c66a1c276977f7e991d8eea9f8d0102f136fed6e76b4f60f3ed0058df7f9737abc4413bff5d4
6
+ metadata.gz: 1bbd8986311ef802cdbd29c587116ebf386042160f8edc95536e9678e588a9ece9612990be7561084b82a83d6c129d53ac892f4da7e4a9f6eb4f495cc7041dd1
7
+ data.tar.gz: 53ad8621033646b8e89c18d900bedc4165ed948e2d65246ba6a0342d4229fc860d05e36e2cbfddd2e787a07d178ea8275ca33e785433afa6c16df10d39f286f7
@@ -3,28 +3,41 @@ require 'rspec'
3
3
  require 'speculations/parser'
4
4
 
5
5
  module SpeculateAbout
6
- def speculate_about file
6
+ def speculate_about file, alternate_syntax: false
7
7
  paths = _find_files(file, File.dirname( caller.first ))
8
8
  raise ArgumentError, "no files found for pattern #{file}" if paths.empty?
9
9
  paths.each do |path|
10
- code = _compile path, file
11
- ENV["SPECULATE_ABOUT_DEBUG"] ? puts(code) : instance_eval(code)
10
+ code = _compile path, _readable(path), alternate_syntax: alternate_syntax
11
+ ENV["SPECULATE_ABOUT_DEBUG"] ? _show(code, path) : instance_eval(code, path)
12
12
  end
13
13
  end
14
14
 
15
15
 
16
16
  private
17
17
 
18
- def _compile path, file
19
- ast = Speculations::Parser.new.parse_from_file(path, file)
18
+ def _compile path, file, alternate_syntax: false
19
+ ast = Speculations::Parser.new.parse_from_file(path, file, alternate_syntax: alternate_syntax)
20
20
  ast.to_code
21
21
  end
22
+ def _readable(path)
23
+ d = File.dirname(path)
24
+ File.join(File.basename(d), File.basename(path))
25
+ end
22
26
  def _find_files file, local_path
23
27
  [Dir.pwd, local_path]
24
28
  .flat_map do |dir|
25
29
  Dir.glob(File.join(dir, file))
26
30
  end
27
31
  end
32
+ def _show(code, path)
33
+ message = "Generated code for #{path}"
34
+ _underline(message)
35
+ puts code
36
+ end
37
+ def _underline(message, ul: "=")
38
+ puts message
39
+ puts message.gsub(/./, ul)
40
+ end
28
41
  end
29
42
 
30
43
  RSpec.configure do |conf|
@@ -3,7 +3,7 @@ class Speculations::Parser
3
3
  require_relative './parser/context'
4
4
  require_relative './parser/state'
5
5
 
6
- attr_reader :filename, :input, :orig_filename, :root, :state
6
+ attr_reader :alternate_syntax, :filename, :input, :orig_filename, :root, :state
7
7
 
8
8
  def self.parsers
9
9
  @__parsers__ ||= {
@@ -14,7 +14,8 @@ class Speculations::Parser
14
14
  }
15
15
  end
16
16
 
17
- def parse_from_file file, orig_filename = nil
17
+ def parse_from_file file, orig_filename = nil, alternate_syntax: false
18
+ @alternate_syntax = alternate_syntax
18
19
  @filename = file
19
20
  @orig_filename = orig_filename || file
20
21
  @input = File
@@ -31,7 +32,7 @@ class Speculations::Parser
31
32
  end
32
33
 
33
34
  def parse!
34
- root = node = Context.new(name: "Speculations from #{@filename}", lnb: 0, filename: @filename, orig_filename: orig_filename, parent: nil)
35
+ root = node = Context.new(alternate_syntax: alternate_syntax, name: "Speculations from #{@filename}", lnb: 0, filename: @filename, orig_filename: orig_filename, parent: nil)
35
36
  input.each_with_index do |line, lnb|
36
37
  @state, node = self.class.parsers.fetch(@state).parse(line, lnb.succ, node)
37
38
  end
@@ -3,22 +3,23 @@ class Speculations::Parser::Context
3
3
  require_relative './context/example'
4
4
  require_relative './context/setup'
5
5
 
6
- attr_reader :filename, :level, :lnb, :name, :orig_filename, :parent, :potential_name, :setup
6
+ attr_reader :alternate_syntax, :filename, :level, :lnb, :name, :orig_filename, :parent, :potential_name, :setup
7
7
 
8
8
  def add_child(name:, lnb:)
9
9
  raise "Illegal nesting" if parent
10
- children << self.class.new(name: name, lnb: lnb, parent: self)
10
+ children << self.class.new(alternate_syntax: alternate_syntax, name: name, lnb: lnb, parent: self)
11
11
  children.last
12
12
  end
13
13
 
14
14
  def add_example(lnb:, line:)
15
15
  examples << Example.new(lnb: lnb, parent: self, line: line, name: potential_name)
16
- @potential_name = nil
16
+ reset_context
17
17
  examples.last
18
18
  end
19
19
 
20
20
  def add_include(lnb:)
21
21
  includes << Include.new(lnb: lnb, parent: self)
22
+ @given = false
22
23
  includes.last
23
24
  end
24
25
 
@@ -30,6 +31,10 @@ class Speculations::Parser::Context
30
31
  @__examples__ ||= []
31
32
  end
32
33
 
34
+ def given?
35
+ @given
36
+ end
37
+
33
38
  def includes
34
39
  @__includes__ ||= []
35
40
  end
@@ -39,8 +44,20 @@ class Speculations::Parser::Context
39
44
  lines.flatten.map{ |line| "#{prefix}#{line.strip}" }.join("\n")
40
45
  end
41
46
 
47
+ def reset_context
48
+ @potential_name = nil
49
+ @given = false
50
+ self
51
+ end
52
+
53
+ def set_given given
54
+ @given = given
55
+ self
56
+ end
57
+
42
58
  def set_name(potential_name)
43
59
  @potential_name = potential_name
60
+ self
44
61
  end
45
62
 
46
63
  def set_setup(lnb:)
@@ -60,8 +77,10 @@ class Speculations::Parser::Context
60
77
 
61
78
  private
62
79
 
63
- def initialize(lnb:, name:, filename: nil, orig_filename: nil, parent: nil)
80
+ def initialize(alternate_syntax: false, lnb:, name:, filename: nil, orig_filename: nil, parent: nil)
64
81
  _init_from_parent filename, orig_filename, parent
82
+ @alternate_syntax = alternate_syntax
83
+ @given = false
65
84
  @level = parent ? parent.level.succ : 1
66
85
  @lnb = lnb
67
86
  @setup = nil
@@ -74,8 +93,12 @@ class Speculations::Parser::Context
74
93
  end
75
94
 
76
95
  def _init_from_parent filename, orig_filename, parent
77
- @filename = parent ? parent.filename : filename
96
+ _set_filename filename, orig_filename, parent
78
97
  @orig_filename = parent ? parent.orig_filename : orig_filename
98
+ end
99
+
100
+ def _set_filename filename, orig_filename, parent
101
+ @filename = parent ? parent.filename : filename
79
102
  raise ArgumentError, "no filename given in root context" unless @filename
80
103
  end
81
104
 
@@ -8,8 +8,12 @@ module Speculations::Parser::State extend self
8
8
  CONTEXT_RGX = %r[\A\s{0,3}\#{1,7}\s+Context\s+(.*)]
9
9
  EOBLOCK_RGX = %r[\A\s{0,3}```\s*\z]
10
10
  EXAMPLE_RGX = %r[\A\s{0,3}```.*\s:example]
11
+ GIVEN_RGX = %r[\A\s{0,3}(?:Given|When)\b]
11
12
  INCLUDE_RGX = %r[\A\s{0,3}```.*\s:include]
12
- NAME_RGX = %r[\A\s{0,3}Example:\s+(.*)]
13
+ NAME_RGX = %r[\A\s{0,3}Example:?\s+(.*)]i
14
+ RUBY_RGX = %r[\A\s{0,3}```ruby]
15
+ THEN_RGX = %r[\A\s{0,3}(?:Then|But|And)\s+(.*)]
16
+ WS_RGX = %r[\A\s*\z]
13
17
 
14
18
  def before_match line
15
19
  BEFORE_RGX =~ line
@@ -28,6 +32,10 @@ module Speculations::Parser::State extend self
28
32
  def example_match line
29
33
  EXAMPLE_RGX =~ line
30
34
  end
35
+
36
+ def given_match line
37
+ GIVEN_RGX =~ line
38
+ end
31
39
 
32
40
  def include_match line
33
41
  INCLUDE_RGX =~ line
@@ -36,4 +44,16 @@ module Speculations::Parser::State extend self
36
44
  def potential_name line
37
45
  NAME_RGX.match(line)
38
46
  end
47
+
48
+ def ruby_match line
49
+ RUBY_RGX =~ line
50
+ end
51
+
52
+ def then_match line
53
+ THEN_RGX.match(line)
54
+ end
55
+
56
+ def ws_match line
57
+ WS_RGX =~ line
58
+ end
39
59
  end
@@ -4,6 +4,49 @@ module Speculations
4
4
  module Out extend self
5
5
 
6
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
17
+ 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
+ [:out, new_node.reset_context]
22
+ when State.ws_match(line)
23
+ [:out, node]
24
+ when name = State.potential_name(line)
25
+ node.set_name(name[1])
26
+ node.set_given(false)
27
+ [:out, node]
28
+ when name = State.then_match(line)
29
+ node.set_name(name[1])
30
+ node.set_given(false)
31
+ [:out, node]
32
+ when State.given_match(line)
33
+ [:out, node.set_given(true)]
34
+ when State.ruby_match(line)
35
+ if node.potential_name
36
+ node = node.add_example(lnb: lnb, line: line)
37
+ [:exa, node]
38
+ elsif node.given?
39
+ node = node.add_include(lnb: lnb)
40
+ [:inc, node]
41
+ else
42
+ [:out, node]
43
+ end
44
+ else
45
+ [:out, node.reset_context]
46
+ end
47
+ end
48
+
49
+ def _parse_classical line, lnb, node
7
50
  case
8
51
  when name = State.context_match(line)
9
52
  node = node.parent if node.parent
@@ -0,0 +1,3 @@
1
+ module SpeculateAbout
2
+ VERSION = "0.4.1"
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speculate_about
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.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-06-23 00:00:00.000000000 Z
11
+ date: 2020-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -43,6 +43,7 @@ files:
43
43
  - lib/speculations/parser/state/exa.rb
44
44
  - lib/speculations/parser/state/inc.rb
45
45
  - lib/speculations/parser/state/out.rb
46
+ - lib/speculations/version.rb
46
47
  homepage: https://github.com/robertdober/speculate
47
48
  licenses:
48
49
  - Apache-2.0