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 +4 -4
- data/README.md +33 -60
- data/drg.gemspec +2 -4
- data/lib/drg/version.rb +1 -1
- data/lib/drg.rb +0 -3
- data/lib/tasks/drg.rake +0 -9
- metadata +5 -50
- data/lib/drg/decorators/sexp_decorator.rb +0 -20
- data/lib/drg/decorators.rb +0 -3
- data/lib/drg/ruby/assignment.rb +0 -25
- data/lib/drg/ruby/class_func.rb +0 -13
- data/lib/drg/ruby/condition.rb +0 -101
- data/lib/drg/ruby/const.rb +0 -100
- data/lib/drg/ruby/func.rb +0 -35
- data/lib/drg/ruby/instance_func.rb +0 -13
- data/lib/drg/ruby.rb +0 -21
- data/lib/drg/spec.rb +0 -115
- data/lib/drg/tasks/spec_runner.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3ec2da36e33e6a4ba09189233dd40b01401b1e7
|
4
|
+
data.tar.gz: 6e95adec97a178eedff8e6377ee4be64cdf3fd7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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{
|
12
|
-
spec.description = %q{
|
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
data/lib/drg.rb
CHANGED
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.
|
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
|
+
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:
|
130
|
-
|
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:
|
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
|
data/lib/drg/decorators.rb
DELETED
data/lib/drg/ruby/assignment.rb
DELETED
@@ -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
|
data/lib/drg/ruby/class_func.rb
DELETED
data/lib/drg/ruby/condition.rb
DELETED
@@ -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
|
data/lib/drg/ruby/const.rb
DELETED
@@ -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
|
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
|