rspec-scaffold 1.0.0 → 2.0.0

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
- SHA1:
3
- metadata.gz: 51b15bd17f15c8ded617f732b63b29b839091124
4
- data.tar.gz: 5cf8d3cd2aa8b584667c7ac49833682b378b1075
2
+ SHA256:
3
+ metadata.gz: 9a2a7871e4122aa2bbb9b421f6ec0e9c052de7a560550b3117db1452487a3def
4
+ data.tar.gz: 8a4a4ae6cd7246bb3c6621296c4d6f8a0ca4f38285924dea526d8c313112df83
5
5
  SHA512:
6
- metadata.gz: 04bbf347bcf64103ccfa680ee78514d1d455b9d698d51dec3272413513074a9aaf5204851e1cda559fc27404391134a5233fdf8a717d8a9e11e7fbd3e62c291d
7
- data.tar.gz: 07f52b0f041b1ce612627ac453c35d18d538ba9bf20d6801aeea1a441d8ab1b95a4b206d19700a26f39fc401c6fab82006f737d96744b1d8bb17f66547d26ea2
6
+ metadata.gz: 59f66d34054bbb192f1d9e20c30e2af2c2570e0c105b63f8825c843fb8db052fc70903778a1b8d8e4ee52a8f45e85aa6c0b118655756e7d10eaa2588ef081aa6
7
+ data.tar.gz: c6cbe0d841a9ca2466ebff5f6a74340a020bd3810eb3a5495556facbba74c60d915e0ee783a3b2d4d87a3b65eff5eca7f3323f7225a8ba3e67f445b467e16e1e
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /tmp/
10
10
  *.gem
11
11
  .byebug_history
12
+ .idea
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.2.2
1
+ ruby-2.7.8
data/.travis.yml CHANGED
@@ -1,7 +1,4 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.2.1
5
- - 2.2.2
6
- - 2.2.3
7
- before_install: gem install bundler -v 1.10.4
3
+ - 2.7.8
4
+ before_install: gem install bundler
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 [![Gem Version](https://badge.fury.io/rb/rspec-scaffold.svg)](https://badge.fury.io/rb/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.
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require 'rake/release'
1
2
  require 'rspec/core/rake_task'
2
3
 
3
4
  RSpec::Core::RakeTask.new(:spec) do |config|
@@ -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".freeze
4
4
  end
5
5
  end
@@ -1,23 +1,78 @@
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
6
 
7
7
  module RSpec
8
8
  module Scaffold
9
- autoload :Version, "rspec/scaffold/version"
10
- autoload :Runner, "rspec/scaffold/runner"
11
- autoload :Generator, "rspec/scaffold/generator"
9
+ autoload :Cli, "rspec/scaffold/cli"
12
10
  autoload :ConditionExhibit, "rspec/scaffold/condition_exhibit"
11
+ autoload :FileWriter, "rspec/scaffold/file_writer"
12
+ autoload :Generator, "rspec/scaffold/generator"
13
+ autoload :DirExpander, "rspec/scaffold/dir_expander"
14
+ autoload :Runner, "rspec/scaffold/runner"
15
+ autoload :SpecLocationBuilder, "rspec/scaffold/spec_location_builder"
16
+ autoload :Version, "rspec/scaffold/version"
13
17
 
18
+ # loads gem's rake tasks in main app
19
+ # Dir["#{RSpec::Scaffold.root}" + "lib/rspec/scaffold/tasks/**/*.rake"].each { |ext| load ext } if defined?(Rake)
20
+
21
+ # DEPRECATED
14
22
  def self.helper_file
15
- if defined?(::Rails) && RSpec::Core::Version::STRING.to_s >= '3'
23
+ if Object.const_defined?("Rails") && RSpec::Core::Version::STRING.to_s >= '3'
16
24
  'rails_helper'
17
25
  else
18
26
  'spec_helper'
19
27
  end
20
28
  end
29
+
30
+ # RSpec::Scaffold.testify_file(filepath)
31
+ # mode = :to_file, :to_text
32
+ def self.testify_file(filepath, mode=:to_text, out: nil)
33
+ begin
34
+ test_scaffold = RSpec::Scaffold::Generator.new(Ryan.new(filepath)).perform
35
+ rescue => e
36
+ RSpec::Scaffold.log("- parse error in '#{filepath}': #{e.message}", :red)
37
+ return nil
38
+ end
39
+
40
+ scaffold_text = test_scaffold.join("\n")
41
+
42
+ if out # pre-empts :mode and infers :to_file
43
+ return RSpec::Scaffold::FileWriter.new(out, scaffold_text).write!
44
+ else
45
+ case mode
46
+ when :to_file
47
+ output_filename = filepath.sub(%r'\.rb\z', '_spec.rb')
48
+ return RSpec::Scaffold::FileWriter.new(output_filename, scaffold_text).write!
49
+ when :to_text
50
+ return scaffold_text
51
+ else
52
+ raise("Unrecognized mode")
53
+ end
54
+ end
55
+ end
56
+
57
+ # RSpec::Scaffold.testify_text(text)
58
+ def self.testify_text(text)
59
+ test_scaffold = RSpec::Scaffold::Generator.new(Ryan.new(text)).perform
60
+ return test_scaffold.join("\n")
61
+ rescue => e
62
+ message = "parse error: #{e.message}"
63
+ RSpec::Scaffold.log(message, :red)
64
+ return message
65
+ end
66
+
67
+ def self.root
68
+ Pathname.new File.expand_path('../../..', __FILE__)
69
+ end
70
+
71
+ # refactored from runner for more general use
72
+ def self.log(msg = nil, color = :green)
73
+ return send(color, " #{msg}")
74
+ end
75
+
21
76
  end
22
77
  end
23
78
 
@@ -4,25 +4,30 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'rspec/scaffold/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "rspec-scaffold"
8
- spec.version = RSpec::Scaffold::VERSION
9
- spec.authors = ["Ryan Buckley"]
10
- spec.email = ["arebuckley@gmail.com"]
7
+ spec.name = "rspec-scaffold"
8
+ spec.version = RSpec::Scaffold::VERSION
9
+ spec.authors = ["Ryan Buckley"]
10
+ spec.email = ["arebuckley@gmail.com"]
11
11
 
12
- spec.summary = %q{Generates RSpec scaffolding for existing code}
13
- spec.description = %q{Generates RSpec scaffolding for conditions and ivar assignments}
14
- spec.homepage = "https://github.com/ridiculous/rspec-scaffold"
12
+ spec.summary = %q{Generates RSpec scaffolding for existing code}
13
+ spec.description = %q{Generates test files based on your codes logic, setting up the initialization args and nested context blocks}
14
+ spec.homepage = "https://github.com/ridiculous/rspec-scaffold"
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.2.1'
24
27
 
25
- spec.add_development_dependency "bundler", "~> 1.10"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "rspec", ">= 3.2", "< 4"
28
+ spec.add_development_dependency "bundler", "~> 2.0"
29
+ spec.add_development_dependency "rake", "~> 13.0"
30
+ spec.add_development_dependency "rspec", ">= 3.2", "< 5"
31
+ spec.add_development_dependency "fakefs", "~> 0.11.0" # fakes filesystem, useful for testing file outputs.
32
+ spec.add_development_dependency "rake-release", "~> 1.3.0"
28
33
  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
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-01-28 00:00:00.000000000 Z
11
+ date: 2023-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -24,48 +24,62 @@ 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.2.1
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.2.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.10'
61
+ version: '2.0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.10'
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '13.0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '13.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -75,7 +89,7 @@ dependencies:
75
89
  version: '3.2'
76
90
  - - "<"
77
91
  - !ruby/object:Gem::Version
78
- version: '4'
92
+ version: '5'
79
93
  type: :development
80
94
  prerelease: false
81
95
  version_requirements: !ruby/object:Gem::Requirement
@@ -85,28 +99,65 @@ dependencies:
85
99
  version: '3.2'
86
100
  - - "<"
87
101
  - !ruby/object:Gem::Version
88
- version: '4'
89
- description: Generates RSpec scaffolding for conditions and ivar assignments
102
+ version: '5'
103
+ - !ruby/object:Gem::Dependency
104
+ name: fakefs
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.11.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.11.0
117
+ - !ruby/object:Gem::Dependency
118
+ name: rake-release
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 1.3.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 1.3.0
131
+ description: Generates test files based on your codes logic, setting up the initialization
132
+ args and nested context blocks
90
133
  email:
91
134
  - arebuckley@gmail.com
92
- executables: []
135
+ executables:
136
+ - rspec-scaffold
93
137
  extensions: []
94
138
  extra_rdoc_files: []
95
139
  files:
96
140
  - ".gitignore"
141
+ - ".rspec"
97
142
  - ".ruby-gemset"
98
143
  - ".ruby-version"
99
144
  - ".travis.yml"
145
+ - CHANGELOG.md
100
146
  - Gemfile
101
147
  - LICENSE.md
102
148
  - README.md
103
149
  - Rakefile
104
150
  - bin/console
105
151
  - bin/setup
152
+ - exe/rspec-scaffold
106
153
  - lib/rspec/scaffold.rb
154
+ - lib/rspec/scaffold/cli.rb
107
155
  - lib/rspec/scaffold/condition_exhibit.rb
156
+ - lib/rspec/scaffold/dir_expander.rb
157
+ - lib/rspec/scaffold/file_writer.rb
108
158
  - lib/rspec/scaffold/generator.rb
109
159
  - lib/rspec/scaffold/runner.rb
160
+ - lib/rspec/scaffold/spec_location_builder.rb
110
161
  - lib/rspec/scaffold/tasks/scaffold.rake
111
162
  - lib/rspec/scaffold/version.rb
112
163
  - rspec-scaffold.gemspec
@@ -114,7 +165,7 @@ homepage: https://github.com/ridiculous/rspec-scaffold
114
165
  licenses:
115
166
  - MIT
116
167
  metadata: {}
117
- post_install_message:
168
+ post_install_message:
118
169
  rdoc_options: []
119
170
  require_paths:
120
171
  - lib
@@ -122,16 +173,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
173
  requirements:
123
174
  - - ">="
124
175
  - !ruby/object:Gem::Version
125
- version: '0'
176
+ version: 2.0.0
126
177
  required_rubygems_version: !ruby/object:Gem::Requirement
127
178
  requirements:
128
179
  - - ">="
129
180
  - !ruby/object:Gem::Version
130
181
  version: '0'
131
182
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 2.4.8
134
- signing_key:
183
+ rubygems_version: 3.1.6
184
+ signing_key:
135
185
  specification_version: 4
136
186
  summary: Generates RSpec scaffolding for existing code
137
187
  test_files: []