SpecMe 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 039da57027c51ea0dcab8bcf05abc9f58b380976
4
+ data.tar.gz: 68eb5cf7432a180e0c97eb61b01300470920ec03
5
+ SHA512:
6
+ metadata.gz: 1fcf51d6eeff16395523aebce2781aad0b2d903067686f99da7287b45811b79b33cba0e4545591cac5809cbf9536d616793d9817dbc038173783cbbb1961a9e3
7
+ data.tar.gz: fa6b6f2dd0cb56b39c0a8238aec892a74da5d047aee6d7713ec54f126566671e5d4607d4048f75548e72009707e6462bd7b195825f2dc2786c2c1312b0dd8ef0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Robert Dober
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # SpecMe
2
+
3
+ You have a great README, with great code examples, just make sure they are correct
4
+
5
+ ## How?
6
+
7
+ Simply by writing code blocks like this one
8
+
9
+ ```md
10
+ <!-- SpecMe -->
11
+ ```ruby
12
+
13
+ completelyNewAdder = MyShinyCodeGenerator.new( :adder )
14
+ completelyNewAdder(1, 2, 3) #--> 6
15
+
16
+ ```
17
+ ```
18
+
19
+ Which will create specs like this
20
+ ```ruby
21
+
22
+ describe "Some generated or provided name" do
23
+ it "some other generated or provided name" do
24
+ completelyNewAdder = MyShinyCodeGenerator.new( :adder )
25
+ expect(
26
+ completelyNewAdder(1, 2, 3)
27
+ ).to eq(
28
+ 6
29
+ )
30
+ end
31
+ end
32
+ ```
33
+
34
+ ## And How exactly?
35
+
36
+
37
+ [See here](dox/UserManual.md)
@@ -0,0 +1,13 @@
1
+ require 'ostruct'
2
+
3
+ class SpecMe
4
+ Config = OpenStruct.new \
5
+ spec_me_root: File.join( 'spec', 'spec_me' ),
6
+ spec_me_helper: 'spec_helper',
7
+ spec_me_tag: 'spec_me',
8
+
9
+ start_code_block: %r{\A```ruby\z},
10
+ end_code_block: %r{\A```\z},
11
+ code_comment: %r{\A\s*#\s*(.*)\z},
12
+ equality_xp: %r{\A\s*(.*)#-->(.*)\z}
13
+ end # class SpecMe
@@ -0,0 +1,57 @@
1
+ class SpecMe
2
+ class Renderer
3
+ attr_accessor :config
4
+
5
+ def render( ast, file_name:, count:1, spec_helper: nil, **params)
6
+ (
7
+ spec_helper_lines(spec_helper) +
8
+ description( file_name: file_name, count: count, **params ) +
9
+ example( count: count ) +
10
+ code(ast) +
11
+ end_lines( 2 )
12
+ ) # .tap{ |r| puts r }
13
+ end
14
+
15
+ def code(ast)
16
+ ast.map{ |node| render_node node }.flatten
17
+ end
18
+
19
+ def description( file_name:, count: 1, **params)
20
+ example_group_name = params.fetch :example_group_name, "#{file_name} #{count}"
21
+ rspec_tag = params.fetch :rspec_tag, config.spec_me_tag
22
+ [%{describe '#{example_group_name}', :#{rspec_tag} do}] #.tap{|r| p description: r}
23
+ end
24
+
25
+ def end_lines n
26
+ n.times.map{ |i|
27
+ ' ' * (n-i.succ) + 'end'
28
+ }
29
+ end
30
+
31
+ def example( count:)
32
+ [%{ it 'example #{count}' do}]
33
+ end
34
+
35
+ def render_node node
36
+ case node.first
37
+ when :comment
38
+ %{ # #{node.last}}
39
+ when :ruby
40
+ %{ #{node.last}}
41
+ when :equality_xp
42
+ [%{ expect( #{node[1]} ).to eq(},
43
+ %{ #{node.last}},
44
+ %{ )}]
45
+ end
46
+ end
47
+ def spec_helper_lines spec_helper
48
+ spec_helper ||= config.spec_me_helper
49
+ [ %{require '#{spec_helper}'}, '' ]
50
+ end
51
+ private
52
+
53
+ def initialize config
54
+ self.config = config
55
+ end
56
+ end # module Renderer
57
+ end # class SpecMe
@@ -0,0 +1,3 @@
1
+ class SpecMe
2
+ VERSION = "0.0.1.pre"
3
+ end # class SpecMe
data/lib/spec_me.rb ADDED
@@ -0,0 +1,75 @@
1
+ require_relative 'spec_me/config'
2
+ require_relative 'spec_me/renderer'
3
+
4
+ class SpecMe
5
+ attr_accessor :ast, :config, :file
6
+
7
+ def run args
8
+ file = args.shift or raise ArgumentError, "Missing file name"
9
+ raise ArgumentError, "Input file `#{file}' missing or not readable" unless File.readable? file
10
+ self.file = file
11
+ parse File.readlines( file )
12
+ generate_spec
13
+ end
14
+
15
+ def initialize
16
+ self.config = SpecMe::Config
17
+ end
18
+
19
+ def ast_to_spec
20
+ Renderer.new( config ).render ast, count: 1, file_name: @base_file_name
21
+ end
22
+
23
+ def generate_spec
24
+ return if ast.empty?
25
+ @base_file_name = File
26
+ .basename( file )
27
+ .sub( %r{\..*\z}, "" )
28
+ @output_file = File.join config.spec_me_root, "#{@base_file_name}_spec.rb"
29
+
30
+ File.open( @output_file, "w" ) do | f |
31
+ f.puts ast_to_spec
32
+ end
33
+ end
34
+
35
+ def parse lines
36
+ self.ast = []
37
+ @state = :outside
38
+ lines.each do | line |
39
+ state_machine line.chomp
40
+ end
41
+ post_parse
42
+ end
43
+
44
+ def parse_line line
45
+ case line
46
+ when config.code_comment
47
+ [:comment, Regexp.last_match[1]]
48
+ when config.equality_xp
49
+ [:equality_xp] + Regexp.last_match[1..2].map(&:strip)
50
+ else
51
+ [:ruby, line.strip]
52
+ end
53
+ end
54
+
55
+ def post_parse
56
+ # No need to create specs if there are no expectations
57
+ self.ast = [] unless ast.any?{ |node| %r{_xp\z} === node.first }
58
+ end
59
+ private
60
+
61
+ def state_machine line
62
+ case @state
63
+ when :outside
64
+ # update_config_from line if config.instruction_line === line
65
+ return unless config.start_code_block === line
66
+ @state = :inside
67
+ when :inside
68
+ if config.end_code_block === line
69
+ @state = :outside
70
+ else
71
+ self.ast << parse_line( line )
72
+ end
73
+ end
74
+ end
75
+ end # class SpecMe
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: SpecMe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre
5
+ platform: ruby
6
+ authors:
7
+ - Robert Dober
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.12
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.12
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.13.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.13.0
41
+ description: Generating rspecs from ruby code blocks in README files
42
+ email: robert.dober@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - LICENSE
48
+ - README.md
49
+ - lib/spec_me.rb
50
+ - lib/spec_me/config.rb
51
+ - lib/spec_me/renderer.rb
52
+ - lib/spec_me/version.rb
53
+ homepage: https://github.com/RobertDober/SpecMe
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: 2.1.0
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">"
69
+ - !ruby/object:Gem::Version
70
+ version: 1.3.1
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.2.0
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Assuring you code examples pass, with RSpec
77
+ test_files: []