transpec 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +35 -3
- data/README.md.erb +35 -3
- data/lib/transpec/cli.rb +50 -4
- data/lib/transpec/commit_message.rb +25 -0
- data/lib/transpec/git.rb +18 -0
- data/lib/transpec/record.rb +28 -0
- data/lib/transpec/report.rb +109 -0
- data/lib/transpec/rewriter.rb +17 -8
- data/lib/transpec/syntax.rb +25 -22
- data/lib/transpec/syntax/be_close.rb +6 -0
- data/lib/transpec/syntax/double.rb +5 -0
- data/lib/transpec/syntax/matcher.rb +17 -1
- data/lib/transpec/syntax/method_stub.rb +40 -8
- data/lib/transpec/syntax/raise_error.rb +17 -0
- data/lib/transpec/syntax/send_node_syntax.rb +4 -0
- data/lib/transpec/syntax/should.rb +23 -2
- data/lib/transpec/syntax/should_receive.rb +54 -2
- data/lib/transpec/version.rb +2 -2
- data/spec/.rubocop.yml +1 -1
- data/spec/support/shared_context.rb +10 -0
- data/spec/transpec/cli_spec.rb +76 -29
- data/spec/transpec/commit_message_spec.rb +63 -0
- data/spec/transpec/configuration_spec.rb +1 -1
- data/spec/transpec/git_spec.rb +114 -38
- data/spec/transpec/record_spec.rb +18 -0
- data/spec/transpec/report_spec.rb +89 -0
- data/spec/transpec/rewriter_spec.rb +5 -0
- data/spec/transpec/syntax/be_close_spec.rb +10 -1
- data/spec/transpec/syntax/double_spec.rb +10 -0
- data/spec/transpec/syntax/matcher_spec.rb +31 -0
- data/spec/transpec/syntax/method_stub_spec.rb +53 -44
- data/spec/transpec/syntax/raise_error_spec.rb +64 -24
- data/spec/transpec/syntax/should_receive_spec.rb +67 -7
- data/spec/transpec/syntax/should_spec.rb +26 -0
- data/tasks/test.rake +27 -12
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f6772bb858f284cf44c824055979f1cd8fe9cb4
|
4
|
+
data.tar.gz: e960ba822a50bf10dbb7dc615c330ea8cf8eab9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa0839b39a340d7cf14bb18d2b00051550559f7d677afda0cf859ef3f28afc535372ddb56793cb6421b3cd0fe39bf7c9d0466a01a98418e657578604c940dbb2
|
7
|
+
data.tar.gz: 9421dfa5e886e1f9057506adf5c8e6f87c393ecad4ec793ad84108d22bb4472e29bef9405b17098b2ce1ceba9a654fdd987541dd7081cd12f5d97e0e38efc60c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## Master
|
4
4
|
|
5
|
+
## v0.2.0
|
6
|
+
|
7
|
+
* Display conversion summary at the end
|
8
|
+
* Add `-m/--commit-message` option that allows to generate commit message automatically
|
9
|
+
|
5
10
|
## v0.1.3
|
6
11
|
|
7
12
|
* Avoid confusing `Excon.stub` with RSpec's `stub` ([#4](https://github.com/yujinakayama/transpec/issues/4))
|
data/README.md
CHANGED
@@ -105,11 +105,11 @@ Before converting your specs:
|
|
105
105
|
* Run `rspec` and check if all the specs pass.
|
106
106
|
* Ensure the Git repository is clean. (You don't want to mix up your changes and Transpec's changes, right?)
|
107
107
|
|
108
|
-
Then, run `transpec`
|
108
|
+
Then, run `transpec` (using `--commit-message` is recommended) in the project root directory:
|
109
109
|
|
110
110
|
```bash
|
111
111
|
$ cd some-project
|
112
|
-
$ transpec
|
112
|
+
$ transpec --commit-message
|
113
113
|
Processing spec/spec_helper.rb
|
114
114
|
Processing spec/spec_spec.rb
|
115
115
|
Processing spec/support/file_helper.rb
|
@@ -120,7 +120,22 @@ Processing spec/transpec/ast/scope_stack_spec.rb
|
|
120
120
|
|
121
121
|
This will convert and overwrite all spec files in the `spec` directory.
|
122
122
|
|
123
|
-
After the conversion, run `rspec` again and check
|
123
|
+
After the conversion, run `rspec` again and check whether all pass:
|
124
|
+
|
125
|
+
```bash
|
126
|
+
$ bundle exec rspec
|
127
|
+
# ...
|
128
|
+
843 examples, 0 failures
|
129
|
+
```
|
130
|
+
|
131
|
+
If all pass, commit the changes with auto-generated message:
|
132
|
+
|
133
|
+
```bash
|
134
|
+
$ git add -u
|
135
|
+
$ git commit -eF .git/COMMIT_EDITMSG
|
136
|
+
```
|
137
|
+
|
138
|
+
And you are done!
|
124
139
|
|
125
140
|
## Options
|
126
141
|
|
@@ -139,6 +154,17 @@ Processing spec/spec_spec.rb
|
|
139
154
|
Processing spec/support/file_helper.rb
|
140
155
|
```
|
141
156
|
|
157
|
+
### `-m/--commit-message`
|
158
|
+
|
159
|
+
Generate commit message that describes conversion summary.
|
160
|
+
Currently only Git is supported.
|
161
|
+
|
162
|
+
When you commit, you need to run the following command to use the generated message:
|
163
|
+
|
164
|
+
```bash
|
165
|
+
$ git commit -eF .git/COMMIT_EDITMSG
|
166
|
+
```
|
167
|
+
|
142
168
|
### `-d/--disable`
|
143
169
|
|
144
170
|
Disable specific conversions.
|
@@ -408,3 +434,9 @@ Tested on MRI 1.9, MRI 2.0 and JRuby in 1.9 mode.
|
|
408
434
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
409
435
|
4. Push to the branch (`git push origin my-new-feature`)
|
410
436
|
5. Create new Pull Request
|
437
|
+
|
438
|
+
## License
|
439
|
+
|
440
|
+
Copyright (c) 2013 Yuji Nakayama
|
441
|
+
|
442
|
+
See the [LICENSE.txt](LICENSE.txt) for details.
|
data/README.md.erb
CHANGED
@@ -78,11 +78,11 @@ Before converting your specs:
|
|
78
78
|
* Run `rspec` and check if all the specs pass.
|
79
79
|
* Ensure the Git repository is clean. (You don't want to mix up your changes and Transpec's changes, right?)
|
80
80
|
|
81
|
-
Then, run `transpec`
|
81
|
+
Then, run `transpec` (using `--commit-message` is recommended) in the project root directory:
|
82
82
|
|
83
83
|
```bash
|
84
84
|
$ cd some-project
|
85
|
-
$ transpec
|
85
|
+
$ transpec --commit-message
|
86
86
|
Processing spec/spec_helper.rb
|
87
87
|
Processing spec/spec_spec.rb
|
88
88
|
Processing spec/support/file_helper.rb
|
@@ -93,7 +93,22 @@ Processing spec/transpec/ast/scope_stack_spec.rb
|
|
93
93
|
|
94
94
|
This will convert and overwrite all spec files in the `spec` directory.
|
95
95
|
|
96
|
-
After the conversion, run `rspec` again and check
|
96
|
+
After the conversion, run `rspec` again and check whether all pass:
|
97
|
+
|
98
|
+
```bash
|
99
|
+
$ bundle exec rspec
|
100
|
+
# ...
|
101
|
+
843 examples, 0 failures
|
102
|
+
```
|
103
|
+
|
104
|
+
If all pass, commit the changes with auto-generated message:
|
105
|
+
|
106
|
+
```bash
|
107
|
+
$ git add -u
|
108
|
+
$ git commit -eF .git/COMMIT_EDITMSG
|
109
|
+
```
|
110
|
+
|
111
|
+
And you are done!
|
97
112
|
|
98
113
|
## Options
|
99
114
|
|
@@ -112,6 +127,17 @@ Processing spec/spec_spec.rb
|
|
112
127
|
Processing spec/support/file_helper.rb
|
113
128
|
```
|
114
129
|
|
130
|
+
### `-m/--commit-message`
|
131
|
+
|
132
|
+
Generate commit message that describes conversion summary.
|
133
|
+
Currently only Git is supported.
|
134
|
+
|
135
|
+
When you commit, you need to run the following command to use the generated message:
|
136
|
+
|
137
|
+
```bash
|
138
|
+
$ git commit -eF .git/COMMIT_EDITMSG
|
139
|
+
```
|
140
|
+
|
115
141
|
### `-d/--disable`
|
116
142
|
|
117
143
|
Disable specific conversions.
|
@@ -404,3 +430,9 @@ Tested on MRI 1.9, MRI 2.0 and JRuby in 1.9 mode.
|
|
404
430
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
405
431
|
4. Push to the branch (`git push origin my-new-feature`)
|
406
432
|
5. Create new Pull Request
|
433
|
+
|
434
|
+
## License
|
435
|
+
|
436
|
+
Copyright (c) 2013 Yuji Nakayama
|
437
|
+
|
438
|
+
See the [LICENSE.txt](LICENSE.txt) for details.
|
data/lib/transpec/cli.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
require 'transpec/configuration'
|
4
|
+
require 'transpec/commit_message'
|
4
5
|
require 'transpec/git'
|
6
|
+
require 'transpec/report'
|
5
7
|
require 'transpec/rewriter'
|
6
8
|
require 'transpec/version'
|
7
9
|
require 'optparse'
|
@@ -17,8 +19,9 @@ module Transpec
|
|
17
19
|
deprecated: :replace_deprecated_method=
|
18
20
|
}
|
19
21
|
|
20
|
-
attr_reader :configuration, :forced
|
22
|
+
attr_reader :configuration, :forced, :generates_commit_message
|
21
23
|
alias_method :forced?, :forced
|
24
|
+
alias_method :generates_commit_message?, :generates_commit_message
|
22
25
|
|
23
26
|
def self.run(args = ARGV)
|
24
27
|
new.run(args)
|
@@ -27,6 +30,8 @@ module Transpec
|
|
27
30
|
def initialize
|
28
31
|
@configuration = Configuration.new
|
29
32
|
@forced = false
|
33
|
+
@generates_commit_message = false
|
34
|
+
@report = Report.new
|
30
35
|
end
|
31
36
|
|
32
37
|
def run(args)
|
@@ -48,7 +53,8 @@ module Transpec
|
|
48
53
|
process_file(file_path)
|
49
54
|
end
|
50
55
|
|
51
|
-
|
56
|
+
display_summary
|
57
|
+
generate_commit_message if generates_commit_message?
|
52
58
|
|
53
59
|
true
|
54
60
|
rescue => error
|
@@ -59,13 +65,16 @@ module Transpec
|
|
59
65
|
def process_file(file_path)
|
60
66
|
puts "Processing #{file_path}"
|
61
67
|
|
62
|
-
rewriter = Rewriter.new(@configuration)
|
68
|
+
rewriter = Rewriter.new(@configuration, @report)
|
63
69
|
rewriter.rewrite_file!(file_path)
|
64
70
|
|
65
|
-
rewriter.
|
71
|
+
@report.invalid_context_errors.concat(rewriter.invalid_context_errors)
|
72
|
+
|
73
|
+
rewriter.invalid_context_errors.each do |error|
|
66
74
|
warn_not_in_example_group_context_error(error)
|
67
75
|
end
|
68
76
|
rescue Parser::SyntaxError => error
|
77
|
+
@report.syntax_errors << error
|
69
78
|
warn_syntax_error(error)
|
70
79
|
end
|
71
80
|
|
@@ -82,6 +91,18 @@ module Transpec
|
|
82
91
|
@forced = true
|
83
92
|
end
|
84
93
|
|
94
|
+
parser.on(
|
95
|
+
'-m', '--commit-message',
|
96
|
+
'Generate commit message that describes',
|
97
|
+
'conversion summary. Only Git is supported.'
|
98
|
+
) do
|
99
|
+
unless Git.inside_of_repository?
|
100
|
+
fail '-m/--commit-message option is specified but not in a Git repository'
|
101
|
+
end
|
102
|
+
|
103
|
+
@generates_commit_message = true
|
104
|
+
end
|
105
|
+
|
85
106
|
parser.on(
|
86
107
|
'-d', '--disable TYPE[,TYPE...]',
|
87
108
|
'Disable specific conversions.',
|
@@ -179,6 +200,31 @@ module Transpec
|
|
179
200
|
fail 'The current Git repository is not clean. Aborting.'
|
180
201
|
end
|
181
202
|
|
203
|
+
def display_summary
|
204
|
+
puts
|
205
|
+
|
206
|
+
unless @report.records.empty?
|
207
|
+
puts 'Summary:'
|
208
|
+
puts
|
209
|
+
puts @report.colored_summary
|
210
|
+
puts
|
211
|
+
end
|
212
|
+
|
213
|
+
puts @report.colored_stats
|
214
|
+
end
|
215
|
+
|
216
|
+
def generate_commit_message
|
217
|
+
return if @report.records.empty?
|
218
|
+
|
219
|
+
commit_message = CommitMessage.new(@report, ARGV)
|
220
|
+
Git.write_commit_message(commit_message.to_s)
|
221
|
+
|
222
|
+
puts
|
223
|
+
puts 'Commit message was generated to .git/COMMIT_EDITMSG.'.color(:cyan)
|
224
|
+
puts 'Use the following command for the next commit:'.color(:cyan)
|
225
|
+
puts ' git commit -eF .git/COMMIT_EDITMSG'
|
226
|
+
end
|
227
|
+
|
182
228
|
def warn_syntax_error(error)
|
183
229
|
warn "Syntax error at #{error.diagnostic.location}. Skipping the file.".color(:red)
|
184
230
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'transpec/version'
|
4
|
+
|
5
|
+
module Transpec
|
6
|
+
class CommitMessage
|
7
|
+
def initialize(report, cli_args = [])
|
8
|
+
@report = report
|
9
|
+
@cli_args = cli_args
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
conversion_summary = @report.summary(bullet: '*', separate_by_blank_line: true)
|
14
|
+
|
15
|
+
<<-END.gsub(/^\s+\|/, '').chomp
|
16
|
+
|Convert specs to latest RSpec syntax with Transpec
|
17
|
+
|
|
18
|
+
|This conversion is done by Transpec #{Transpec::Version} with the following command:
|
19
|
+
| transpec #{@cli_args.join(' ')}
|
20
|
+
|
|
21
|
+
|#{conversion_summary}
|
22
|
+
END
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/transpec/git.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module Transpec
|
4
4
|
module Git
|
5
5
|
GIT = 'git'
|
6
|
+
COMMIT_MESSAGE_FILE_PATH = File.join('.git', 'COMMIT_EDITMSG')
|
6
7
|
|
7
8
|
module_function
|
8
9
|
|
@@ -14,11 +15,28 @@ module Transpec
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def inside_of_repository?
|
18
|
+
fail '`git` command is not available' unless command_available?
|
17
19
|
system("#{GIT} rev-parse --is-inside-work-tree > /dev/null 2> /dev/null")
|
18
20
|
end
|
19
21
|
|
20
22
|
def clean?
|
23
|
+
fail_unless_inside_of_repository
|
21
24
|
`#{GIT} status --porcelain`.empty?
|
22
25
|
end
|
26
|
+
|
27
|
+
def repository_root
|
28
|
+
fail_unless_inside_of_repository
|
29
|
+
`#{GIT} rev-parse --show-toplevel`.chomp
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_commit_message(message)
|
33
|
+
fail_unless_inside_of_repository
|
34
|
+
file_path = File.join(repository_root, COMMIT_MESSAGE_FILE_PATH)
|
35
|
+
File.write(file_path, message)
|
36
|
+
end
|
37
|
+
|
38
|
+
def fail_unless_inside_of_repository
|
39
|
+
fail 'The current working directory is not a Git repository' unless inside_of_repository?
|
40
|
+
end
|
23
41
|
end
|
24
42
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
class Record
|
5
|
+
attr_reader :original_syntax, :converted_syntax
|
6
|
+
|
7
|
+
def initialize(original_syntax, converted_syntax)
|
8
|
+
@original_syntax = original_syntax
|
9
|
+
@converted_syntax = converted_syntax
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
self.class == other.class &&
|
14
|
+
@original_syntax == other.original_syntax &&
|
15
|
+
@converted_syntax == other.converted_syntax
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :eql?, :==
|
19
|
+
|
20
|
+
def hash
|
21
|
+
@original_syntax.hash ^ @converted_syntax.hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"`#{original_syntax}` -> `#{converted_syntax}`"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'rainbow'
|
4
|
+
|
5
|
+
module Transpec
|
6
|
+
class Report
|
7
|
+
attr_reader :records, :invalid_context_errors, :syntax_errors
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@records = []
|
11
|
+
@invalid_context_errors = []
|
12
|
+
@syntax_errors = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def unique_record_counts
|
16
|
+
record_counts = Hash.new(0)
|
17
|
+
|
18
|
+
records.each do |record|
|
19
|
+
record_counts[record] += 1
|
20
|
+
end
|
21
|
+
|
22
|
+
Hash[record_counts.sort_by { |record, count| -count }]
|
23
|
+
end
|
24
|
+
|
25
|
+
def colored_summary(options = nil)
|
26
|
+
options ||= { bullet: nil, separate_by_blank_line: false }
|
27
|
+
|
28
|
+
summary = ''
|
29
|
+
|
30
|
+
unique_record_counts.each do |record, count|
|
31
|
+
summary << "\n" if options[:separate_by_blank_line] && !summary.empty?
|
32
|
+
summary << format_record(record, count, options[:bullet])
|
33
|
+
end
|
34
|
+
|
35
|
+
summary
|
36
|
+
end
|
37
|
+
|
38
|
+
def summary(options = nil)
|
39
|
+
without_color { colored_summary(options) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def colored_stats
|
43
|
+
convertion_and_incomplete_stats + error_stats
|
44
|
+
end
|
45
|
+
|
46
|
+
def stats
|
47
|
+
without_color { colored_stats }
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def without_color
|
53
|
+
# TODO: Consider using another coloring gem that does not depend global state.
|
54
|
+
original_coloring_state = Sickill::Rainbow.enabled
|
55
|
+
Sickill::Rainbow.enabled = false
|
56
|
+
value = yield
|
57
|
+
Sickill::Rainbow.enabled = original_coloring_state
|
58
|
+
value
|
59
|
+
end
|
60
|
+
|
61
|
+
def format_record(record, count, bullet = nil)
|
62
|
+
entry_prefix = bullet ? bullet + ' ' : ''
|
63
|
+
indentation = if bullet
|
64
|
+
' ' * entry_prefix.length
|
65
|
+
else
|
66
|
+
''
|
67
|
+
end
|
68
|
+
|
69
|
+
text = entry_prefix + pluralize(count, 'conversion').color(:cyan) + "\n"
|
70
|
+
text << indentation + ' ' + 'from: '.color(:cyan) + record.original_syntax + "\n"
|
71
|
+
text << indentation + ' ' + 'to: '.color(:cyan) + record.converted_syntax + "\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
def convertion_and_incomplete_stats
|
75
|
+
color = invalid_context_errors.empty? ? :green : :yellow
|
76
|
+
|
77
|
+
text = pluralize(records.count, 'conversion') + ', '
|
78
|
+
text << pluralize(invalid_context_errors.count, 'incomplete') + ', '
|
79
|
+
text.color(color)
|
80
|
+
end
|
81
|
+
|
82
|
+
def error_stats
|
83
|
+
color = if !syntax_errors.empty?
|
84
|
+
:red
|
85
|
+
elsif invalid_context_errors.empty?
|
86
|
+
:green
|
87
|
+
else
|
88
|
+
:yellow
|
89
|
+
end
|
90
|
+
|
91
|
+
pluralize(syntax_errors.count, 'error').color(color)
|
92
|
+
end
|
93
|
+
|
94
|
+
def pluralize(number, thing, options = {})
|
95
|
+
text = ''
|
96
|
+
|
97
|
+
if number == 0 && options[:no_for_zero]
|
98
|
+
text = 'no'
|
99
|
+
else
|
100
|
+
text << number.to_s
|
101
|
+
end
|
102
|
+
|
103
|
+
text << " #{thing}"
|
104
|
+
text << 's' unless number == 1
|
105
|
+
|
106
|
+
text
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|