lab42_literate 0.1.2 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 719c356f00f0141fa7a9c0bfec1b25792f067927
4
- data.tar.gz: ab1de21e75855dcf24996a447d08479734a54901
3
+ metadata.gz: 5dc4434c53fc4b7ae709911bed4ea867eee642b4
4
+ data.tar.gz: 3a68fe614d6f32e3b5e13d8bb46a02ca28347ffc
5
5
  SHA512:
6
- metadata.gz: eb38c90f79ff71b04b4d6252fe0f5ce7ba6d4bc9564ce279ee8ea2f198f107568d7e609eccf3952af8680a389c13b0654086cc0edd784d631af86c4db4fbd8f4
7
- data.tar.gz: fadeeeee4eb23c14de66a2d1788a7d01aa2ffb620c7a6f65b3c5b82c01c9d5def3e517bb607bdfe3ea7be8e6ce5f643d0dfd12943f6e9c8fae498b58348813d3
6
+ metadata.gz: d9e5a3cab528ecc1e3c8b4aec44068506e69dfc0445e121ddaef0e6fb350b8c379e6ec1141f48222cb775d7a66925d988d6e65cc23e9b7c21358066a0ddc5184
7
+ data.tar.gz: 128ced3230f2486533283039ed0ae96d1c278826d4dcc557b5329b52d664ac0f6f4067f75ad3f9dd5e77b547ee64f3982358bb87ecc9c83fbdab4342045ea766
data/README.md CHANGED
@@ -7,7 +7,17 @@
7
7
  [![Issue Count](https://codeclimate.com/github/RobertDober/lab42_literate/badges/issue_count.svg)](https://codeclimate.com/github/RobertDober/lab42_literate)
8
8
  [![Test Coverage](https://codeclimate.com/github/RobertDober/lab42_literate/badges/coverage.svg)](https://codeclimate.com/github/RobertDober/lab42_literate)
9
9
 
10
- ## Literate Programming à la doctest.
10
+ ## Literate Programming à la doctest in Elxir.
11
+
12
+ [Elixir Doctest](https://elixir-lang.org/getting-started/mix-otp/docs-tests-and-with.html#doctests) has inspired this gem.
13
+
14
+ Of course Elixir doctests from the metadata of a compiled elixir source (beam).
15
+
16
+ As in Ruby we do not have any metadata this works with simple text extraction and evalutaion.
17
+
18
+ This gives us however the possibility to write our doctests in **any** file and allows you
19
+ to assure that your `README.md` code examples are **all correct**.
20
+
11
21
 
12
22
  Just extract code blocks from any file, and run them as specs with a simple `doctest file` in an RSpec example group.
13
23
 
@@ -49,14 +59,76 @@ with
49
59
 
50
60
  ### How does it work?
51
61
 
52
- Each block ` ```ruby literate` creates an example with title `"literate block in #{file}:#{start_lnb}..#{end_lnb}"`
53
- and instance_evals the lines from the block in the example's context.
62
+ Each block ` ```ruby literate` creates an example group with title `"literate block in #{file}:#{start_lnb}..#{end_lnb}"`.
63
+
64
+ Then an anonymous example `it do ...`
65
+ and instance_evals the lines from the block in this example's context.
54
66
 
55
67
 
56
68
  ### Setup?
57
69
 
58
- Not yet.
59
70
 
60
- ### Explicit Title of the generated example
71
+ #### Inside the spec calling `doctest`
72
+
73
+
74
+ Given this literate file
75
+
76
+ ```ruby literate
77
+ foo.reverse #=> 'oof'
78
+ ```
79
+
80
+ will perfectly work if you setup your spec as follows
81
+
82
+ ```ruby
83
+ RSpec.describe 'FOO', type: :literate do
84
+ let(:foo){ 'foo' }
85
+ doctest('literate_file.md')
86
+ end
87
+ ```
88
+
89
+
90
+ #### Inside the literal file itself
91
+
92
+ All literate blocks containing a `Given` block inside the document will be
93
+ executed in the context in which `doctest` has been called, **before** the
94
+ example blocks will be generated, thusly the following literate file will
95
+ succeed
96
+
97
+ ```ruby literate
98
+ Given do
99
+ let(:a){ 1 }
100
+ end
101
+ ```
102
+
103
+ ```ruby literate
104
+ a + b #=> 42
105
+ ```
106
+
107
+ ```ruby literate
108
+ Given do
109
+ let(:b){ 41 }
110
+ end
111
+ ```
112
+
113
+
114
+
115
+ ### Explicit Title of the generated Example Group
61
116
 
62
117
  Just add text after ` ```ruby literate`
118
+
119
+ E.g.
120
+
121
+ ```ruby literate Assure errors are empty
122
+
123
+ ...
124
+ expect(errors).to be_empty
125
+
126
+ ```
127
+
128
+ ### Calling `doctest` inside an Example
129
+
130
+ Will be deprecated.
131
+
132
+ Does not support all features.
133
+
134
+ Use at own risk.
@@ -2,10 +2,18 @@ module Lab42
2
2
  module Literate
3
3
  require_relative 'literate/example_doctest'
4
4
  require_relative 'literate/group_doctest'
5
+
6
+ module Given
7
+ def Given &blk
8
+ instance_exec(&blk)
9
+ end
10
+ end
5
11
  end
6
12
  end
7
13
 
8
14
  RSpec.configure do | conf |
9
15
  conf.extend Lab42::Literate::GroupDoctest, type: :literate
16
+ conf.extend Lab42::Literate::Given, type: :literate
17
+
10
18
  conf.include Lab42::Literate::ExampleDoctest, type: :literate
11
19
  end
@@ -1,3 +1,7 @@
1
+ require 'parser/current'
2
+ Parser::Builders::Default.emit_lambda = true
3
+ Parser::Builders::Default.emit_procarg0 = true
4
+
1
5
  class Lab42::Literate::Extractor::Block
2
6
  attr_reader :lines, :start_lnb, :title
3
7
 
@@ -5,14 +9,23 @@ class Lab42::Literate::Extractor::Block
5
9
  lines << line
6
10
  end
7
11
 
12
+
8
13
  def get_title alternative
9
14
  title.empty? ? alternative : title
10
15
  end
11
16
 
17
+
18
+ def given?
19
+ parsed.children.first.children == [nil, :Given]
20
+ rescue
21
+ false
22
+ end
23
+
12
24
  def range
13
25
  start_lnb..(start_lnb.pred + lines.size)
14
26
  end
15
27
 
28
+
16
29
  private
17
30
 
18
31
  def initialize start_lnb, title: ''
@@ -21,4 +34,7 @@ class Lab42::Literate::Extractor::Block
21
34
  @title = title
22
35
  end
23
36
 
37
+ def parsed
38
+ @__parsed__ ||= Parser::CurrentRuby.parse(lines.join("\n"))
39
+ end
24
40
  end
@@ -3,20 +3,27 @@ module Lab42::Literate::GroupDoctest
3
3
  Ex = Lab42::Literate::Extractor
4
4
 
5
5
  def doctest filename
6
- doc_blocks = Ex.extract(File.readlines(filename))
7
- doc_blocks.each{ |block| make_context filename, block }
6
+ blocks = Ex
7
+ .extract(File.readlines(filename))
8
+
9
+ setups, examples = blocks.partition(&:given?)
10
+ setups.each{ |setup| make_setup filename, setup }
11
+ examples.each{ |example| make_context filename, example }
8
12
  end
9
13
 
10
14
  private
11
15
 
12
- def make_context filename, block
13
- return if block.lines.empty?
14
- title = block.get_title "literate block in #{filename}:#{block.range.inspect}"
16
+ def make_context filename, example
17
+ return if example.lines.empty?
18
+ title = example.get_title "literate block in #{filename}:#{example.range.inspect}"
15
19
  context title do
16
20
  it do
17
- eval(block.lines.join("\n"))
21
+ eval(example.lines.join("\n"))
18
22
  end
19
23
  end
20
24
  end
21
25
 
26
+ def make_setup filename, setup
27
+ eval(setup.lines.join("\n"))
28
+ end
22
29
  end
@@ -1,5 +1,5 @@
1
1
  module Lab42
2
2
  module Literate
3
- VERSION = '0.1.2'
3
+ VERSION = '0.1.3'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lab42_literate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Dober
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-19 00:00:00.000000000 Z
11
+ date: 2017-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.4'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: cucumber
29
43
  requirement: !ruby/object:Gem::Requirement