transpec 0.1.3 → 0.2.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 +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
|