drg 0.15.6 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
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