rspec-scaffold 1.0.0 → 2.0.0.beta1

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: 51b15bd17f15c8ded617f732b63b29b839091124
4
- data.tar.gz: 5cf8d3cd2aa8b584667c7ac49833682b378b1075
3
+ metadata.gz: f05f5d2cb52269e49bd64ac995962240bcea44fa
4
+ data.tar.gz: d1a5ef14f5cfa6c4ae05c06d0152bde1b4b92a99
5
5
  SHA512:
6
- metadata.gz: 04bbf347bcf64103ccfa680ee78514d1d455b9d698d51dec3272413513074a9aaf5204851e1cda559fc27404391134a5233fdf8a717d8a9e11e7fbd3e62c291d
7
- data.tar.gz: 07f52b0f041b1ce612627ac453c35d18d538ba9bf20d6801aeea1a441d8ab1b95a4b206d19700a26f39fc401c6fab82006f737d96744b1d8bb17f66547d26ea2
6
+ metadata.gz: 01e90b853c0797e877430108ac79cb6f9d32e06df07335a63abbb844c6e49d3ffebc416eb1260c0ff2f74d8b00344c1822f6efc137d17a74fcbb951c5564b58e
7
+ data.tar.gz: b8b2d7a25dedd8113c3adeee9182e4fe73fb4f8d622fdc15cd03913ab564cdb962ed8c3aef2acc449eb97bc53f839f9835c61d49c715521b8c8689e323480a47
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.2.1
5
- - 2.2.2
6
- - 2.2.3
3
+ - 2.1.10
4
+ - 2.2.6
5
+ - 2.3.4
6
+ - 2.4.0
7
7
  before_install: gem install bundler -v 1.10.4
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [2.0.0.beta1] - 2017-05-12
8
+ ### Added
9
+ - Convenience methods `RSpec::Scaffold.testify_file` and `RSpec::Scaffold.testify_text` which allow making scaffolds from within code.
10
+ - rspec-scaffold CLI
11
+
12
+ ### Changed
13
+ - Scaffolds no longer produce the 'require spec/rails_helper' line - devs should keep it in .rspec file.
14
+ - Updates to Rails controller scaffolds
15
+ - Updates to Rails Model scaffolds
16
+
17
+ ## [1.0.0] - 2016-08-05
18
+ Core functionality, `rake rspec:scaffold[app/models/ability.rb]`.
data/Gemfile CHANGED
@@ -3,8 +3,6 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in rspec-scaffold.gemspec
4
4
  gemspec
5
5
 
6
- gem 'byebug' if RUBY_VERSION >= '2.0.0'
7
-
8
6
  group :test do
9
7
  gem 'rake' # for ogb TravisCI
10
8
  gem 'rspec-core', '~> 3'
data/README.md CHANGED
@@ -1,22 +1,74 @@
1
- # RSpec Scaffolding [![Build Status](https://travis-ci.org/ridiculous/rspec-scaffold.svg)](https://travis-ci.org/ridiculous/rspec-scaffold)
1
+ # RSpec Scaffold [![Build Status](https://travis-ci.org/ridiculous/rspec-scaffold.svg)](https://travis-ci.org/ridiculous/rspec-scaffold)
2
2
 
3
- Generates RSpec scaffolding for existing code. Helps you write tests by showing you what you should be testing,
4
- which are conditions and changes to state (at a minimum).
3
+ Generates RSpec scaffolding for existing code.
4
+ Cleverly infers spec location from source file location.
5
+ Helps you write tests by showing you what you should be testing, which are conditions and changes to state (at a minimum).
5
6
 
6
7
  ## Installation
7
8
 
8
9
  Requires Ruby >= 1.9.3
9
10
 
11
+ __1. update gemfile and bundle__
12
+
10
13
  ```ruby
11
- gem 'rspec-scaffold'
14
+ gem 'rspec-scaffold', '~> 2.0.0.beta1', require: false
15
+ ```
16
+
17
+ __2. see if it works__
18
+
19
+ ```
20
+ rspec-scaffold
12
21
  ```
13
22
 
23
+ ## Caveats
24
+ Works best if used from within a Rails app root and if the project has the spec/ directory (it should!).
25
+
14
26
  ## Usage
27
+ The gem provides a command line utility `rspec-scaffold` for working with existing files, and simple-to-use module methods for programmatic use.
28
+ The idea is to point to existing ruby code files and `rspec-scaffold` will ensure corresponding spec files in `/spec` directory.
29
+
30
+ ### The CLI
31
+ Only handles files/directories. If you want to feed in raw code, use the module methods.
15
32
 
16
- Takes either a file or a directory.
33
+ __file in -> file out__
17
34
 
18
35
  ```bash
19
- rake rspec:scaffold[lib]
36
+ rspec-scaffold "path/to/code.rb"
37
+ ```
38
+
39
+ __directory in -> files out__
40
+
41
+ ```bash
42
+ # pass -y option to pre-agree to many spec file creation
43
+ rspec-scaffold "app/models/"
44
+ ```
45
+
46
+ __output to STDOUT instead of file__
47
+
48
+ ```bash
49
+ rspec-scaffold -t "path/to/code.rb"
50
+ ```
51
+
52
+ ### The methods
53
+
54
+ Three scenarios are supported:
55
+
56
+ __1. Provide ruby code -> get scaffold string (not supported by CLI since it would be cumbersome)__
57
+
58
+ ```rb
59
+ RSpec::Scaffold.testify_text(text)
60
+ ```
61
+
62
+ __2. Provide ruby code file(s) -> get scaffold string__
63
+
64
+ ```rb
65
+ RSpec::Scaffold.testify_file(filepath, :to_text)
66
+ ```
67
+
68
+ __3. Provide ruby code file(s) -> get scaffold file(s)__
69
+
70
+ ```rb
71
+ RSpec::Scaffold.testify_file(filepath, out: "/optional/custom/output/file.rb")
20
72
  ```
21
73
 
22
74
  ## Example
@@ -42,39 +94,45 @@ end
42
94
  ```
43
95
 
44
96
  ```bash
45
- rake rspec:scaffold[app/models/ability.rb]
97
+ rspec-scaffold "app/models/ability.rb"
46
98
  ```
47
99
 
48
- Outputs:
100
+ Outputs to 'spec/models/ability_spec.rb':
49
101
 
50
102
  ```ruby
51
- # spec/models/ability_spec.rb
52
- require "spec_helper"
53
-
54
- describe Ability do
103
+ # rspec spec/models/ability_spec.rb
104
+ describe Ability, type: :model do
105
+ klass = Ability
55
106
  let(:user) {}
56
107
 
57
- subject { described_class.new user }
58
-
59
108
  describe "#initialize" do
60
109
  context "when user.admin?" do
61
- before {}
110
+ xit "should " do
111
+ expect(0).to eq 1
112
+ end
62
113
  end
63
114
 
64
115
  context "unless user.admin?" do
65
- before {}
116
+ xit "should " do
117
+ expect(0).to eq 1
118
+ end
66
119
  end
67
120
  end
121
+
68
122
  end
69
123
  ```
70
124
 
125
+ ## TODO
126
+ * Have scaffolds be aware of method arguments, especially keyword ones.
127
+ * Have concern scaffolds output which module it is they are for.
128
+ * Have concern scaffolds recognize methods defined within `module ClassMethods` as class methods.
129
+
71
130
  ## Development
72
131
 
73
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
132
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
74
133
 
75
134
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
76
135
 
77
136
  ## Contributing
78
137
 
79
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rspec-scaffold.
80
-
138
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ridiculous/rspec-scaffold.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rspec/scaffold'
4
+ RSpec::Scaffold::Cli.new(Pathname(`pwd`.strip)).start
@@ -0,0 +1,161 @@
1
+ module RSpec
2
+ module Scaffold
3
+ class Cli
4
+ # This class handles `rspec=scaffold` command runs from command line.
5
+
6
+ # this method allows simple testing since it, unlike ARGV constant, can be mocked.
7
+ def self.command_line_arguments
8
+ return ARGV # => ["-t", "-y", "/some/path"] or ["-ty", "/some/path"]
9
+ end
10
+
11
+ # @param [Pathname] boot_path
12
+ def initialize(boot_path)
13
+ @boot_path = boot_path
14
+ @command_line_arguments = send(:class).command_line_arguments
15
+ end
16
+
17
+ # This method will be run as a script and uses on ARGV hash contents
18
+ def start
19
+ # fallback to help text output if needed args are missing
20
+ (puts help_string; abort) if path_argument.nil? || options.include?("h")
21
+
22
+ # 0 see if path argument is not absolute
23
+ (puts absolute_path_warning; abort) if path_argument[%r'\A[\/]']
24
+
25
+ # 0. see if passed file/dir exists and is in boot_path tree.
26
+ (puts not_found_warning_string; abort) if !file_or_dir.exist?
27
+
28
+ # 1. must process path argument to determine whether it is a single file or a dir.
29
+ @processable_files = if file_or_dir.directory?
30
+ RSpec::Scaffold::DirExpander.new(file_or_dir).expand_ruby_files
31
+ else
32
+ # file_or_dir.file?
33
+ [file_or_dir]
34
+ end
35
+
36
+ # 2. verify processing if there are numerous files and -y is not given
37
+ if !many_processable_file_danger? || argumented_agreeing? || output_to_console?
38
+ # noop, alls well
39
+ else
40
+ puts "#{@processable_files.size} files are about to be processed. Are you sure? [Y/n]"
41
+ if STDIN.gets.strip[%r'\Ay'i]
42
+ green("-> Proceeding with scaffold build!")
43
+ else
44
+ abort("Nothing was done!")
45
+ end
46
+ end
47
+
48
+ # 2. once path processing is done, array of files (sometimes and array of one file) is looped over
49
+ @processable_files.each do |processable_file|
50
+ # all is set for processing
51
+ if output_to_console?
52
+ test_scaffold = RSpec::Scaffold.testify_file(processable_file, :to_text)
53
+
54
+ puts("#== #{processable_file} ==")
55
+ puts("")
56
+ puts(test_scaffold)
57
+ puts("")
58
+ else
59
+ # build found file's spec file location
60
+ spec_file_location = RSpec::Scaffold::SpecLocationBuilder.new(@boot_path, processable_file).spec_location
61
+
62
+ # output to spec files, core behavior
63
+ RSpec::Scaffold.testify_file(processable_file, out: spec_file_location)
64
+ end
65
+ end
66
+
67
+ puts "-> All done!"
68
+
69
+ return true
70
+ end
71
+
72
+ private
73
+
74
+ self::OPTIONS = {
75
+ "--help" => "h",
76
+ "--text" => "t",
77
+ }.freeze
78
+
79
+ def options
80
+ @options ||= @command_line_arguments.select{|arg| arg[0] == "-" && arg.size > 1}.map do |arg|
81
+ if !!arg == true && arg[1] != "-"
82
+ # unpack several singledash options
83
+ arg.split("")[1..-1]
84
+ else
85
+ # making doubledash options into singledash
86
+ send(:class)::OPTIONS[arg]
87
+ end
88
+ end.flatten.uniq.join("")
89
+
90
+ return @options #=> "hty"
91
+ end
92
+
93
+ def argumented_agreeing?
94
+ return options.include?("y")
95
+ end
96
+
97
+ def output_to_console?
98
+ return options.include?("t")
99
+ end
100
+
101
+ def many_processable_file_danger?
102
+ return 5 < @processable_files.size
103
+ end
104
+
105
+ def path_argument
106
+ @path_argument ||= (!!@command_line_arguments[-1] == true && @command_line_arguments[-1][0] != "-" ? @command_line_arguments[-1] : nil)
107
+
108
+ return @path_argument
109
+ end
110
+
111
+ def file_or_dir
112
+ return nil if path_argument.nil?
113
+
114
+ @file_or_dir ||= findable_pathname
115
+
116
+ return @file_or_dir
117
+ end
118
+
119
+ def findable_pathname
120
+ return @findable_pathname ||= Pathname("#{@boot_path}").join("#{path_argument}")
121
+ end
122
+
123
+ def help_string
124
+ help_string = <<-ENDBAR
125
+ Build RSpec tests scaffolds for existing ruby code.
126
+
127
+ Usage:
128
+ rspec-scaffold <options> PATH
129
+
130
+ Available options:
131
+ -h, --help Prints this message
132
+ -t, --text Outputs scaffold(s) to STDOUT instead of spec files
133
+
134
+ Common use cases:
135
+ 1) file in -> file out | rspec-scaffold "path/to/code.rb"
136
+ 2) directory in -> files out | rspec-scaffold "path/to/code/directory"
137
+ 3) output to STDOUT instead of files | rspec-scaffold -t "path/to/code.rb"
138
+ ENDBAR
139
+
140
+ return help_string.strip.gsub(%r'\A\s+', '')
141
+ end
142
+
143
+ def not_found_warning_string
144
+ warning_string = <<-ENDBAR
145
+ Could not find "#{findable_pathname}"
146
+ ENDBAR
147
+
148
+ return warning_string.strip.gsub(%r'\A\s+', '')
149
+ end
150
+
151
+ def absolute_path_warning
152
+ warning_string = <<-ENDBAR
153
+ Absolute path argument '#{path_argument}' detected. Please use a relative path (no leading slash) from project root.
154
+ ENDBAR
155
+
156
+ return warning_string.strip.gsub(%r'\A\s+', '')
157
+ end
158
+
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,28 @@
1
+ module RSpec
2
+ module Scaffold
3
+ class DirExpander
4
+ # manages recursively finding ruby files in directories.
5
+
6
+ # @param [Pathname] input_dir
7
+ def initialize(input_dir)
8
+ @input_dir = Pathname(input_dir)
9
+ end
10
+
11
+ # RSpec::Scaffold::DirExpander.new("/path/to/dir")
12
+ def expand_ruby_files
13
+ # 1. Raise if not a directory
14
+ raise(ArgumentError.new(%Q|"#{file}" is not a directory|)) if !@input_dir.directory?
15
+
16
+ # 2. do the expansion of ruby files
17
+ print ">> scanning #{@input_dir} tree for ruby files... "
18
+
19
+ @ruby_files_in_tree ||= Dir.glob("#{@input_dir.to_s.gsub(%r'/\z', '')}/**/*.rb")
20
+
21
+ puts "done"
22
+
23
+ return @ruby_files_in_tree #=> ["/rspec-scaffold/spec/dummy/app/lib/some_service_class.rb"] array of strings
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ module RSpec
2
+ module Scaffold
3
+ class FileWriter
4
+ # manages outputting test scaffolds to file.
5
+
6
+ def initialize(output_file, output_text)
7
+ @output_file = Pathname(output_file)
8
+ @output_text = output_text
9
+ end
10
+
11
+ # RSpec::Scaffold::FileWriter.new("/path/to/file.rb", "yay, test scaffold!")
12
+ def write!
13
+ # 1. skip if file already exists.
14
+ if output_file_already_exists?
15
+ RSpec::Scaffold.log("- #{@output_file} - already exists", :puts)
16
+ return
17
+ end
18
+
19
+ # 2. ensure parent directories exist
20
+ FileUtils.makedirs(@output_file.parent)
21
+
22
+ # 3. write to file
23
+ File.open(@output_file, 'wb') do |f| # 'wb' originally
24
+ f << @output_text
25
+ end
26
+
27
+ RSpec::Scaffold.log("+ #{@output_file}")
28
+
29
+ return @output_file.to_s
30
+ end
31
+
32
+ private
33
+ def output_file_already_exists?
34
+ return @exists ||= @output_file.exist?
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -1,36 +1,57 @@
1
1
  module RSpec
2
2
  module Scaffold
3
- class Generator < DelegateClass(Ryan)
3
+ class Generator
4
+ # Generates an array of lines that can be joined into an RSpec file based.
5
+ #
6
+ # @param [Ryan,#name,#funcs,#initialization_args,#class?,#module?] parser object that is used to build the rspec file
4
7
 
5
- # = Class
6
- # generate a rspec file based on existing code
7
-
8
- attr_reader :file
9
-
10
- def initialize(file)
11
- @file = file
12
- super Ryan.new(file)
8
+ def initialize(parser)
9
+ @parser = parser
13
10
  end
14
11
 
15
- def const
16
- @const ||= name.split('::').inject(Kernel) { |k, part| k.const_get part }
17
- end
12
+ def perform(parser=nil)
13
+ # for backwards compat with arg to perform
14
+ @parser = (parser.nil? ? @parser : parser)
18
15
 
19
- def perform
20
16
  indent = (' ' * 2)
21
17
  second_indent = indent * 2
22
- lines = [%Q(require "#{Scaffold.helper_file}"), %Q(), %Q(describe #{const} do)]
23
- if class?
24
- initialization_args.each do |arg|
18
+
19
+ # header
20
+ lines = [
21
+ %Q(# spring rspec),
22
+ %Q(describe #{@parser.name} do)
23
+ ]
24
+
25
+ if @parser.class?
26
+ @parser.initialization_args.each do |arg|
25
27
  lines << %Q(#{indent}let(:#{arg.to_s.sub(/^[&*]/, '')}) {})
26
28
  end
27
29
  lines << %Q()
28
- lines << %Q(#{indent}subject { described_class.new #{initialization_args.join(', ')} })
29
- elsif module?
30
- lines << %Q(#{indent}subject { Class.new { include #{const} }.new })
30
+ lines << %Q(#{indent}subject { described_class.new #{@parser.initialization_args.join(', ')} })
31
+ elsif @parser.module?
32
+ lines << %Q(#{indent}subject { Class.new { include #{@parser.name} }.new })
31
33
  end
34
+
32
35
  lines << %Q()
33
- funcs.reject(&:private?).each do |func|
36
+
37
+ # handle Rails model scopes
38
+ if scope_definitions.any?
39
+ lines << %Q|#{indent}describe 'Scopes' do|
40
+
41
+ scope_definitions.each do |scope_name|
42
+ lines << %Q|#{second_indent}describe '.#{scope_name}' do|
43
+ lines << %Q|#{' ' * 6}xit "should collect TODO" do|
44
+ lines << %Q|#{' ' * 6}end|
45
+ lines << %Q|#{second_indent}end|
46
+ lines << %Q||
47
+ end
48
+
49
+ lines << %Q|#{indent}end|
50
+ lines << %Q()
51
+ end
52
+
53
+ # handle class and instance methods
54
+ @parser.funcs.reject(&:private?).each do |func|
34
55
  lines << %Q(#{indent}describe "#{func.class? ? '.' : '#'}#{func.name}" do)
35
56
  func.assignments.each do |assignment|
36
57
  lines << %Q(#{second_indent}it "#{assignment}" do) << %Q(#{second_indent}end)
@@ -41,9 +62,55 @@ module RSpec
41
62
  end
42
63
  lines << %Q(#{indent}end) << %Q()
43
64
  end
65
+
44
66
  lines << %Q(end) << %Q()
45
- lines
67
+
68
+ return lines
46
69
  end
70
+
71
+ private
72
+
73
+ def scope_definitions
74
+ return @scope_definitions ||= scope_definitions_in_sexp(@parser.sexp)
75
+ end
76
+
77
+ def scope_definitions_in_sexp(sexp_or_symbol)
78
+ is_a_cope_definition = begin
79
+ sexp_or_symbol.respond_to?(:map) && sexp_or_symbol.to_a[2] == :scope
80
+ rescue
81
+ false
82
+ end
83
+
84
+ definitions = if is_a_cope_definition
85
+ begin
86
+ [sexp_or_symbol.to_a[3][1]] #=> scope symbol name
87
+ rescue
88
+ [nil]
89
+ end
90
+ elsif sexp_or_symbol.class == Sexp && sexp_or_symbol.size > 1
91
+ # try looping over and going deeper
92
+ sexp_or_symbol.map do |nested_sexp|
93
+ if nested_sexp.class == Sexp && nested_sexp.size > 1 && %i|class module iter|.include?(nested_sexp[0])
94
+ # there's nested_sexps, go deeper
95
+ nested_sexp.map do |deep_nested_sexp|
96
+ scope_definitions_in_sexp(deep_nested_sexp)
97
+ end
98
+ else
99
+ begin
100
+ [nested_sexp.to_a[3][1]] if nested_sexp.to_a[2] == :scope #=> scope symbol name
101
+ rescue
102
+ [nil]
103
+ end
104
+ end
105
+ end
106
+ else
107
+ # sexp_or_symbol happends to be a symbol, do nothing
108
+ [nil]
109
+ end
110
+
111
+ return definitions.flatten.compact
112
+ end
113
+
47
114
  end
48
115
  end
49
116
  end
@@ -4,18 +4,22 @@ module RSpec
4
4
  attr_reader :file
5
5
 
6
6
  # @param [Pathname] file
7
- def initialize(file)
8
- @file = Pathname.new(file)
7
+ def initialize(file = nil)
8
+ @file = Pathname.new(file) if file
9
9
  end
10
10
 
11
+ # V1, DEPRECATED
11
12
  def perform
12
13
  fail ArgumentError, %Q(File or directory does not exist: "#{file}") if !File.exists?(file) && !File.exists?("#{file}.rb")
14
+
13
15
  ruby_files.each do |ruby_file|
14
16
  rspec_file = Pathname.new(spec_file(ruby_file))
15
17
  spec_file_path = rspec_file.to_s[%r|/(spec/.+)|, 1]
16
- next if rspec_file.exist?.tap { |exists| log "- #{spec_file_path} - already exists", :gray if exists }
17
- spec = generate_spec(ruby_file)
18
+ next if rspec_file.exist?.tap { |exists| log "- #{spec_file_path} - already exists", :puts if exists }
19
+
20
+ spec = generate_spec(Pathname.new(File.expand_path(ruby_file)))
18
21
  next unless spec
22
+
19
23
  log "+ #{spec_file_path}"
20
24
  FileUtils.mkdir_p(rspec_file.parent)
21
25
  File.open(rspec_file, 'wb') do |f|
@@ -24,20 +28,25 @@ module RSpec
24
28
  end
25
29
  end
26
30
 
27
- #
28
- # Private
29
- #
30
-
31
- def generate_spec(ruby_file)
32
- spec = RSpec::Scaffold::Generator.new Pathname.new(File.expand_path(ruby_file))
33
- if spec.funcs.any?
34
- spec.perform
31
+ # @param [String/Pathname] ruby
32
+ def generate_spec(ruby)
33
+ ryan = Ryan.new(ruby)
34
+ if ryan.funcs.any?
35
+ RSpec::Scaffold::Generator.new(ryan).perform
35
36
  else
36
- log "- #{ruby_file} - no methods", :gray
37
+ log "- #{truncate(ruby)} - no methods", :puts
37
38
  nil
38
39
  end
39
40
  rescue => e
40
- log "! #{ruby_file} - #{e.inspect.gsub /^#<|>$/, ''}", :red
41
+ log "! #{truncate(ruby)} - #{e.inspect.gsub /^#<|>$/, ''}\n#{e.backtrace.take(10)}", :red
42
+ end
43
+
44
+ #
45
+ # Private
46
+ #
47
+
48
+ def truncate(str)
49
+ str.to_s.scan(/.+/).take(2).tap { |x| x[1..-1].each { |i| i[0..-1] = '...' } }.join
41
50
  end
42
51
 
43
52
  def ruby_files
@@ -70,7 +79,7 @@ module RSpec
70
79
  end
71
80
 
72
81
  def log(msg = nil, color = :green)
73
- HighLine.new.say %Q( <%= color('#{msg}', :#{color}) %>)
82
+ return RSpec::Scaffold.log(msg, color)
74
83
  end
75
84
  end
76
85
  end
@@ -0,0 +1,29 @@
1
+ module RSpec
2
+ module Scaffold
3
+ class SpecLocationBuilder
4
+ # manages inferring spec file locations for code files.
5
+
6
+ # @param [Pathname] project_root
7
+ # @param [Pathname] file_path
8
+ def initialize(project_root, file_path)
9
+ @project_root = Pathname(project_root)
10
+ @file_path = Pathname(file_path)
11
+ @relative_file_path = (@file_path.relative? ? Pathname(@file_path) : ( Pathname(@file_path.to_s.sub(@project_root.to_s, '')) ))
12
+ end
13
+
14
+ # RSpec::Scaffold::SpecLocationBuilder.new("/home/dev/projects/some_app", "/app/models/user.rb").spec_location
15
+ def spec_location
16
+ # for default rails app dir code
17
+ @spec_location ||= if @relative_file_path.to_s[%r'\A/?app/']
18
+ # replace first 'app/' with 'spec/' and change ending a bit
19
+ @project_root.join(@relative_file_path.sub(%r'\A/?app/', 'spec/'))
20
+ else
21
+ @project_root.join("spec").join(@relative_file_path.to_s.sub(%r'\A/', ''))
22
+ end.sub(%r'\.rb\z', '_spec.rb')
23
+
24
+ return @spec_location
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module Scaffold
3
- VERSION = "1.0.0".freeze
3
+ VERSION = "2.0.0.beta1".freeze
4
4
  end
5
5
  end
@@ -1,23 +1,79 @@
1
1
  require "pathname"
2
2
  require "delegate"
3
- require "rspec"
3
+ #require "rspec"
4
4
  require "ryan"
5
- require "highline"
5
+ require "luks"
6
+ require 'pry'
6
7
 
7
8
  module RSpec
8
9
  module Scaffold
9
- autoload :Version, "rspec/scaffold/version"
10
- autoload :Runner, "rspec/scaffold/runner"
11
- autoload :Generator, "rspec/scaffold/generator"
10
+ autoload :Cli, "rspec/scaffold/cli"
12
11
  autoload :ConditionExhibit, "rspec/scaffold/condition_exhibit"
12
+ autoload :FileWriter, "rspec/scaffold/file_writer"
13
+ autoload :Generator, "rspec/scaffold/generator"
14
+ autoload :DirExpander, "rspec/scaffold/dir_expander"
15
+ autoload :Runner, "rspec/scaffold/runner"
16
+ autoload :SpecLocationBuilder, "rspec/scaffold/spec_location_builder"
17
+ autoload :Version, "rspec/scaffold/version"
13
18
 
19
+ # loads gem's rake tasks in main app
20
+ # Dir["#{RSpec::Scaffold.root}" + "lib/rspec/scaffold/tasks/**/*.rake"].each { |ext| load ext } if defined?(Rake)
21
+
22
+ # DEPRECATED
14
23
  def self.helper_file
15
- if defined?(::Rails) && RSpec::Core::Version::STRING.to_s >= '3'
24
+ if Object.const_defined?("Rails") && RSpec::Core::Version::STRING.to_s >= '3'
16
25
  'rails_helper'
17
26
  else
18
27
  'spec_helper'
19
28
  end
20
29
  end
30
+
31
+ # RSpec::Scaffold.testify_file(filepath)
32
+ # mode = :to_file, :to_text
33
+ def self.testify_file(filepath, mode=:to_text, out: nil)
34
+ begin
35
+ test_scaffold = RSpec::Scaffold::Generator.new(Ryan.new(filepath)).perform
36
+ rescue => e
37
+ RSpec::Scaffold.log("- parse error in '#{filepath}': #{e.message}", :red)
38
+ return nil
39
+ end
40
+
41
+ scaffold_text = test_scaffold.join("\n")
42
+
43
+ if out # pre-empts :mode and infers :to_file
44
+ return RSpec::Scaffold::FileWriter.new(out, scaffold_text).write!
45
+ else
46
+ case mode
47
+ when :to_file
48
+ output_filename = filepath.sub(%r'\.rb\z', '_spec.rb')
49
+ return RSpec::Scaffold::FileWriter.new(output_filename, scaffold_text).write!
50
+ when :to_text
51
+ return scaffold_text
52
+ else
53
+ raise("Unrecognized mode")
54
+ end
55
+ end
56
+ end
57
+
58
+ # RSpec::Scaffold.testify_text(text)
59
+ def self.testify_text(text)
60
+ test_scaffold = RSpec::Scaffold::Generator.new(Ryan.new(text)).perform
61
+ return test_scaffold.join("\n")
62
+ rescue => e
63
+ message = "parse error: #{e.message}"
64
+ RSpec::Scaffold.log(message, :red)
65
+ return message
66
+ end
67
+
68
+ def self.root
69
+ Pathname.new File.expand_path('../../..', __FILE__)
70
+ end
71
+
72
+ # refactored from runner for more general use
73
+ def self.log(msg = nil, color = :green)
74
+ return send(color, " #{msg}")
75
+ end
76
+
21
77
  end
22
78
  end
23
79
 
@@ -15,14 +15,20 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
17
  spec.bindir = 'exe'
18
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.executables = ["rspec-scaffold"] # NB, as of bundler 0.12, executables *must* be in /exe
19
19
  spec.require_paths = ["lib"]
20
20
  spec.license = 'MIT'
21
21
 
22
+ spec.required_ruby_version = '>= 2.0.0'
23
+
22
24
  spec.add_dependency 'highline', '~> 1.6'
23
- spec.add_dependency 'ryan', '~> 1.0'
25
+ spec.add_dependency 'luks'# , '~> 1.6'
26
+ spec.add_dependency 'ryan', '~> 1.1.0'
24
27
 
25
28
  spec.add_development_dependency "bundler", "~> 1.10"
26
29
  spec.add_development_dependency "rake", "~> 10.0"
27
30
  spec.add_development_dependency "rspec", ">= 3.2", "< 4"
31
+ spec.add_development_dependency "pry", "~> 0.10.4"
32
+ spec.add_development_dependency "simplecov", "~> 0.13.0"
33
+ spec.add_development_dependency "fakefs", "~> 0.11.0" # fakes filesystem, useful for testing file outputs.
28
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-01-28 00:00:00.000000000 Z
11
+ date: 2017-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -24,20 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: luks
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: ryan
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '1.0'
47
+ version: 1.1.0
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '1.0'
54
+ version: 1.1.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,27 +100,77 @@ dependencies:
86
100
  - - "<"
87
101
  - !ruby/object:Gem::Version
88
102
  version: '4'
103
+ - !ruby/object:Gem::Dependency
104
+ name: pry
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.10.4
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.10.4
117
+ - !ruby/object:Gem::Dependency
118
+ name: simplecov
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 0.13.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 0.13.0
131
+ - !ruby/object:Gem::Dependency
132
+ name: fakefs
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 0.11.0
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: 0.11.0
89
145
  description: Generates RSpec scaffolding for conditions and ivar assignments
90
146
  email:
91
147
  - arebuckley@gmail.com
92
- executables: []
148
+ executables:
149
+ - rspec-scaffold
93
150
  extensions: []
94
151
  extra_rdoc_files: []
95
152
  files:
96
153
  - ".gitignore"
154
+ - ".rspec"
97
155
  - ".ruby-gemset"
98
156
  - ".ruby-version"
99
157
  - ".travis.yml"
158
+ - CHANGELOG.md
100
159
  - Gemfile
101
160
  - LICENSE.md
102
161
  - README.md
103
162
  - Rakefile
104
163
  - bin/console
105
164
  - bin/setup
165
+ - exe/rspec-scaffold
106
166
  - lib/rspec/scaffold.rb
167
+ - lib/rspec/scaffold/cli.rb
107
168
  - lib/rspec/scaffold/condition_exhibit.rb
169
+ - lib/rspec/scaffold/dir_expander.rb
170
+ - lib/rspec/scaffold/file_writer.rb
108
171
  - lib/rspec/scaffold/generator.rb
109
172
  - lib/rspec/scaffold/runner.rb
173
+ - lib/rspec/scaffold/spec_location_builder.rb
110
174
  - lib/rspec/scaffold/tasks/scaffold.rake
111
175
  - lib/rspec/scaffold/version.rb
112
176
  - rspec-scaffold.gemspec
@@ -122,12 +186,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
186
  requirements:
123
187
  - - ">="
124
188
  - !ruby/object:Gem::Version
125
- version: '0'
189
+ version: 2.0.0
126
190
  required_rubygems_version: !ruby/object:Gem::Requirement
127
191
  requirements:
128
- - - ">="
192
+ - - ">"
129
193
  - !ruby/object:Gem::Version
130
- version: '0'
194
+ version: 1.3.1
131
195
  requirements: []
132
196
  rubyforge_project:
133
197
  rubygems_version: 2.4.8