rubocop-yast 0.0.6 → 0.0.8

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: 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"