drg 0.15.6 → 0.16.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
2
  SHA1:
3
- metadata.gz: 7d07718561b63d248e436961dca545007b488753
4
- data.tar.gz: f418bac5e2c6bb10e45d7193d11dc24d4c7d4d65
3
+ metadata.gz: f3ec2da36e33e6a4ba09189233dd40b01401b1e7
4
+ data.tar.gz: 6e95adec97a178eedff8e6377ee4be64cdf3fd7d
5
5
  SHA512:
6
- metadata.gz: 8aeb1467b533b35c6507d18aebbd4163002e5728ad7d90e4945c6ac393428c7a5903b24a85cfdf29e55a88f0796c693b6a4ccf3afd0f84d51d45a2c4402bf622
7
- data.tar.gz: c5412c09381ca920633349490e1bde537a825e0e94711fda7563ae054441e6b1209cceee17b42949f68d8c432e004d6ddefcdd3ffd0fa8916ddce458f0400309
6
+ metadata.gz: 0cec841fbfa30623d4edc7e534be902ebe919b4d9ce927822758f39cc6eea3ed411ca9c281f51b1da95b55669a2995405248742169de35d91051f022c9ae4210
7
+ data.tar.gz: 99cb20b249bed5bc2a089248fa88e2ece5c976f9618e34fceb7f635e3ff772de2fb971b705edfc7f0e751408a3058b615315722daee465bde781f5f204ecfc61
data/README.md CHANGED
@@ -1,13 +1,9 @@
1
1
  # DRG
2
+ [![Code Climate](https://codeclimate.com/github/ridiculous/drg/badges/gpa.svg)](https://codeclimate.com/github/ridiculous/drg)
2
3
  [![Gem Version](https://badge.fury.io/rb/drg.svg)](http://badge.fury.io/rb/drg)
3
4
 
4
- A suite of rake tasks to help you test and manage your project.
5
-
6
- The `drg:pin` suite provides enhanced dependency management with Bundler. You can pin Gem versions to the current or the next
7
- available minor, major or patch level version.
8
-
9
- The `drg:spec` task generates RSpec scaffolding for existing code. This helps bootstrap your tests and guide you in what
10
- you should be testing.
5
+ A Ruby utility to help automate dependency management using Bundler. You can pin Gem versions to the current or the next
6
+ available level.
11
7
 
12
8
  ## Requirements
13
9
 
@@ -22,7 +18,6 @@ gem 'drg'
22
18
  ## Tasks
23
19
 
24
20
  ```bash
25
- rake drg:spec
26
21
  rake drg:pin
27
22
  rake drg:pin:major
28
23
  rake drg:pin:minor
@@ -33,58 +28,6 @@ rake drg:pin:minor_latest
33
28
  rake drg:unpin
34
29
  ```
35
30
 
36
- ### drg:spec
37
-
38
- Generates RSpec scaffolding for existing code. Pass a file or directory and DRG will generate spec files for each:
39
-
40
- ```bash
41
- rake drg:spec[app/controllers]
42
- rake drg:spec[app/models/user.rb]
43
- ```
44
-
45
- This task looks at your code's methods and breaks down their conditions into RSpec `context`s. For example:
46
-
47
- Given this file:
48
-
49
- ```ruby
50
- # app/models/ability.rb
51
- class Ability
52
- include CanCan::Ability
53
-
54
- def initialize(user)
55
- if user.admin?
56
- can :manage, :all
57
- else
58
- can :read, :all
59
- can :update, User do |u|
60
- u.id == user.id
61
- end
62
- end
63
- end
64
- end
65
- ```
66
-
67
- It will generate this spec:
68
- ```ruby
69
- require "spec_helper"
70
-
71
- describe Ability do
72
- let(:user) {}
73
-
74
- subject { described_class.new user }
75
-
76
- describe "#initialize" do
77
- context "when user.admin?" do
78
- before {}
79
- end
80
-
81
- context "unless user.admin?" do
82
- before {}
83
- end
84
- end
85
- end
86
- ```
87
-
88
31
  ### drg:pin
89
32
 
90
33
  DRG really wants to help you manage your project's gems. But DRG doesn't want to replace Bundler. Instead, we want to build on
@@ -198,6 +141,32 @@ Remove the versions from your Gemfile. A clean start!
198
141
  rake drg:unpin
199
142
  ```
200
143
 
144
+ ### Automation
145
+
146
+ I use the following bash script to update all gems to the latest [major|minor|patch] version, run all tests and then add
147
+ the result if the specs pass or rollback the changes if they fail.
148
+
149
+ ```bash
150
+ #!/bin/bash
151
+ git add Gemfile
152
+ for cmd in $@; do
153
+ echo " * Updating $cmd versions"
154
+ bundle exec rake drg:pin:${cmd}_latest
155
+ bundle update
156
+ bundle exec rspec . -t ~js
157
+ if [ $? -eq 0 ]
158
+ then
159
+ echo " * Tests passed after updating $cmd versions. Adding Gemfile ..."
160
+ git add Gemfile*
161
+ else
162
+ echo " * Tests failed after updating $cmd versions. Reverting change to Gemfile ..." >&2
163
+ git checkout -- Gemfile*
164
+ bundle
165
+ exit 1
166
+ fi
167
+ done
168
+ ```
169
+
201
170
  ### Skipping gems
202
171
 
203
172
  You can tell drg to ignore gems by adding an inline comment with @drg (skip|ignore|frozen)
@@ -206,6 +175,10 @@ You can tell drg to ignore gems by adding an inline comment with @drg (skip|igno
206
175
  gem 'name' # @drg skip
207
176
  ```
208
177
 
178
+ ## Changes
179
+
180
+ Looking for `drg:spec` that does RSpec scaffolding? It's been moved to it's own gem: [rspec-scaffold](https://github.com/ridiculous/rspec-scaffold)
181
+
209
182
  ## Development
210
183
 
211
184
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests.
data/drg.gemspec CHANGED
@@ -8,18 +8,16 @@ Gem::Specification.new do |spec|
8
8
  spec.version = DRG::VERSION
9
9
  spec.authors = ["Ryan Buckley"]
10
10
  spec.email = ["arebuckley@gmail.com"]
11
- spec.summary = %q{A suite of rake tasks to help you test and manage your project}
12
- spec.description = %q{A suite of rake tasks that provide enhanced dependency management and rspec scaffolding}
11
+ spec.summary = %q{DRG that Gemfile! The missing bundler extension}
12
+ spec.description = %q{DRG that Gemfile! The missing bundler extension. Gem version automation with Bundler}
13
13
  spec.homepage = "https://github.com/ridiculous/drg"
14
14
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
15
  spec.executables = []
16
16
  spec.require_paths = ["lib"]
17
17
 
18
- spec.add_dependency 'ruby_parser', '>= 3.7.0', '< 4.0.0'
19
18
  spec.add_dependency 'bundler', '~> 1.10'
20
19
  spec.add_dependency 'duck_puncher', '>= 2.0.0', '<= 3.0.0'
21
20
  spec.add_dependency 'highline', '~> 1.7'
22
- spec.add_dependency 'ruby2ruby', '~> 2.2'
23
21
 
24
22
  spec.add_development_dependency 'rake', '~> 10.0'
25
23
  spec.add_development_dependency 'rspec', '>= 3.2', '< 4'
data/lib/drg/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DRG
2
- VERSION = '0.15.6'.freeze
2
+ VERSION = '0.16.0'.freeze
3
3
  end
data/lib/drg.rb CHANGED
@@ -11,9 +11,6 @@ module DRG
11
11
  DuckPuncher.punch! :Object
12
12
 
13
13
  autoload :Tasks, 'drg/tasks'
14
- autoload :Ruby, 'drg/ruby'
15
- autoload :Decorators, 'drg/decorators'
16
- autoload :Spec, 'drg/spec'
17
14
  end
18
15
 
19
16
  load 'tasks/drg.rake'
data/lib/tasks/drg.rake CHANGED
@@ -46,13 +46,4 @@ namespace :drg do
46
46
  task latest_minor: :minor_latest
47
47
  task latest_patch: :patch_latest
48
48
  end
49
-
50
- task :spec, [:file_name] => :environment do |_, args|
51
- DRG::Tasks::SpecRunner.new(args.file_name).perform
52
- end
53
-
54
- unless defined?(Rails)
55
- task :environment do
56
- end
57
- end
58
49
  end
metadata CHANGED
@@ -1,35 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.6
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-28 00:00:00.000000000 Z
11
+ date: 2015-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: ruby_parser
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 3.7.0
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: 4.0.0
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 3.7.0
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: 4.0.0
33
13
  - !ruby/object:Gem::Dependency
34
14
  name: bundler
35
15
  requirement: !ruby/object:Gem::Requirement
@@ -78,20 +58,6 @@ dependencies:
78
58
  - - "~>"
79
59
  - !ruby/object:Gem::Version
80
60
  version: '1.7'
81
- - !ruby/object:Gem::Dependency
82
- name: ruby2ruby
83
- requirement: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - "~>"
86
- - !ruby/object:Gem::Version
87
- version: '2.2'
88
- type: :runtime
89
- prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - "~>"
93
- - !ruby/object:Gem::Version
94
- version: '2.2'
95
61
  - !ruby/object:Gem::Dependency
96
62
  name: rake
97
63
  requirement: !ruby/object:Gem::Requirement
@@ -126,8 +92,8 @@ dependencies:
126
92
  - - "<"
127
93
  - !ruby/object:Gem::Version
128
94
  version: '4'
129
- description: A suite of rake tasks that provide enhanced dependency management and
130
- rspec scaffolding
95
+ description: DRG that Gemfile! The missing bundler extension. Gem version automation
96
+ with Bundler
131
97
  email:
132
98
  - arebuckley@gmail.com
133
99
  executables: []
@@ -145,23 +111,12 @@ files:
145
111
  - bin/setup
146
112
  - drg.gemspec
147
113
  - lib/drg.rb
148
- - lib/drg/decorators.rb
149
- - lib/drg/decorators/sexp_decorator.rb
150
- - lib/drg/ruby.rb
151
- - lib/drg/ruby/assignment.rb
152
- - lib/drg/ruby/class_func.rb
153
- - lib/drg/ruby/condition.rb
154
- - lib/drg/ruby/const.rb
155
- - lib/drg/ruby/func.rb
156
- - lib/drg/ruby/instance_func.rb
157
- - lib/drg/spec.rb
158
114
  - lib/drg/tasks.rb
159
115
  - lib/drg/tasks/active_pinner.rb
160
116
  - lib/drg/tasks/gemfile.rb
161
117
  - lib/drg/tasks/gemfile_line.rb
162
118
  - lib/drg/tasks/log.rb
163
119
  - lib/drg/tasks/pinner.rb
164
- - lib/drg/tasks/spec_runner.rb
165
120
  - lib/drg/tasks/updater.rb
166
121
  - lib/drg/version.rb
167
122
  - lib/tasks/drg.rake
@@ -187,5 +142,5 @@ rubyforge_project:
187
142
  rubygems_version: 2.4.6
188
143
  signing_key:
189
144
  specification_version: 4
190
- summary: A suite of rake tasks to help you test and manage your project
145
+ summary: DRG that Gemfile! The missing bundler extension
191
146
  test_files: []
@@ -1,20 +0,0 @@
1
- class DRG::Decorators::SexpDecorator < DelegateClass(Sexp)
2
- def each_sexp_condition
3
- return enum_for(__method__) unless block_given?
4
- yielded = []
5
- each_sexp do |exp|
6
- if exp.first == :if
7
- yield exp
8
- yielded << exp
9
- else
10
- nested_sexp = exp.enum_for(:deep_each).select { |s| s.first == :if }
11
- nested_sexp.each do |sexp|
12
- if yielded.find { |x| x.object_id == sexp.object_id or x.enum_for(:deep_each).find { |xx| xx.object_id == sexp.object_id } }.nil?
13
- yield sexp
14
- yielded << sexp
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,3 +0,0 @@
1
- module DRG::Decorators
2
- autoload :SexpDecorator, 'drg/decorators/sexp_decorator'
3
- end
@@ -1,25 +0,0 @@
1
- module DRG
2
- class Ruby
3
- class Assignment
4
- attr_reader :sexp
5
-
6
- def initialize(sexp)
7
- @sexp = sexp
8
- end
9
-
10
- def to_s
11
- "assigns #{ivar_name}"
12
- end
13
-
14
- # @example s(:iasgn, :@duder, s(:if, ...)
15
- # @example s(:op_asgn_or, s(:ivar, :@report), ...)
16
- def ivar_name
17
- if sexp.first == :iasgn
18
- sexp[1]
19
- elsif sexp.first == :op_asgn_or
20
- sexp[1][1]
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,13 +0,0 @@
1
- class DRG::Ruby::ClassFunc < DRG::Ruby::Func
2
- def name
3
- sexp[2]
4
- end
5
-
6
- def args
7
- map_args(sexp[3]) if sexp[3].first == :args
8
- end
9
-
10
- def class?
11
- true
12
- end
13
- end
@@ -1,101 +0,0 @@
1
- require 'ruby2ruby'
2
-
3
- class DRG::Ruby::Condition
4
-
5
- module SetComparison
6
- def eql?(other)
7
- hash == other.hash
8
- end
9
-
10
- def hash
11
- sexp.object_id
12
- end
13
- end
14
-
15
- include SetComparison
16
-
17
- attr_reader :statement, :nested_conditions, :sexp, :parts, :unless_found
18
-
19
- def initialize(sexp)
20
- @sexp = sexp
21
- @statement = Ruby2Ruby.new.process(sexp.deep_clone)
22
- @nested_conditions = create_nested_conditions
23
- @parts = load_parts
24
- end
25
-
26
- def short_statement
27
- "#{'unless ' if sexp[2].nil?}#{Ruby2Ruby.new.process(sexp[1].clone!)}"
28
- end
29
-
30
- def return_value
31
- edit Ruby2Ruby.new.process(if_return_value.clone!)
32
- end
33
-
34
- def else_return_value
35
- edit Ruby2Ruby.new.process(find_else_return_val.clone!)
36
- end
37
-
38
- def if_return_value
39
- if sexp[2].nil?
40
- sexp.last
41
- elsif sexp[2].first == :if
42
- nil
43
- elsif sexp[2].first == :block
44
- sexp[2].last
45
- elsif sexp[2].first == :rescue
46
- sexp[2][1].last
47
- else
48
- sexp[2]
49
- end
50
- end
51
-
52
- def find_else_return_val
53
- if sexp.compact[3].nil?
54
- nil
55
- elsif sexp[3].first == :block
56
- sexp[3].last
57
- elsif sexp[3].first == :if
58
- nil
59
- else
60
- sexp[3]
61
- end
62
- end
63
-
64
- def edit(txt)
65
- txt = txt.to_s
66
- txt.sub! /^return\b/, 'returns'
67
- txt.sub! /^returns\s*$/, 'returns nil'
68
- if txt.include?(' = ')
69
- txt = "assigns #{txt}"
70
- elsif !txt.empty? and txt !~ /^return/
71
- txt = "returns #{txt.strip}"
72
- end
73
- txt.strip
74
- end
75
-
76
- #
77
- # Private
78
- #
79
-
80
- # @description handles elsif
81
- def load_parts
82
- condition_parts = Set.new
83
- sexp.each_sexp do |s|
84
- if s.first == :if
85
- condition_parts << self.class.new(s)
86
- end
87
- end
88
- condition_parts.to_a
89
- end
90
-
91
- def create_nested_conditions
92
- nc = Set.new
93
- s = sexp.drop(1)
94
- s.flatten.include?(:if) && s.deep_each do |exp|
95
- DRG::Decorators::SexpDecorator.new(exp).each_sexp_condition do |node|
96
- nc << self.class.new(node)
97
- end
98
- end
99
- nc.to_a
100
- end
101
- end
@@ -1,100 +0,0 @@
1
- require 'ruby_parser'
2
-
3
- class DRG::Ruby::Const
4
- CLASS_MOD_DEFS = { class: :class, module: :module }
5
- CONSTANT_DEFS = { cdecl: :class }.merge CLASS_MOD_DEFS
6
-
7
- attr_reader :sexp
8
-
9
- # @param [Sexp] sexp
10
- def initialize(sexp)
11
- sexp = sexp[2] if sexp[0] == :block
12
- @sexp = sexp
13
- end
14
-
15
- # s(:module, :Admin, s(:class, :Super, nil, s(:class, :UsersController, s(:colon3, :ApplicationController), s(:defn, :name, s(:args)
16
- # s(:class, :Report, nil, s(:cdecl, :DEFAULT_TZ, s(:str, "UTC")), s(:defs, s(:self), :enqueue,
17
- def name(sexp = @sexp, list = [])
18
- sexp = Array(sexp)
19
- if sexp[1].is_a?(Sexp) && sexp[1][0] == :colon2
20
- parts = sexp[1].to_a.flatten
21
- list.concat parts.drop(parts.size / 2)
22
- elsif CONSTANT_DEFS.key?(sexp[0])
23
- list << sexp[1].to_s
24
- # recurse unless the second element is nil, which indicates it's the end of the class/module definition
25
- if !sexp[2].nil? || (sexp[3].is_a?(Sexp) and CLASS_MOD_DEFS.key?(sexp[3].first))
26
- name(sexp.compact[2], list)
27
- end
28
- end
29
- list.join('::')
30
- end
31
-
32
- def type(sexp = @sexp, val = nil)
33
- sexp = Array(sexp)
34
- if sexp[1].is_a?(Sexp) && sexp[1][0] == :colon2
35
- val = sexp[0]
36
- elsif CONSTANT_DEFS.key?(sexp[0])
37
- val = type(sexp.compact[2], sexp[0])
38
- end
39
- CONSTANT_DEFS[val]
40
- end
41
-
42
- def initialization_args
43
- funcs.find(-> { OpenStruct.new }) { |func| func.name == :initialize }.args.to_a
44
- end
45
-
46
- def func_by_name(name_as_symbol)
47
- funcs.find { |x| x.name == name_as_symbol }
48
- end
49
-
50
- def funcs
51
- @funcs ||= load_funcs.flatten
52
- end
53
-
54
- def class?
55
- type == :class
56
- end
57
-
58
- def module?
59
- type == :module
60
- end
61
-
62
- # @todo
63
- def instance_vars
64
- end
65
-
66
- # @todo
67
- def class_vars
68
- end
69
-
70
- private
71
-
72
- def load_funcs(sexp_list = sexp)
73
- marked_private = false
74
- sexp_list.map { |node|
75
- next unless node.is_a?(Sexp)
76
- case node.first
77
- when :defn
78
- DRG::Ruby::InstanceFunc.new(node, marked_private)
79
- when :defs
80
- DRG::Ruby::ClassFunc.new(node, marked_private)
81
- when :call
82
- marked_private ||= node[2] == :private
83
- nil
84
- when ->(name) { CONSTANT_DEFS.key?(name) }
85
- # @note handle diz kind stuff:
86
- # s(:class, :VerificationCode, nil, s(:defs, s(:self), :find, s(:args, :*)))
87
- # and
88
- # s(:module, :ConditionParsers, s(:class, :ReturnValue, ...))
89
- # and
90
- # s(:class, :NotificationPresenter, nil, s(:call, nil, :extend, s(:const, :Forwardable)), s(:call, nil, :attr_reader, ...))
91
- load_funcs(node.compact.drop(2))
92
- else
93
- # @todo uncomment with logger at debug level
94
- # puts "got #{__method__} with #{node.first} and don't know how to handle it"
95
- # @note :const seems to indicate module inclusion/extension
96
- nil
97
- end
98
- }.compact
99
- end
100
- end
data/lib/drg/ruby/func.rb DELETED
@@ -1,35 +0,0 @@
1
- class DRG::Ruby::Func < Struct.new(:sexp, :_private)
2
- alias private? _private
3
-
4
- def conditions
5
- DRG::Decorators::SexpDecorator.new(sexp).each_sexp_condition.map &DRG::Ruby::Condition.method(:new)
6
- end
7
-
8
- def assignments
9
- nodes = find_assignments(sexp)
10
- sexp.find_nodes(:rescue).each do |node|
11
- node = node[1] if node[1].first == :block
12
- nodes.concat find_assignments(node)
13
- end
14
- nodes.map &DRG::Ruby::Assignment.method(:new)
15
- end
16
-
17
- def find_assignments(s_expression)
18
- s_expression.find_nodes(:op_asgn_or) + s_expression.find_nodes(:iasgn)
19
- end
20
-
21
- # @note we drop(1) to get rid of :args (which should be the first item in the sexp)
22
- # @note called from subclasses
23
- def map_args(_sexp = sexp, list = [])
24
- val = _sexp.first
25
- return list.drop(1) unless val
26
- case val
27
- when Symbol
28
- map_args(_sexp.drop(1), list << val)
29
- when Sexp
30
- map_args(_sexp.drop(1), list << val[1])
31
- else
32
- nil
33
- end
34
- end
35
- end
@@ -1,13 +0,0 @@
1
- class DRG::Ruby::InstanceFunc < DRG::Ruby::Func
2
- def name
3
- sexp[1]
4
- end
5
-
6
- def args
7
- map_args(sexp[2]) if sexp[2].first == :args
8
- end
9
-
10
- def class?
11
- false
12
- end
13
- end
data/lib/drg/ruby.rb DELETED
@@ -1,21 +0,0 @@
1
- require 'ruby_parser'
2
- require 'delegate'
3
-
4
- module DRG
5
- class Ruby
6
- autoload :Const, 'drg/ruby/const'
7
- autoload :Condition, 'drg/ruby/condition'
8
- autoload :Func, 'drg/ruby/func'
9
- autoload :ClassFunc, 'drg/ruby/class_func'
10
- autoload :InstanceFunc, 'drg/ruby/instance_func'
11
- autoload :Assignment, 'drg/ruby/assignment'
12
-
13
- attr_reader :sexp, :const
14
-
15
- # @param [Pathname, String] file
16
- def initialize(file)
17
- @sexp = RubyParser.new.parse File.read(file)
18
- @const = DRG::Ruby::Const.new(sexp)
19
- end
20
- end
21
- end
data/lib/drg/spec.rb DELETED
@@ -1,115 +0,0 @@
1
- class DRG::Spec < DelegateClass(DRG::Ruby::Const)
2
- # = Class
3
- # generate a rspec file based on existing code
4
-
5
- def self.default_indent_size
6
- 2
7
- end
8
-
9
- def self.generate(file)
10
- spec = new(file)
11
- return if spec.funcs.empty? # nothing to do
12
- lines = [%Q(require "spec_helper"), %Q(), %Q(describe #{spec.const} do)]
13
- if spec.class?
14
- spec.initialization_args.each do |arg|
15
- lines << %Q( let(:#{arg.to_s.sub(/^[&*]/, '')}) {})
16
- end
17
- lines << %Q()
18
- lines << %Q( subject { described_class.new #{spec.initialization_args.join(', ')} })
19
- elsif spec.module?
20
- lines << %Q( subject { Class.new { include #{spec.const} }.new })
21
- end
22
- lines << %Q()
23
- spec.funcs.reject(&:private?).each do |func|
24
- lines << %Q( describe #{spec.quote("#{func.class? ? '.' : '#'}#{func.name}")} do)
25
- func.assignments.each do |assignment|
26
- lines << %Q( it #{spec.quote(assignment)} do) << %Q( end)
27
- end
28
- func.conditions.each do |condition|
29
- lines.concat spec.collect_contexts(condition, ' ')
30
- end
31
- lines << %Q( end) << %Q()
32
- end
33
- lines << %Q(end) << %Q()
34
- lines
35
- end
36
-
37
- attr_reader :ruby, :file
38
-
39
- def initialize(file)
40
- @file = file
41
- @ruby = DRG::Ruby.new(file)
42
- super @ruby.const
43
- end
44
-
45
- def const
46
- @const ||= begin
47
- require file
48
- Kernel.const_get(ruby.const.name)
49
- end
50
- end
51
-
52
- def collect_contexts(condition, indent = '', contexts = [])
53
- new_indent = indent + (' ' * self.class.default_indent_size)
54
- contexts << %Q(#{indent}context #{quote(tr(condition.short_statement))} do) << %Q(#{new_indent}before {})
55
- if should_print? condition.return_value
56
- contexts << %Q(#{new_indent}it #{quote(condition.return_value)} do) << %Q(#{new_indent}end)
57
- end
58
- if condition.nested_conditions.any?
59
- condition.nested_conditions.each { |nc| collect_contexts(nc, new_indent, contexts) }
60
- end
61
- contexts << %Q(#{indent}end) << %Q() # /context
62
- if condition.parts.empty?
63
- contexts << %Q(#{indent}context #{quote(tr(negate(condition.short_statement)))} do) << %Q(#{new_indent}before {})
64
- if should_print? condition.else_return_value
65
- contexts << %Q(#{new_indent}it #{quote(condition.else_return_value)} do) << %Q(#{new_indent}end)
66
- end
67
- contexts << %Q(#{indent}end)
68
- end
69
- condition.parts.each do |condition_part|
70
- contexts << %Q(#{indent}context #{quote(tr(condition_part.short_statement))} do) << %Q(#{new_indent}before {})
71
- contexts << %Q(#{new_indent}it #{quote(condition_part.return_value)} do) << %Q(#{new_indent}end)
72
- contexts << %Q(#{indent}end)
73
- if should_print? condition_part.else_return_value
74
- contexts << %Q(#{indent}context #{quote(tr(negate(condition_part.short_statement)))} do) << %Q(#{new_indent}before {})
75
- contexts << %Q(#{new_indent}it #{quote(condition_part.else_return_value)} do) << %Q(#{new_indent}end)
76
- contexts << %Q(#{indent}end)
77
- end
78
- end
79
- contexts
80
- end
81
-
82
- def quote(txt)
83
- txt = txt.to_s
84
- txt.strip!
85
- if txt =~ /"/
86
- "%Q[#{txt.gsub(/\#\{(.*?)\}/m, '\#{\1}')}]"
87
- else
88
- %Q("#{txt}")
89
- end
90
- end
91
-
92
- def negate(phrase)
93
- if phrase[/^unless /]
94
- phrase.sub /^unless /, 'if '
95
- else
96
- "not #{phrase}"
97
- end
98
- end
99
-
100
- def tr(phrase)
101
- phrase.sub! /^if /, 'when '
102
- phrase.sub! /^not if /, 'unless '
103
- phrase.sub! /^if not /, 'unless '
104
- phrase.sub! /then$/, ''
105
- if phrase !~ /^(when|unless|not)/
106
- phrase = "when #{phrase}"
107
- end
108
- phrase
109
- end
110
-
111
- # @description reject multiline statements, which means we messed up somewhere else, so let's hide that
112
- def should_print?(txt)
113
- !txt.empty? and txt !~ /\n/
114
- end
115
- end
@@ -1,71 +0,0 @@
1
- require 'fileutils'
2
-
3
- module DRG
4
- module Tasks
5
- class SpecRunner
6
- include Log
7
-
8
- attr_reader :file
9
-
10
- # @param [Pathname] file
11
- def initialize(file)
12
- @file = Pathname.new(file)
13
- end
14
-
15
- def perform
16
- fail ArgumentError, %Q(File or directory does not exist: "#{file}") if !File.exists?(file) && !File.exists?("#{file}.rb")
17
- ruby_files.each do |ruby_file|
18
- rspec_file = Pathname.new(spec_file(ruby_file))
19
- spec_file_path = rspec_file.to_s[%r|/(spec/.+)|, 1]
20
- next if rspec_file.exist?.tap { |result| log "- #{spec_file_path} - already exists", :gray if result }
21
- spec = generate_spec(ruby_file)
22
- next unless spec
23
- log "+ #{spec_file_path}"
24
- FileUtils.mkdir_p(rspec_file.parent)
25
- File.open(rspec_file, 'wb') do |f|
26
- f << spec.join("\n")
27
- end
28
- end
29
- end
30
-
31
- def generate_spec(ruby_file)
32
- spec = DRG::Spec.generate Pathname.new(File.expand_path(ruby_file))
33
- if spec
34
- spec
35
- else
36
- log "- #{ruby_file} - no methods", :gray
37
- nil
38
- end
39
- end
40
-
41
- def ruby_files
42
- if File.directory?(file)
43
- Dir[File.join(file, '**', '*.rb')]
44
- else
45
- if file.extname.empty?
46
- ["#{file}.rb"]
47
- else
48
- [file]
49
- end
50
- end
51
- end
52
-
53
- # @note subbing out /app/ is Rails specific
54
- def spec_file(ruby_file)
55
- File.join(spec_path, "#{specify(ruby_file)}").sub '/app/', '/'
56
- end
57
-
58
- def specify(file_name)
59
- file_name.sub('.rb', '_spec.rb')
60
- end
61
-
62
- def spec_path
63
- if File.directory?(File.expand_path('spec'))
64
- File.expand_path('spec')
65
- else
66
- fail "Couldn't find spec directory"
67
- end
68
- end
69
- end
70
- end
71
- end