rubocop-yast 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c59e960c99f00013d3881020fe1d576e9d67ab91
4
- data.tar.gz: 89d463fb18eb4d31ad00df25be33621cd4309446
3
+ metadata.gz: ab9d34ebc702b4f960ea9052af25796369d11d60
4
+ data.tar.gz: 0562543d6aca25bd76a0f933fcfd8670cde680cf
5
5
  SHA512:
6
- metadata.gz: f6f08655ccfef688328df7f9f245df9c963ed4a55c963ae81b40395e71befa4fca00f50c8fba339f80223689863a24d51c49ff41e923d166880555d2efb02087
7
- data.tar.gz: ea903ebf6261f79f6a7e7b3646648d198ae0432b3da2e301dbc2b29a1d07e23a7c8b9ddcf849f4d3c46b221b6d0ff11ef97879952bedbde3c66e8bc4d2fb834e
6
+ metadata.gz: 8f8c2c95efd7d2e58b78258fae535b1e3c671dbfdb3a108daf9231ae7224f46d21b81912622951635065c0c5364faaa0f509b68b95815992427412e8ee6a5784
7
+ data.tar.gz: 9fe4dfebd32eea8427cf671018187e60361d99fdb5089e3e4c1d35c2db30278ac11689a1823b233bf5e5dadb5f45e53b37828977dc8e85354d46acbc5392d06e
@@ -2,7 +2,24 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
- ## 0.0.6 (15/12/2014)
5
+ ## 0.0.8 (2015-12-11)
6
+
7
+ ### New Features
8
+
9
+ - Nearly all Cucumber features converted from Zombie Killer work.
10
+ The exception is a `retry` in `rescue`.
11
+
12
+ ## 0.0.7 (2015-12-08)
13
+
14
+ ### Changes
15
+
16
+ - Added Cucumber features converted from the Zombie Killer spec.
17
+ Some of them are marked as pending because they don't work yet.
18
+ - SafeMode config removed, it is always enabled instead.
19
+ - StrictMode config added, enabled by default: report all Ops, even if they
20
+ cannot be autocorrected.
21
+
22
+ ## 0.0.6 (2014-12-15)
6
23
 
7
24
  ### New Features
8
25
 
data/README.md CHANGED
@@ -67,8 +67,9 @@ Yast/Builtins:
67
67
  # Check for obsolete Ops.* calls
68
68
  Yast/Ops:
69
69
  Enabled: true
70
- # in the safe mode only safe places are reported and fixed
71
- SafeMode: true
70
+ # in strict mode all Ops calls are reported
71
+ # even if they cannot be autocorrected
72
+ StrictMode: true
72
73
  ```
73
74
 
74
75
  Development
data/Rakefile CHANGED
@@ -13,10 +13,7 @@ end
13
13
  require "cucumber/rake/task"
14
14
  Cucumber::Rake::Task.new(:features)
15
15
 
16
- require "rspec/core/rake_task"
17
- RSpec::Core::RakeTask.new(:spec)
18
-
19
16
  require "rubocop/rake_task"
20
17
  RuboCop::RakeTask.new(:rubocop)
21
18
 
22
- task default: [:spec, :features, :rubocop]
19
+ task default: [:features, :rubocop]
@@ -5,7 +5,7 @@ Yast/Builtins:
5
5
  Yast/Ops:
6
6
  Description: "Check for obsolete Ops.* calls"
7
7
  Enabled: true
8
- SafeMode: true
8
+ StrictMode: true
9
9
 
10
10
  Yast/LogVariable:
11
11
  Description: "Check for using 'log' variable"
@@ -6,6 +6,7 @@ require_relative "rubocop/yast/config"
6
6
  RuboCop::Yast::Config.load_defaults
7
7
 
8
8
  require_relative "rubocop/yast/version"
9
+ require_relative "rubocop/yast/logger"
9
10
  require_relative "rubocop/cop/yast/builtins"
10
11
  require_relative "rubocop/cop/yast/ops"
11
12
  require_relative "rubocop/cop/yast/log_variable"
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "rubocop/yast/track_variable_scope"
4
+ require "unparser"
4
5
 
5
6
  # We have encountered code that does satisfy our simplifying assumptions,
6
7
  # translating it would not be correct.
@@ -10,63 +11,98 @@ end
10
11
  module RuboCop
11
12
  module Cop
12
13
  module Yast
13
- # This cop checks for Ops.* calls, it can autocorrect safe places or
14
- # all places in unsafe mode
14
+ # This cop checks for Ops.* calls aka Zombies.
15
+ # Some of these can be autocorrected, mostly when we can prove
16
+ # that their arguments cannot be nil.
17
+ # In Strict Mode, it reports all zombies.
18
+ # In Permissive Mode, it report only zombies that can be autocorrected.
15
19
  class Ops < Cop
16
- include RuboCop::Yast::TrackVariableScope
17
-
18
20
  # Ops replacement mapping
19
21
  REPLACEMENT = {
20
- add: "+"
22
+ add: :+,
23
+ # divide: :/, # must also check divisor nonzero
24
+ # greater_than::>, # handle ycp comparison
25
+ # greater_or_equal: :>=,# handle ycp comparison
26
+ # less_than: :<, # handle ycp comparison
27
+ # less_or_equal: :<=, # handle ycp comparison
28
+ modulo: :%,
29
+ multiply: :*,
30
+ subtract: :-
21
31
  }
22
32
 
23
- MSG = "Obsolete Ops.%s call found"
24
-
25
33
  def initialize(config = nil, options = nil)
26
34
  super(config, options)
27
35
 
28
- @safe_mode = cop_config && cop_config["SafeMode"]
36
+ @strict_mode = cop_config && cop_config["StrictMode"]
29
37
  @replaced_nodes = []
38
+ @processor = OpsProcessor.new(self)
30
39
  end
31
40
 
32
- def on_send(node)
33
- return unless call?(node, :Ops, :add)
34
-
35
- _ops, method, a, b = *node
36
- return if !(nice(a) && nice(b)) && safe_mode
37
-
38
- add_offense(node, :selector, format(MSG, method))
41
+ def investigate(processed_source)
42
+ @processor.investigate(processed_source)
39
43
  end
40
44
 
41
- private
45
+ attr_reader :strict_mode
42
46
 
43
- def call?(node, namespace, message)
44
- n_receiver, n_message = *node
45
- n_receiver && n_receiver.type == :const &&
46
- n_receiver.children[0].nil? &&
47
- n_receiver.children[1] == namespace &&
48
- n_message == message
49
- end
47
+ private
50
48
 
51
49
  def autocorrect(node)
52
- @corrections << lambda do |corrector|
53
- _ops, message, arg1, arg2 = *node
50
+ return unless @processor.autocorrectable?(node)
51
+
52
+ _ops, message, arg1, arg2 = *node
54
53
 
55
- new_ops = REPLACEMENT[message]
56
- return unless new_ops
54
+ new_op = REPLACEMENT[message]
55
+ return unless new_op
57
56
 
58
- corrector.replace(node.loc.expression,
59
- ops_replacement(new_ops, arg1, arg2))
57
+ @corrections << lambda do |corrector|
58
+ source_range = node.loc.expression
59
+ next if contains_comment?(source_range.source)
60
+ new_node = Parser::AST::Node.new(:send, [arg1, new_op, arg2])
61
+ corrector.replace(source_range, Unparser.unparse(new_node))
60
62
  end
61
63
  end
62
64
 
63
- def ops_replacement(new_ops, arg1, arg2)
64
- "#{arg1.loc.expression.source} #{new_ops} " \
65
- "#{arg2.loc.expression.source}"
65
+ def contains_comment?(string)
66
+ /^[^'"\n]*#/.match(string)
66
67
  end
67
-
68
- attr_reader :safe_mode
69
68
  end
70
69
  end
71
70
  end
72
71
  end
72
+
73
+ # Niceness processor really
74
+ class OpsProcessor < Parser::AST::Processor
75
+ include RuboCop::Yast::TrackVariableScope
76
+ include RuboCop::Cop::Util # const_name
77
+
78
+ attr_reader :cop
79
+
80
+ def initialize(cop)
81
+ @cop = cop
82
+ end
83
+
84
+ def investigate(processed_source)
85
+ process(processed_source.ast)
86
+ end
87
+
88
+ MSG = "Obsolete Ops.%s call found"
89
+
90
+ def on_send(node)
91
+ super
92
+
93
+ receiver, message = *node
94
+ return unless const_name(receiver) == "Ops"
95
+ return unless RuboCop::Cop::Yast::Ops::REPLACEMENT.key?(message)
96
+ return unless cop.strict_mode || autocorrectable?(node)
97
+ cop.add_offense(node, :selector, format(MSG, message))
98
+ end
99
+
100
+ # assumes node is an Ops.add
101
+ def autocorrectable?(node)
102
+ RuboCop::Yast.logger.debug "AUTOCORRECTABLE?(#{node.inspect})"
103
+ RuboCop::Yast.logger.debug "CUR SCOPE #{scope.inspect}"
104
+
105
+ _ops, _method, a, b = *node
106
+ nice(a) && nice(b)
107
+ end
108
+ end
@@ -0,0 +1,28 @@
1
+ require "logger"
2
+
3
+ module RuboCop
4
+ # Yast specific helpers
5
+ module Yast
6
+ def logger
7
+ return @logger if @logger
8
+
9
+ @logger = ::Logger.new(STDERR)
10
+ @logger.level = ::Logger::WARN
11
+ @logger.level = ::Logger::DEBUG if $DEBUG
12
+ @logger
13
+ end
14
+ module_function :logger
15
+
16
+ def backtrace(skip_frames: 0)
17
+ c = caller
18
+ lines = []
19
+ c.reverse.drop(skip_frames).each_with_index do |frame, i|
20
+ lines << "#{i}: #{frame}"
21
+ end
22
+ lines.reverse_each do |l|
23
+ puts l
24
+ end
25
+ end
26
+ module_function :backtrace
27
+ end
28
+ end
@@ -18,7 +18,7 @@ module Niceness
18
18
 
19
19
  def nice(node)
20
20
  nice_literal(node) || nice_variable(node) || nice_send(node) ||
21
- nice_begin(node)
21
+ nice_sformat(node) || nice_begin(node)
22
22
  end
23
23
 
24
24
  def nice_literal(node)
@@ -54,7 +54,25 @@ module Niceness
54
54
  args.size == arity && args.all? { |a| nice(a) }
55
55
  end
56
56
 
57
+ # Builtins.sformat is special in that it can produce nil
58
+ # but only if the format string is nil which is fortunately
59
+ # easy to rule out. Other args may be ugly but we don't care.
60
+ def nice_sformat(node)
61
+ return false unless node.type == :send
62
+ return false unless call?(node, :Builtins, :sformat)
63
+ _builtins, _sformat, format_string, *_other_args = *node
64
+ nice(format_string)
65
+ end
66
+
57
67
  def nice_begin(node)
58
68
  node.type == :begin && nice(node.children.last)
59
69
  end
70
+
71
+ def call?(node, namespace, message)
72
+ n_receiver, n_message = *node
73
+ n_receiver && n_receiver.type == :const &&
74
+ n_receiver.children[0].nil? &&
75
+ n_receiver.children[1] == namespace &&
76
+ n_message == message
77
+ end
60
78
  end
@@ -18,15 +18,6 @@ module RuboCop
18
18
  @scopes ||= VariableScopeStack.new
19
19
  end
20
20
 
21
- # FIXME
22
- def process(node)
23
- return if node.nil?
24
- # if ! @unsafe
25
- # oops(node, RuntimeError.new("Unknown node type #{node.type}")) \
26
- # unless HANDLED_NODE_TYPES.include? node.type
27
- # end
28
- end
29
-
30
21
  # currently visible scope
31
22
  def scope
32
23
  scopes.innermost
@@ -41,23 +32,46 @@ module RuboCop
41
32
  end
42
33
 
43
34
  def on_def(node)
44
- with_new_scope_rescuing_oops(node)
35
+ name, _, _ = *node
36
+ RuboCop::Yast.logger.debug "ONDEF #{name}"
37
+ RuboCop::Yast.logger.debug "CUR SCOPE #{scope.inspect}"
38
+ RuboCop::Yast.backtrace skip_frames: 50 if $DEBUG
39
+
40
+ with_new_scope_rescuing_oops(node) { super }
45
41
  end
46
42
 
47
43
  def on_defs(node)
48
- with_new_scope_rescuing_oops(node)
44
+ with_new_scope_rescuing_oops(node) { super }
49
45
  end
50
46
 
51
47
  def on_module(node)
52
- with_new_scope_rescuing_oops(node)
48
+ with_new_scope_rescuing_oops(node) { super }
53
49
  end
54
50
 
55
51
  def on_class(node)
56
- with_new_scope_rescuing_oops(node)
52
+ with_new_scope_rescuing_oops(node) { super }
57
53
  end
58
54
 
59
55
  def on_sclass(node)
60
- with_new_scope_rescuing_oops(node)
56
+ with_new_scope_rescuing_oops(node) { super }
57
+ end
58
+
59
+ def on_if(node)
60
+ cond, then_body, else_body = *node
61
+ process(cond)
62
+
63
+ scopes.with_copy do
64
+ process(then_body)
65
+ end
66
+
67
+ scopes.with_copy do
68
+ process(else_body)
69
+ end
70
+
71
+ # clean slate
72
+ scope.clear
73
+
74
+ node
61
75
  end
62
76
 
63
77
  # def on_unless
@@ -79,36 +93,46 @@ module RuboCop
79
93
 
80
94
  # clean slate
81
95
  scope.clear
96
+
97
+ node
82
98
  end
83
99
 
84
100
  def on_lvasgn(node)
101
+ super
85
102
  name, value = * node
86
103
  return if value.nil? # and-asgn, or-asgn, resbody do this
87
104
  scope[name].nice = nice(value)
105
+ node
88
106
  end
89
107
 
90
108
  def on_and_asgn(node)
109
+ super
91
110
  var, value = *node
92
111
  bool_op_asgn(var, value, :and)
112
+ node
93
113
  end
94
114
 
95
115
  def on_or_asgn(node)
116
+ super
96
117
  var, value = *node
97
118
  bool_op_asgn(var, value, :or)
119
+ node
98
120
  end
99
121
 
100
- def on_block(_node)
122
+ def on_block(node)
101
123
  # ignore body, clean slate
102
124
  scope.clear
125
+ node
103
126
  end
104
127
  alias_method :on_for, :on_block
105
128
 
106
- def on_while(_node)
129
+ def on_while(node)
107
130
  # ignore both condition and body,
108
131
  # with a simplistic scope we cannot handle them
109
132
 
110
133
  # clean slate
111
134
  scope.clear
135
+ node
112
136
  end
113
137
  alias_method :on_until, :on_while
114
138
 
@@ -117,22 +141,24 @@ module RuboCop
117
141
 
118
142
  def on_rescue(node)
119
143
  # (:rescue, begin-block, resbody..., else-block-or-nil)
120
- _begin_body, *_rescue_bodies, _else_body = *node
121
-
122
- # FIXME
123
- # @source_rewriter.transaction do
124
- # process(begin_body)
125
- # process(else_body)
126
- # rescue_bodies.each do |r|
127
- # process(r)
128
- # end
129
- # end
130
- # rescue TooComplexToTranslateError
131
- # warning "begin-rescue is too complex to translate due to a retry"
144
+ begin_body, *rescue_bodies, else_body = *node
145
+
146
+ # FIXME: the transaction must be rolled back
147
+ # by the TooComplexToTranslateError
148
+ # @source_rewriter.transaction do
149
+ process(begin_body)
150
+ process(else_body)
151
+ rescue_bodies.each do |r|
152
+ process(r)
153
+ end
132
154
  # end
155
+ node
156
+ rescue TooComplexToTranslateError
157
+ warn "begin-rescue is too complex to translate due to a retry"
158
+ node
133
159
  end
134
160
 
135
- def on_resbody(_node)
161
+ def on_resbody(node)
136
162
  # How it is parsed:
137
163
  # (:resbody, exception-types-or-nil, exception-variable-or-nil, body)
138
164
  # exception-types is an :array
@@ -143,19 +169,20 @@ module RuboCop
143
169
  # and join begin-block with else-block, but it is little worth
144
170
  # because they will contain few zombies.
145
171
  scope.clear
172
+ super
146
173
  end
147
174
 
148
- def on_ensure(_node)
175
+ def on_ensure(node)
149
176
  # (:ensure, guarded-code, ensuring-code)
150
177
  # guarded-code may be a :rescue or not
151
178
 
152
179
  scope.clear
180
+ node
153
181
  end
154
182
 
155
183
  def on_retry(_node)
156
184
  # that makes the :rescue a loop, top-down data-flow fails
157
- # FIXME
158
- # raise TooComplexToTranslateError
185
+ raise TooComplexToTranslateError
159
186
  end
160
187
 
161
188
  private
@@ -1,6 +1,15 @@
1
1
  # Tracks state for a variable
2
2
  class VariableState
3
- attr_accessor :nice
3
+ def nice
4
+ RuboCop::Yast.logger.debug "GETN #{inspect}"
5
+ @nice
6
+ end
7
+
8
+ def nice=(v)
9
+ @nice = v
10
+ RuboCop::Yast.logger.debug "SETN #{inspect}"
11
+ v
12
+ end
4
13
  end
5
14
 
6
15
  # Tracks state for local variables visible at certain point.
@@ -23,11 +32,14 @@ class VariableScope < Hash
23
32
 
24
33
  # @return [VariableState] state
25
34
  def [](varname)
26
- super
35
+ v = super
36
+ RuboCop::Yast.logger.debug "GET #{varname} -> #{v}"
37
+ v
27
38
  end
28
39
 
29
40
  # Set state for a variable
30
41
  def []=(varname, state)
42
+ RuboCop::Yast.logger.debug "SET #{varname} -> #{state}"
31
43
  super
32
44
  end
33
45
 
@@ -50,6 +62,7 @@ class VariableScopeStack
50
62
  # @return the scope as the block left it, popped from the stack
51
63
  def with_new(&block)
52
64
  @stack.push VariableScope.new
65
+ RuboCop::Yast.logger.debug "SCOPES #{@stack.inspect}"
53
66
  block.call
54
67
  @stack.pop
55
68
  end
@@ -3,6 +3,6 @@
3
3
  module RuboCop
4
4
  # Yast plugin settings
5
5
  module Yast
6
- VERSION = "0.0.6"
6
+ VERSION = "0.0.8"
7
7
  end
8
8
  end
@@ -24,11 +24,12 @@ Gem::Specification.new do |spec|
24
24
  "*.gemspec",
25
25
  "Gemfile",
26
26
  "Rakefile"
27
- ]
27
+ ].reject { |f| f =~ /~$/ }
28
28
  spec.test_files = spec.files.grep(/^spec\//)
29
29
  spec.extra_rdoc_files = ["LICENSE", "README.md"]
30
30
 
31
- spec.add_runtime_dependency("rubocop", "~> 0.27")
31
+ spec.add_runtime_dependency("rubocop", "~> 0.29.1")
32
+ spec.add_runtime_dependency("unparser", "~> 0")
32
33
 
33
34
  spec.add_development_dependency("rake")
34
35
  spec.add_development_dependency("rspec", "~> 3.1.0")
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.6
4
+ version: 0.0.8
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-16 00:00:00.000000000 Z
11
+ date: 2015-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.27'
19
+ version: 0.29.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.27'
26
+ version: 0.29.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: unparser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -106,6 +120,7 @@ files:
106
120
  - lib/rubocop/yast/builtins/time.rb
107
121
  - lib/rubocop/yast/builtins/y2log.rb
108
122
  - lib/rubocop/yast/config.rb
123
+ - lib/rubocop/yast/logger.rb
109
124
  - lib/rubocop/yast/niceness.rb
110
125
  - lib/rubocop/yast/node_helpers.rb
111
126
  - lib/rubocop/yast/reformatter.rb
@@ -113,9 +128,6 @@ files:
113
128
  - lib/rubocop/yast/variable_scope.rb
114
129
  - lib/rubocop/yast/version.rb
115
130
  - rubocop-yast.gemspec
116
- - spec/builtins_spec.rb
117
- - spec/ops_spec.rb
118
- - spec/spec_helper.rb
119
131
  homepage: http://github.com/yast/rubocop-yast
120
132
  licenses:
121
133
  - MIT
@@ -140,7 +152,4 @@ rubygems_version: 2.2.2
140
152
  signing_key:
141
153
  specification_version: 4
142
154
  summary: Specific YaST Rubocop checks
143
- test_files:
144
- - spec/builtins_spec.rb
145
- - spec/ops_spec.rb
146
- - spec/spec_helper.rb
155
+ test_files: []
@@ -1,560 +0,0 @@
1
- # Automatically generated -- DO NOT EDIT!
2
-
3
- require "spec_helper"
4
-
5
- describe "RuboCop::Cop::Yast::Builtins" do
6
- describe "Generic Tests:" do
7
- it "It reports y2milestone builtin as offense" do
8
- code = code_cleanup(<<-EOT)
9
- Builtins.y2milestone("foo")
10
- EOT
11
-
12
- cop = RuboCop::Cop::Yast::Builtins.new
13
- inspect_source(cop, [code])
14
-
15
- expect(cop.offenses.size).to eq(1)
16
- end
17
-
18
- it "It finds builtin in explicit Yast namespace" do
19
- code = code_cleanup(<<-EOT)
20
- Yast::Builtins.y2milestone("foo")
21
- EOT
22
-
23
- cop = RuboCop::Cop::Yast::Builtins.new
24
- inspect_source(cop, [code])
25
-
26
- expect(cop.offenses.size).to eq(1)
27
- end
28
-
29
- it "It finds builtin in explicit ::Yast namespace" do
30
- code = code_cleanup(<<-EOT)
31
- ::Yast::Builtins.y2milestone("foo")
32
- EOT
33
-
34
- cop = RuboCop::Cop::Yast::Builtins.new
35
- inspect_source(cop, [code])
36
-
37
- expect(cop.offenses.size).to eq(1)
38
- end
39
-
40
- it "Builtins in the ::Builtins name space are ignored" do
41
- code = code_cleanup(<<-EOT)
42
- ::Builtins.y2milestone("foo")
43
- EOT
44
-
45
- cop = RuboCop::Cop::Yast::Builtins.new
46
- inspect_source(cop, [code])
47
-
48
- expect(cop.offenses).to be_empty
49
- end
50
-
51
- it "Builtins in non Yast name space are ignored" do
52
- code = code_cleanup(<<-EOT)
53
- Foo::Builtins.y2milestone("foo")
54
- EOT
55
-
56
- cop = RuboCop::Cop::Yast::Builtins.new
57
- inspect_source(cop, [code])
58
-
59
- expect(cop.offenses).to be_empty
60
- end
61
-
62
- it "lsort(), crypt and gettext builtins are allowed" do
63
- code = code_cleanup(<<-EOT)
64
- Builtins.lsort(["foo"])
65
- Builtins.crypt("foo")
66
- Builtins.dgettext("domain", "foo")
67
- EOT
68
-
69
- cop = RuboCop::Cop::Yast::Builtins.new
70
- inspect_source(cop, [code])
71
-
72
- expect(cop.offenses).to be_empty
73
- end
74
-
75
- it "It does not change unknown builtins" do
76
- original_code = code_cleanup(<<-EOT)
77
- Builtins.foo()
78
- EOT
79
-
80
- translated_code = code_cleanup(<<-EOT)
81
- Builtins.foo()
82
- EOT
83
-
84
- cop = RuboCop::Cop::Yast::Builtins.new
85
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
86
- end
87
- end
88
-
89
- describe "Builtins.getenv():" do
90
- it "With string literal parameter is translated to ENV equivalent" do
91
- original_code = code_cleanup(<<-EOT)
92
- Builtins.getenv("foo")
93
- EOT
94
-
95
- translated_code = code_cleanup(<<-EOT)
96
- ENV["foo"]
97
- EOT
98
-
99
- cop = RuboCop::Cop::Yast::Builtins.new
100
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
101
- end
102
-
103
- it "Variable as parameter is preserved" do
104
- original_code = code_cleanup(<<-EOT)
105
- foo = bar
106
- Builtins.getenv(foo)
107
- EOT
108
-
109
- translated_code = code_cleanup(<<-EOT)
110
- foo = bar
111
- ENV[foo]
112
- EOT
113
-
114
- cop = RuboCop::Cop::Yast::Builtins.new
115
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
116
- end
117
-
118
- it "Any other statement is preserved" do
119
- original_code = code_cleanup(<<-EOT)
120
- Builtins.getenv(Ops.add(foo, bar))
121
- EOT
122
-
123
- translated_code = code_cleanup(<<-EOT)
124
- ENV[Ops.add(foo, bar)]
125
- EOT
126
-
127
- cop = RuboCop::Cop::Yast::Builtins.new
128
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
129
- end
130
- end
131
-
132
- describe "Logging - Builtins.y2debug(), ...:" do
133
- it "It translates `y2debug` to `log.debug`" do
134
- original_code = code_cleanup(<<-EOT)
135
- Builtins.y2debug("foo")
136
- EOT
137
-
138
- translated_code = code_cleanup(<<-EOT)
139
- include Yast::Logger
140
- log.debug "foo"
141
- EOT
142
-
143
- cop = RuboCop::Cop::Yast::Builtins.new
144
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
145
- end
146
-
147
- it "It translates `y2milestone` to `log.info`" do
148
- original_code = code_cleanup(<<-EOT)
149
- Builtins.y2milestone("foo")
150
- EOT
151
-
152
- translated_code = code_cleanup(<<-EOT)
153
- include Yast::Logger
154
- log.info "foo"
155
- EOT
156
-
157
- cop = RuboCop::Cop::Yast::Builtins.new
158
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
159
- end
160
-
161
- it "It translates `y2warning` to `log.warn`" do
162
- original_code = code_cleanup(<<-EOT)
163
- Builtins.y2warning("foo")
164
- EOT
165
-
166
- translated_code = code_cleanup(<<-EOT)
167
- include Yast::Logger
168
- log.warn "foo"
169
- EOT
170
-
171
- cop = RuboCop::Cop::Yast::Builtins.new
172
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
173
- end
174
-
175
- it "It translates `y2error` to `log.error`" do
176
- original_code = code_cleanup(<<-EOT)
177
- Builtins.y2error("foo")
178
- EOT
179
-
180
- translated_code = code_cleanup(<<-EOT)
181
- include Yast::Logger
182
- log.error "foo"
183
- EOT
184
-
185
- cop = RuboCop::Cop::Yast::Builtins.new
186
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
187
- end
188
-
189
- it "It translates `y2security` to `log.error`" do
190
- original_code = code_cleanup(<<-EOT)
191
- Builtins.y2security("foo")
192
- EOT
193
-
194
- translated_code = code_cleanup(<<-EOT)
195
- include Yast::Logger
196
- log.error "foo"
197
- EOT
198
-
199
- cop = RuboCop::Cop::Yast::Builtins.new
200
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
201
- end
202
-
203
- it "It translates `y2internal` to `log.fatal`" do
204
- original_code = code_cleanup(<<-EOT)
205
- Builtins.y2internal("foo")
206
- EOT
207
-
208
- translated_code = code_cleanup(<<-EOT)
209
- include Yast::Logger
210
- log.fatal "foo"
211
- EOT
212
-
213
- cop = RuboCop::Cop::Yast::Builtins.new
214
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
215
- end
216
-
217
- it "It adds the include statement only once" do
218
- original_code = code_cleanup(<<-EOT)
219
- Builtins.y2milestone("foo")
220
- Builtins.y2milestone("foo")
221
- EOT
222
-
223
- translated_code = code_cleanup(<<-EOT)
224
- include Yast::Logger
225
- log.info \"foo\"
226
- log.info \"foo\"
227
- EOT
228
-
229
- cop = RuboCop::Cop::Yast::Builtins.new
230
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
231
- end
232
-
233
- it "It converts YCP sformat to Ruby interpolation" do
234
- original_code = code_cleanup(<<-EOT)
235
- Builtins.y2milestone("foo: %1", foo)
236
- EOT
237
-
238
- translated_code = code_cleanup(<<-EOT)
239
- include Yast::Logger
240
- log.info "foo: \#{foo}"
241
- EOT
242
-
243
- cop = RuboCop::Cop::Yast::Builtins.new
244
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
245
- end
246
-
247
- it "It converts %% in the format string to simple %" do
248
- original_code = code_cleanup(<<-EOT)
249
- Builtins.y2milestone("foo: %1%%", foo)
250
- EOT
251
-
252
- translated_code = code_cleanup(<<-EOT)
253
- include Yast::Logger
254
- log.info "foo: \#{foo}%"
255
- EOT
256
-
257
- cop = RuboCop::Cop::Yast::Builtins.new
258
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
259
- end
260
-
261
- it "It replaces repeated % placeholders in the format string" do
262
- original_code = code_cleanup(<<-EOT)
263
- Builtins.y2warning("%1 %1", foo)
264
- EOT
265
-
266
- translated_code = code_cleanup(<<-EOT)
267
- include Yast::Logger
268
- log.warn "\#{foo} \#{foo}"
269
- EOT
270
-
271
- cop = RuboCop::Cop::Yast::Builtins.new
272
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
273
- end
274
-
275
- it "The % placeholders do not need to start from 1" do
276
- original_code = code_cleanup(<<-EOT)
277
- Builtins.y2warning("%2 %2", foo, bar)
278
- EOT
279
-
280
- translated_code = code_cleanup(<<-EOT)
281
- include Yast::Logger
282
- log.warn "\#{bar} \#{bar}"
283
- EOT
284
-
285
- cop = RuboCop::Cop::Yast::Builtins.new
286
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
287
- end
288
-
289
- it "The % placeholders do not need to be in ascending order" do
290
- original_code = code_cleanup(<<-EOT)
291
- Builtins.y2warning("%2 %1", foo, bar)
292
- EOT
293
-
294
- translated_code = code_cleanup(<<-EOT)
295
- include Yast::Logger
296
- log.warn "\#{bar} \#{foo}"
297
- EOT
298
-
299
- cop = RuboCop::Cop::Yast::Builtins.new
300
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
301
- end
302
-
303
- it "It keeps the original statements in interpolated string" do
304
- original_code = code_cleanup(<<-EOT)
305
- Builtins.y2warning("%1", foo + bar)
306
- EOT
307
-
308
- translated_code = code_cleanup(<<-EOT)
309
- include Yast::Logger
310
- log.warn "\#{foo + bar}"
311
- EOT
312
-
313
- cop = RuboCop::Cop::Yast::Builtins.new
314
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
315
- end
316
-
317
- it "It converts a log with string interpolation" do
318
- original_code = code_cleanup(<<-EOT)
319
- Builtins.y2warning("foo: \#{foo}")
320
- EOT
321
-
322
- translated_code = code_cleanup(<<-EOT)
323
- include Yast::Logger
324
- log.warn "foo: \#{foo}"
325
- EOT
326
-
327
- cop = RuboCop::Cop::Yast::Builtins.new
328
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
329
- end
330
-
331
- it "It converts a log with a message variable" do
332
- original_code = code_cleanup(<<-EOT)
333
- msg = "message"
334
- Builtins.y2warning(msg)
335
- EOT
336
-
337
- translated_code = code_cleanup(<<-EOT)
338
- include Yast::Logger
339
- msg = "message"
340
- log.warn msg
341
- EOT
342
-
343
- cop = RuboCop::Cop::Yast::Builtins.new
344
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
345
- end
346
-
347
- it "It converts a log with function call" do
348
- original_code = code_cleanup(<<-EOT)
349
- Builtins.y2warning(msg)
350
- EOT
351
-
352
- translated_code = code_cleanup(<<-EOT)
353
- include Yast::Logger
354
- log.warn msg
355
- EOT
356
-
357
- cop = RuboCop::Cop::Yast::Builtins.new
358
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
359
- end
360
-
361
- it "It doesn't convert a log with extra parameters" do
362
- original_code = code_cleanup(<<-EOT)
363
- Builtins.y2warning(msg, arg1, arg2)
364
- EOT
365
-
366
- translated_code = code_cleanup(<<-EOT)
367
- Builtins.y2warning(msg, arg1, arg2)
368
- EOT
369
-
370
- cop = RuboCop::Cop::Yast::Builtins.new
371
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
372
- end
373
-
374
- it "It converts log with operator call" do
375
- original_code = code_cleanup(<<-EOT)
376
- Builtins.y2warning(msg1 + msg2)
377
- EOT
378
-
379
- translated_code = code_cleanup(<<-EOT)
380
- include Yast::Logger
381
- log.warn msg1 + msg2
382
- EOT
383
-
384
- cop = RuboCop::Cop::Yast::Builtins.new
385
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
386
- end
387
-
388
- it "It adds logger include to the class definition" do
389
- original_code = code_cleanup(<<-EOT)
390
- class Foo
391
- Builtins.y2error('foo')
392
- end
393
- EOT
394
-
395
- translated_code = code_cleanup(<<-EOT)
396
- class Foo
397
- include Yast::Logger
398
-
399
- log.error "foo"
400
- end
401
- EOT
402
-
403
- cop = RuboCop::Cop::Yast::Builtins.new
404
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
405
- end
406
-
407
- it "It adds logger include with correct indentation" do
408
- original_code = code_cleanup(<<-EOT)
409
- class Foo
410
- Builtins.y2error('foo')
411
- end
412
- EOT
413
-
414
- translated_code = code_cleanup(<<-EOT)
415
- class Foo
416
- include Yast::Logger
417
-
418
- log.error "foo"
419
- end
420
- EOT
421
-
422
- cop = RuboCop::Cop::Yast::Builtins.new
423
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
424
- end
425
-
426
- it "It does not add the logger include if already present" do
427
- original_code = code_cleanup(<<-EOT)
428
- class Foo
429
- include Yast::Logger
430
- Builtins.y2error('foo')
431
- end
432
- EOT
433
-
434
- translated_code = code_cleanup(<<-EOT)
435
- class Foo
436
- include Yast::Logger
437
- log.error "foo"
438
- end
439
- EOT
440
-
441
- cop = RuboCop::Cop::Yast::Builtins.new
442
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
443
- end
444
-
445
- it "It adds the logger include after the parent class name if present" do
446
- original_code = code_cleanup(<<-EOT)
447
- class Foo < Bar
448
- Builtins.y2error('foo')
449
- end
450
- EOT
451
-
452
- translated_code = code_cleanup(<<-EOT)
453
- class Foo < Bar
454
- include Yast::Logger
455
-
456
- log.error "foo"
457
- end
458
- EOT
459
-
460
- cop = RuboCop::Cop::Yast::Builtins.new
461
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
462
- end
463
-
464
- it "It adds logger include once to a derived class in a module" do
465
- original_code = code_cleanup(<<-EOT)
466
- module Yast
467
- class TestClass < Module
468
- def test
469
- Builtins.y2error("foo")
470
- Builtins.y2debug("foo")
471
- end
472
- end
473
- end
474
- EOT
475
-
476
- translated_code = code_cleanup(<<-EOT)
477
- module Yast
478
- class TestClass < Module
479
- include Yast::Logger
480
-
481
- def test
482
- log.error "foo"
483
- log.debug "foo"
484
- end
485
- end
486
- end
487
- EOT
488
-
489
- cop = RuboCop::Cop::Yast::Builtins.new
490
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
491
- end
492
-
493
- it "It converts the single quoted format string to double quoted" do
494
- original_code = code_cleanup(<<-EOT)
495
- Builtins.y2milestone('foo: %1', foo)
496
- EOT
497
-
498
- translated_code = code_cleanup(<<-EOT)
499
- include Yast::Logger
500
- log.info "foo: \#{foo}"
501
- EOT
502
-
503
- cop = RuboCop::Cop::Yast::Builtins.new
504
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
505
- end
506
-
507
- it "It escapes double quotes and interpolations" do
508
- original_code = code_cleanup(<<-EOT)
509
- Builtins.y2milestone('"\#{foo}"')
510
- EOT
511
-
512
- translated_code = code_cleanup(<<-EOT)
513
- include Yast::Logger
514
- log.info "\\"\\\#{foo}\\""
515
- EOT
516
-
517
- cop = RuboCop::Cop::Yast::Builtins.new
518
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
519
- end
520
-
521
- it "It does not convert logging with backtrace" do
522
- original_code = code_cleanup(<<-EOT)
523
- Builtins.y2milestone(-1, "foo")
524
- EOT
525
-
526
- translated_code = code_cleanup(<<-EOT)
527
- Builtins.y2milestone(-1, "foo")
528
- EOT
529
-
530
- cop = RuboCop::Cop::Yast::Builtins.new
531
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
532
- end
533
-
534
- it "It does not convert code with a local variable 'log'" do
535
- original_code = code_cleanup(<<-EOT)
536
- log = 1
537
- Builtins.y2milestone("foo")
538
- EOT
539
-
540
- translated_code = code_cleanup(<<-EOT)
541
- log = 1
542
- Builtins.y2milestone("foo")
543
- EOT
544
-
545
- cop = RuboCop::Cop::Yast::Builtins.new
546
- expect(autocorrect_source(cop, original_code)).to eq(translated_code)
547
- end
548
-
549
- it "It finds an offense with missing parenthesis around argument" do
550
- code = code_cleanup(<<-EOT)
551
- Builtins.y2milestone "Executing hook '\#{name}'"
552
- EOT
553
-
554
- cop = RuboCop::Cop::Yast::Builtins.new
555
- inspect_source(cop, [code])
556
-
557
- expect(cop.offenses.size).to eq(1)
558
- end
559
- end
560
- end
@@ -1,119 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe RuboCop::Cop::Yast::Ops do
6
- context("In safe mode") do
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
-
14
- it "finds trivial Ops.add call" do
15
- inspect_source(cop, ["Ops.add(2, 4)"])
16
-
17
- expect(cop.offenses.size).to eq(1)
18
- end
19
-
20
- it "finds Ops.add call with variable" do
21
- inspect_source(cop, ["foo = 2\n Ops.add(foo, 4)"])
22
-
23
- expect(cop.offenses.size).to eq(1)
24
- end
25
-
26
- it "finds Ops.add call with variable inside condition" do
27
- inspect_source(cop, ["foo = 1\nif true\nOps.add(foo, 4)\nend"])
28
-
29
- expect(cop.offenses.size).to eq(1)
30
- end
31
-
32
- it "ignores unsafe calls" do
33
- inspect_source(cop, ["if true\nOps.add(foo, 4)\nend"])
34
-
35
- expect(cop.offenses).to be_empty
36
- end
37
-
38
- # check that all node types are handled properly
39
- it "parses complex code" do
40
- src = <<-EOF
41
- module Foo
42
- class Bar
43
- def baz(arg)
44
- case arg
45
- when :foo
46
- a &&= true
47
- b ||= true
48
- end
49
- rescue e
50
- while false
51
- find.foo do
52
- end
53
- retry
54
- end
55
- ensure
56
- sure
57
- end
58
- class << foo
59
- end
60
- def self.foo
61
- end
62
- end
63
- end
64
- EOF
65
-
66
- inspect_source(cop, src)
67
-
68
- expect(cop.offenses).to be_empty
69
- end
70
-
71
- it "auto-corrects Ops.add(2, 4) with 2 + 4" do
72
- new_source = autocorrect_source(cop, "Ops.add(2, 4)")
73
- expect(new_source).to eq("2 + 4")
74
- end
75
-
76
- it "auto-corrects Ops.add(a, b) with a + b" do
77
- new_source = autocorrect_source(cop, "a = 1; b = 2; Ops.add(a, b)")
78
- expect(new_source).to eq("a = 1; b = 2; a + b")
79
- end
80
-
81
- it 'auto-corrects Ops.add("foo", "bar") with "foo" + "bar"' do
82
- new_source = autocorrect_source(cop, 'Ops.add("foo", "bar")')
83
- expect(new_source).to eq('"foo" + "bar"')
84
- end
85
-
86
- # FIXME: auto-correct does not work work recursively
87
- xit "auto-corrects nested Ops.add calls" do
88
- new_source = autocorrect_source(cop,
89
- 'Ops.add("foo", Ops.add("bar", "baz"))')
90
- expect(new_source).to eq('"foo" + "bar + baz"')
91
- end
92
-
93
- it "keeps unsafe call Ops.add(foo, bar)" do
94
- source = "foo = 1; Ops.add(foo, bar)"
95
- new_source = autocorrect_source(cop, source)
96
- expect(new_source).to eq(source)
97
- end
98
- end
99
-
100
- context("In unsafe mode") do
101
- let(:config) do
102
- conf = { "Yast/Ops" => { "SafeMode" => false } }
103
- RuboCop::Config.new(conf)
104
- end
105
-
106
- subject(:cop) { described_class.new(config) }
107
-
108
- it "finds unsafe Ops.add calls" do
109
- inspect_source(cop, ["if true\nOps.add(foo, 4)\nend"])
110
-
111
- expect(cop.offenses.size).to eq(1)
112
- end
113
-
114
- it "auto-corrects unsafe call Ops.add(foo, bar) with foo + bar" do
115
- new_source = autocorrect_source(cop, "Ops.add(foo, bar)")
116
- expect(new_source).to eq("foo + bar")
117
- end
118
- end
119
- end
@@ -1,29 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "simplecov"
4
-
5
- SimpleCov.start do
6
- # don't check code coverage in these subdirectories
7
- add_filter "/vendor/"
8
- add_filter "/spec/"
9
- end
10
-
11
- # allow only the new "expect" RSpec syntax
12
- RSpec.configure do |config|
13
- config.expect_with :rspec do |c|
14
- c.syntax = :expect
15
- end
16
-
17
- config.mock_with :rspec do |c|
18
- c.syntax = :expect
19
- end
20
- end
21
-
22
- # reuse the Rubocop helper, provides some nice methods used in tests
23
- require File.join(
24
- Gem::Specification.find_by_name("rubocop").gem_dir, "spec", "spec_helper.rb"
25
- )
26
-
27
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
28
-
29
- require "rubocop-yast"