rubocop-yast 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/spec/ops_spec.rb CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- def config(safe_mode: true)
6
- conf = { "Yast/Ops" => { "SafeMode" => safe_mode } }
7
- RuboCop::Config.new(conf)
8
- end
9
-
10
5
  describe RuboCop::Cop::Yast::Ops do
11
6
  context("In safe mode") do
12
- subject(:cop) { described_class.new(config(safe_mode: true)) }
7
+ let(:config) do
8
+ conf = { "Yast/Ops" => { "SafeMode" => true } }
9
+ RuboCop::Config.new(conf)
10
+ end
11
+
12
+ subject(:cop) { described_class.new(config) }
13
13
 
14
14
  it "finds trivial Ops.add call" do
15
15
  inspect_source(cop, ["Ops.add(2, 4)"])
@@ -99,7 +99,12 @@ describe RuboCop::Cop::Yast::Ops do
99
99
  end
100
100
 
101
101
  context("In unsafe mode") do
102
- subject(:cop) { described_class.new(config(safe_mode: false)) }
102
+ let(:config) do
103
+ conf = { "Yast/Ops" => { "SafeMode" => false } }
104
+ RuboCop::Config.new(conf)
105
+ end
106
+
107
+ subject(:cop) { described_class.new(config) }
103
108
 
104
109
  it "finds unsafe Ops.add calls" do
105
110
  inspect_source(cop, ["if true\nOps.add(foo, 4)\nend"])
@@ -0,0 +1,47 @@
1
+
2
+ # this module provides code block generators for RSpecRenderer
3
+ module RspecCode
4
+ # rubocop:disable Metrics/MethodLength
5
+ def generate_translation_code
6
+ [
7
+ "original_code = code_cleanup(<<-EOT)",
8
+ Code.indent(@original_code),
9
+ "EOT",
10
+ "",
11
+ "translated_code = code_cleanup(<<-EOT)",
12
+ Code.indent(@translated_code),
13
+ "EOT",
14
+ "",
15
+ "cop = RuboCop::Cop::Yast::Builtins.new",
16
+ "expect(autocorrect_source(cop, original_code)).to eq(translated_code)"
17
+ ].join("\n")
18
+ end
19
+
20
+ def generate_offense_code
21
+ [
22
+ "code = code_cleanup(<<-EOT)",
23
+ Code.indent(@offense),
24
+ "EOT",
25
+ "",
26
+ "cop = RuboCop::Cop::Yast::Builtins.new",
27
+ "inspect_source(cop, [code])",
28
+ "",
29
+ "expect(cop.offenses.size).to eq(1)",
30
+ "expect(cop.messages.first).to match(/Builtin call `.*` is obsolete/)"
31
+ ].join("\n")
32
+ end
33
+
34
+ def generate_accepted_code
35
+ [
36
+ "code = code_cleanup(<<-EOT)",
37
+ Code.indent(@accepted_code),
38
+ "EOT",
39
+ "",
40
+ "cop = RuboCop::Cop::Yast::Builtins.new",
41
+ "inspect_source(cop, [code])",
42
+ "",
43
+ "expect(cop.offenses).to be_empty"
44
+ ].join("\n")
45
+ end
46
+ # rubocop:enable Metrics/MethodLength
47
+ end
@@ -0,0 +1,206 @@
1
+ require "redcarpet"
2
+
3
+ require_relative "rspec_code"
4
+
5
+ # Utility functions for manipulating code.
6
+ module Code
7
+ INDENT_STEP = 2
8
+
9
+ class << self
10
+ def join(lines)
11
+ lines.map { |l| "#{l}\n" }.join("")
12
+ end
13
+
14
+ def indent(s)
15
+ s.gsub(/^(?=.)/, " " * INDENT_STEP)
16
+ end
17
+ end
18
+ end
19
+
20
+ # Represents RSpec's "it" block.
21
+ class It
22
+ def initialize(attrs)
23
+ @description = attrs[:description]
24
+ @code = attrs[:code]
25
+ @skip = attrs[:skip]
26
+ end
27
+
28
+ def render
29
+ [
30
+ "#{@skip ? "xit" : "it"} #{@description.inspect} do",
31
+ Code.indent(@code),
32
+ "end"
33
+ ].join("\n")
34
+ end
35
+ end
36
+
37
+ # Represents RSpec's "describe" block.
38
+ class Describe
39
+ attr_reader :blocks
40
+
41
+ def initialize(attrs)
42
+ @description = attrs[:description]
43
+ @blocks = attrs[:blocks]
44
+ end
45
+
46
+ def render
47
+ parts = []
48
+ parts << "describe #{@description.inspect} do"
49
+ parts << Code.indent(@blocks.map(&:render).join("\n\n")) if !blocks.empty?
50
+ parts << "end"
51
+ parts.join("\n")
52
+ end
53
+ end
54
+
55
+ # Renders a Markdown file to an RSpec test script
56
+ class RSpecRenderer < Redcarpet::Render::Base
57
+ include RspecCode
58
+
59
+ IGNORED_HEADERS = [
60
+ "Table Of Contents",
61
+ "Description"
62
+ ]
63
+
64
+ def initialize
65
+ super
66
+
67
+ @next_block_type = :unknown
68
+ @describe = Describe.new(description: "RuboCop-Yast", blocks: [])
69
+ end
70
+
71
+ # preprocess the MarkDown input - remove comments
72
+ def preprocess(fulldoc)
73
+ # use multiline regexp pattern
74
+ fulldoc.gsub(/<!--.*-->/m, "")
75
+ end
76
+
77
+ def header(text, header_level)
78
+ return nil if header_level == 1 || IGNORED_HEADERS.include?(text)
79
+
80
+ if header_level > describes_depth + 1
81
+ raise "Missing higher level header: #{text}"
82
+ end
83
+
84
+ describe_at_level(header_level - 1).blocks << Describe.new(
85
+ description: text + ":",
86
+ blocks: []
87
+ )
88
+
89
+ nil
90
+ end
91
+
92
+ def paragraph(text)
93
+ if text =~ /^\*\*(.*)\*\*$/
94
+ @next_block_type = Regexp.last_match[1].downcase.to_sym
95
+ else
96
+ first_sentence = text.split(/\.(\s+|$)/).first
97
+ @description = first_sentence.sub(/^RuboCop-Yast /, "").sub(/\n/, " ")
98
+ end
99
+
100
+ nil
101
+ end
102
+
103
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity:
104
+ def block_code(code, _language)
105
+ escaped_code = escape(code[0..-2])
106
+
107
+ case @next_block_type
108
+ when :original
109
+ @original_code = escaped_code
110
+ when :translated
111
+ @translated_code = escaped_code
112
+ when :unchanged
113
+ @original_code = @translated_code = escaped_code
114
+ when :offense
115
+ @offense = escaped_code
116
+ when :accepted
117
+ @accepted_code = escaped_code
118
+ else
119
+ raise "Invalid next code block type: #{@next_block_type}.\n#{code}"
120
+ end
121
+
122
+ @next_block_type = :unknown
123
+
124
+ add_translation_block if @original_code && @translated_code
125
+ add_offense_block if @offense
126
+ add_accepted_block if @accepted_code
127
+
128
+ nil
129
+ end
130
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity:
131
+
132
+ # escape ruby interpolation
133
+ def escape(code)
134
+ code.gsub("\#{", "\\\#{")
135
+ end
136
+
137
+ def doc_header
138
+ Code.join([
139
+ "# Automatically generated -- DO NOT EDIT!",
140
+ "",
141
+ "require \"spec_helper\"",
142
+ ""
143
+ ])
144
+ end
145
+
146
+ def doc_footer
147
+ "#{@describe.render}\n"
148
+ end
149
+
150
+ private
151
+
152
+ def describes_depth
153
+ describe = @describe
154
+ depth = 1
155
+ while describe.blocks.last.is_a?(Describe)
156
+ describe = describe.blocks.last
157
+ depth += 1
158
+ end
159
+ depth
160
+ end
161
+
162
+ def current_describe
163
+ describe = @describe
164
+ describe = describe.blocks.last while describe.blocks.last.is_a?(Describe)
165
+ describe
166
+ end
167
+
168
+ def describe_at_level(level)
169
+ describe = @describe
170
+ 2.upto(level) do
171
+ describe = describe.blocks.last
172
+ end
173
+ describe
174
+ end
175
+
176
+ def add_translation_block
177
+ current_describe.blocks << It.new(
178
+ description: @description,
179
+ code: generate_translation_code,
180
+ skip: @description =~ /XFAIL/
181
+ )
182
+
183
+ @original_code = nil
184
+ @translated_code = nil
185
+ end
186
+
187
+ def add_offense_block
188
+ current_describe.blocks << It.new(
189
+ description: @description,
190
+ code: generate_offense_code,
191
+ skip: @description =~ /XFAIL/
192
+ )
193
+
194
+ @offense = nil
195
+ end
196
+
197
+ def add_accepted_block
198
+ current_describe.blocks << It.new(
199
+ description: @description,
200
+ code: generate_accepted_code,
201
+ skip: @description =~ /XFAIL/
202
+ )
203
+
204
+ @accepted_code = nil
205
+ end
206
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,21 +1,23 @@
1
1
  # encoding: utf-8
2
2
 
3
- if ENV["COVERAGE"]
4
- require "simplecov"
3
+ require "simplecov"
5
4
 
6
- # use coveralls for on-line code coverage reporting at Travis CI
7
- if ENV["TRAVIS"]
8
- require "coveralls"
5
+ # use coveralls for on-line code coverage reporting at Travis CI
6
+ if ENV["TRAVIS"]
7
+ require "coveralls"
9
8
 
10
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
11
- SimpleCov::Formatter::HTMLFormatter,
12
- Coveralls::SimpleCov::Formatter
13
- ]
14
- end
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ Coveralls::SimpleCov::Formatter
12
+ ]
13
+ end
15
14
 
16
- SimpleCov.minimum_coverage 95
15
+ SimpleCov.minimum_coverage 95
17
16
 
18
- SimpleCov.start
17
+ SimpleCov.start do
18
+ # don't check code coverage in these subdirectories
19
+ add_filter "/vendor/"
20
+ add_filter "/spec/"
19
21
  end
20
22
 
21
23
  # allow only the new "expect" RSpec syntax
@@ -29,11 +31,17 @@ RSpec.configure do |config|
29
31
  end
30
32
  end
31
33
 
32
- # As much as possible, we try to reuse RuboCop's spec environment.
34
+ # reuse the Rubocop helper, provides some nice methods used in tests
33
35
  require File.join(
34
36
  Gem::Specification.find_by_name("rubocop").gem_dir, "spec", "spec_helper.rb"
35
37
  )
36
38
 
37
39
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
38
40
 
41
+ def code_cleanup(s)
42
+ s.split("\n").reject { |l| l =~ /^\s*$/ }.first =~ /^(\s*)/
43
+ return s.dup if Regexp.last_match.nil?
44
+ s.gsub(Regexp.new("^#{Regexp.last_match[1]}"), "")[0..-2]
45
+ end
46
+
39
47
  require "rubocop-yast"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-yast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ladislav Slezák
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-03 00:00:00.000000000 Z
11
+ date: 2014-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redcarpet
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -85,13 +99,23 @@ files:
85
99
  - lib/rubocop-yast.rb
86
100
  - lib/rubocop/cop/yast/builtins.rb
87
101
  - lib/rubocop/cop/yast/ops.rb
102
+ - lib/rubocop/yast/builtins/builtin.rb
103
+ - lib/rubocop/yast/builtins/getenv.rb
104
+ - lib/rubocop/yast/builtins/time.rb
105
+ - lib/rubocop/yast/builtins/y2log.rb
88
106
  - lib/rubocop/yast/config.rb
89
107
  - lib/rubocop/yast/niceness.rb
108
+ - lib/rubocop/yast/node_helpers.rb
109
+ - lib/rubocop/yast/reformatter.rb
110
+ - lib/rubocop/yast/track_variable_scope.rb
90
111
  - lib/rubocop/yast/variable_scope.rb
91
112
  - lib/rubocop/yast/version.rb
92
113
  - rubocop-yast.gemspec
114
+ - spec/builtins_spec.md
93
115
  - spec/builtins_spec.rb
94
116
  - spec/ops_spec.rb
117
+ - spec/rspec_code.rb
118
+ - spec/rspec_renderer.rb
95
119
  - spec/spec_helper.rb
96
120
  homepage: http://github.com/yast/rubocop-yast
97
121
  licenses:
@@ -118,6 +142,9 @@ signing_key:
118
142
  specification_version: 4
119
143
  summary: Specific YaST Rubocop checks
120
144
  test_files:
145
+ - spec/builtins_spec.md
121
146
  - spec/builtins_spec.rb
122
147
  - spec/ops_spec.rb
148
+ - spec/rspec_code.rb
149
+ - spec/rspec_renderer.rb
123
150
  - spec/spec_helper.rb