rails5-spec-converter 1.0.4 → 1.0.5

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: 828614a89d1694bc81dafc184bbfa9ac32f60719
4
- data.tar.gz: dafbae38f00ecc71e583f3415ae28e9f2972e30b
3
+ metadata.gz: f063f02a538854ce40ba052bee57619976d13984
4
+ data.tar.gz: 2953c939e47421e564bb1c38009b25c7e55eab57
5
5
  SHA512:
6
- metadata.gz: 46e9d313500d4615d4f220bae8381c963668332a5d8803a1870d6fb3fdef58ff394c185d89d3a0b6873652e45bba8d29bbc230abff808b189f64ae572b4f21de
7
- data.tar.gz: 4eee1870ad1c50952d0d6b443c273817f2470c3ac697d893366c759b6bc6b1477831f545b4a468522960a95e95bf354993bd14f7668c4fa494188f89eb00aebe
6
+ metadata.gz: caec295f2a297a1f7041d8cddb3129555f4ff20b886ae1ccf5baf85bd512008daca842885b608fae1ac0df2ff35ab92d3cfd1bd64d2db8e29e6631098d5c9ba6
7
+ data.tar.gz: 38bd4a4c918a0cb108d20c3b7f120eac19caeae42bdfd31e0b79bed40d49cb4d84973110632707966e65b422e47a2b7bbea9f6fd900c031f4b70eb41255175aa
data/README.md CHANGED
@@ -33,6 +33,36 @@ Make sure you've committed everything to Git first, then
33
33
 
34
34
  This will update all the files in that directory matching the glob `spec/**/*_spec.rb`. It should be idempotent.
35
35
 
36
+ If you want to specify a specific set of files instead, you can run `rails5-spec-converter path_to_my_files`.
37
+
38
+ By default it will make some noise, run with `rails5-spec-converter --quiet` if you want it not to.
39
+
40
+ ### Whitespace
41
+
42
+ The tool will attempt to indent the newly-added "params" hash in situations when the arguments are on newlines, e.g.:
43
+
44
+ ```
45
+ get :index
46
+ search: 'bayleef',
47
+ format: :json
48
+ ```
49
+
50
+ becomes
51
+
52
+ ```
53
+ get :index
54
+ params: {
55
+ search: 'bayleef'
56
+ },
57
+ format: :json
58
+ ```
59
+
60
+ Since the extra spaces in front of 'params' are brand-new whitespace, you may want to configure them (default is 2 spaces).
61
+
62
+ `rails5-spec-converter --indent ' '`
63
+
64
+ `rails5-spec-converter --indent '\t'`
65
+
36
66
  ## Development
37
67
 
38
68
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,15 +1,45 @@
1
1
  require 'rails5/spec_converter/text_transformer'
2
+ require 'optparse'
2
3
 
3
4
  module Rails5
4
5
  module SpecConverter
5
6
  class CLI
7
+ def initialize
8
+ @options = {}
9
+ OptionParser.new do |opts|
10
+ opts.banner = "Usage: rails5-spec-converter [options] [files]"
11
+
12
+ opts.on("-q", "--quiet", "Run quietly") do |q|
13
+ @options[:quiet] = q
14
+ end
15
+
16
+ opts.on("-i", "--indent INDENT", "Use specified string for indentation (default is two spaces)") do |indent|
17
+ @options[:indent] = indent.gsub("\\t", "\t")
18
+ end
19
+ end.parse!
20
+
21
+ @files = ARGV
22
+ end
23
+
6
24
  def run
7
- Dir.glob("spec/**/*_spec.rb") do |path|
8
- original_content = File.read(path)
9
- transformed_content = Rails5::SpecConverter::TextTransformer.new(original_content).transform
10
- File.write(path, transformed_content)
25
+ paths = @files.length > 0 ? @files : ["spec/**/*_spec.rb"]
26
+
27
+ paths.each do |path|
28
+ Dir.glob(path) do |file_path|
29
+ log "Processing: #{file_path}"
30
+
31
+ original_content = File.read(file_path)
32
+ transformed_content = Rails5::SpecConverter::TextTransformer.new(original_content, @options).transform
33
+ File.write(file_path, transformed_content)
34
+ end
11
35
  end
12
36
  end
37
+
38
+ def log(str)
39
+ return if @options[:quiet]
40
+
41
+ puts str
42
+ end
13
43
  end
14
44
  end
15
45
  end
@@ -8,7 +8,9 @@ module Rails5
8
8
  ALLOWED_KWARG_KEYS = %i(params session flash method body xhr format)
9
9
 
10
10
  class TextTransformer
11
- def initialize(content)
11
+ def initialize(content, options = {})
12
+ @indent = options[:indent] || ' '
13
+ @quiet = options[:quiet]
12
14
  @content = content
13
15
  end
14
16
 
@@ -75,20 +77,73 @@ module Rails5
75
77
  end
76
78
  end
77
79
 
78
- curly_sep = hash_node.parent.loc.expression.source.match(/{\S/) ? '' : ' '
79
-
80
80
  if pairs_that_belong_in_params.length > 0
81
- rewritten_hashes = ["params: {#{curly_sep}#{restring_hash(pairs_that_belong_in_params)}#{curly_sep}}"]
81
+ joiner = joiner_between_pairs(hash_node)
82
+ params_hash = appropriately_spaced_params_hash(
83
+ hash_node: hash_node,
84
+ pairs: pairs_that_belong_in_params
85
+ )
86
+
87
+ rewritten_hashes = ["params: #{params_hash}"]
82
88
  if pairs_that_belong_outside_params.length > 0
83
- rewritten_hashes << restring_hash(pairs_that_belong_outside_params)
89
+ rewritten_hashes << restring_hash(pairs_that_belong_outside_params, joiner: joiner)
84
90
  end
85
91
  source_rewriter.replace(
86
92
  hash_node.loc.expression,
87
- rewritten_hashes.join(', ')
93
+ rewritten_hashes.join(joiner)
88
94
  )
89
95
  end
90
96
  end
91
97
 
98
+ def additional_indent(hash_node)
99
+ joiner = joiner_between_pairs(hash_node)
100
+ joiner && joiner.include?("\n") ? @indent : nil
101
+ end
102
+
103
+ def existing_indent(hash_node)
104
+ previous_sibling = hash_node.parent.children[hash_node.sibling_index - 1]
105
+ text_before_hash = text_between_siblings(previous_sibling, hash_node)
106
+ whitespace_match = text_before_hash.match("\n(\s*)")
107
+ return whitespace_match[1] if whitespace_match
108
+
109
+ joiner = joiner_between_pairs(hash_node)
110
+ pair_joiner_match = joiner.match("\n(\s*)") if joiner
111
+ return pair_joiner_match[1] if pair_joiner_match
112
+ end
113
+
114
+ def has_space_after_curly?(hash_node)
115
+ hash_node.parent.loc.expression.source.match(/{\S/)
116
+ end
117
+
118
+ def joiner_between_pairs(hash_node)
119
+ texts_between = []
120
+ hash_node.children[0..-2].each_with_index do |pair, index|
121
+ next_pair = hash_node.children[index + 1]
122
+ texts_between << text_between_siblings(pair, next_pair)
123
+ end
124
+ if texts_between.uniq.length > 1
125
+ log "Inconsistent whitespace between hash pairs, using the first separator (#{texts_between[0].inspect})."
126
+ log "Seen when processing this expression: \n```\n#{hash_node.loc.expression.source}\n```\n\n"
127
+ end
128
+ texts_between[0]
129
+ end
130
+
131
+ def text_between_siblings(node1, node2)
132
+ @content[node1.loc.expression.end_pos...node2.loc.expression.begin_pos]
133
+ end
134
+
135
+ def appropriately_spaced_params_hash(hash_node:, pairs:)
136
+ extra_indent = additional_indent(hash_node)
137
+
138
+ if extra_indent
139
+ base_indent = existing_indent(hash_node)
140
+ "{\n#{restring_hash(pairs, indent: base_indent + extra_indent, joiner: ",\n")}\n#{base_indent}}"
141
+ else
142
+ curly_sep = has_space_after_curly?(hash_node) ? '' : ' '
143
+ "{#{curly_sep}#{restring_hash(pairs)}#{curly_sep}}"
144
+ end
145
+ end
146
+
92
147
  def wrap_arg(source_rewriter, node, key)
93
148
  node_loc = node.loc.expression
94
149
  node_source = node_loc.source
@@ -98,8 +153,14 @@ module Rails5
98
153
  source_rewriter.replace(node_loc, "#{key}: #{node_source}")
99
154
  end
100
155
 
101
- def restring_hash(pairs)
102
- pairs.map { |pair| pair.loc.expression.source }.join(", ")
156
+ def restring_hash(pairs, joiner: ", ", indent: '')
157
+ pairs.map { |pair| "#{indent}#{pair.loc.expression.source}" }.join(joiner)
158
+ end
159
+
160
+ def log(str)
161
+ return if @quiet
162
+
163
+ puts str
103
164
  end
104
165
  end
105
166
  end
@@ -1,5 +1,5 @@
1
1
  module Rails5
2
2
  module SpecConverter
3
- VERSION = "1.0.4"
3
+ VERSION = "1.0.5"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails5-spec-converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Grathwell
@@ -139,8 +139,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  version: '0'
140
140
  requirements: []
141
141
  rubyforge_project:
142
- rubygems_version: 2.5.1
142
+ rubygems_version: 2.4.5
143
143
  signing_key:
144
144
  specification_version: 4
145
145
  summary: A tool to upgrade Rails 4-style specs to Rails 5-style
146
146
  test_files: []
147
+ has_rdoc: