querly 0.6.0 → 0.7.0

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: 98d2102a17e63b28b3c08366d02b7e54c804d8c8
4
- data.tar.gz: a152411cc3e70cd97fac3534c950c16c62d955d1
3
+ metadata.gz: 2a7dfd2ae45b1173ea9e23967e5c39b211bebffb
4
+ data.tar.gz: d014023c1f6e4d6989d04ea688dbaad0fed475ba
5
5
  SHA512:
6
- metadata.gz: 903128838bc67d5296f269ceffc1b3e42eedb982e917064351607fb652171bfc29e2bc3c2ce7c8faac1338b11d56ff82fa6fcfe16c6e06a382907affb871f19f
7
- data.tar.gz: d0aeabc064163ae7630f007e7756f88932ed6c555bb4e864aeb23bf350f1ad62d6765d43b51d6010d4851d3f9653b0cfc7a7c5515164aebf84e143e87d5de313
6
+ metadata.gz: 54969626459f41a814877e188ee487a911f01cbe9a17fe83ed2ed8b110736be3088994c2c0e73754c418c93e37e640fe409707740edd9245f63adc7d09045cf0
7
+ data.tar.gz: 100d7dbc6eb4dc7a6edadd86c08760782aa4ab65f1b4958d1b1e3f6360a2db28b00b748297367dd7df47caef9259b7b93f13b3a4f6ffc57dc694c785dcb49332
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.7.0 (2017-08-22)
6
+
7
+ * Add Wiki pages to repository in manual directory #25
8
+ * Add named literal pattern `:string: as 'name` with `where: { name: ["alice", /bob/] }` #24
9
+ * Add `init` command #28
10
+
5
11
  ## 0.6.0 (2017-06-27)
6
12
 
7
13
  * Load current directory when no path is given (@wata727) #18
data/README.md CHANGED
@@ -87,10 +87,10 @@ If your code contains `p` or `pp` calls, querly will print warning messages.
87
87
 
88
88
  ## Configuration
89
89
 
90
- Visit our wiki pages for configuration and query language reference.
90
+ See the following manual for configuration and query language reference.
91
91
 
92
- * [Configuration](https://github.com/soutaro/querly/wiki/Configuration)
93
- * [Patterns](https://github.com/soutaro/querly/wiki/Patterns)
92
+ * [Configuration](https://github.com/soutaro/querly/blob/master/manual/configuration.md)
93
+ * [Patterns](https://github.com/soutaro/querly/blob/master/manual/patterns.md)
94
94
 
95
95
  Use `querly console` command to test patterns interactively.
96
96
 
data/lib/querly/cli.rb CHANGED
@@ -86,6 +86,17 @@ Specify configuration file by --config option.
86
86
  puts "Querly #{VERSION}"
87
87
  end
88
88
 
89
+ def self.source_root
90
+ File.join(__dir__, "../..")
91
+ end
92
+
93
+ include Thor::Actions
94
+
95
+ desc "init", "Generate Querly config file (querly.yml)"
96
+ def init()
97
+ copy_file("template.yml", "querly.yml")
98
+ end
99
+
89
100
  private
90
101
 
91
102
  def config_path
@@ -23,7 +23,7 @@ module Querly
23
23
 
24
24
  class Any < Base
25
25
  def test_node(node)
26
- true
26
+ !!node
27
27
  end
28
28
  end
29
29
 
@@ -81,56 +81,53 @@ module Querly
81
81
 
82
82
  class Literal < Base
83
83
  attr_reader :type
84
- attr_reader :value
84
+ attr_reader :values
85
85
 
86
- def initialize(type:, value: nil)
86
+ def initialize(type:, values: nil)
87
87
  @type = type
88
- @value = value
88
+ @values = values ? Array(values) : nil
89
+ end
90
+
91
+ def with_values(values)
92
+ self.class.new(type: type, values: values)
93
+ end
94
+
95
+ def test_value(object)
96
+ if values
97
+ values.any? {|value| value === object }
98
+ else
99
+ true
100
+ end
89
101
  end
90
102
 
91
103
  def test_node(node)
92
104
  case node&.type
93
105
  when :int
94
106
  return false unless type == :int || type == :number
95
- if value
96
- value == node.children.first
97
- else
98
- true
99
- end
107
+ test_value(node.children.first)
100
108
 
101
109
  when :float
102
110
  return false unless type == :float || type == :number
103
- if value
104
- value == node.children.first
105
- else
106
- true
107
- end
111
+ test_value(node.children.first)
108
112
 
109
113
  when :true
110
- type == :bool && (value == nil || value == true)
114
+ type == :bool && (values == nil || values == [true])
111
115
 
112
116
  when :false
113
- type == :bool && (value == nil || value == false)
117
+ type == :bool && (values == nil || values == [false])
114
118
 
115
119
  when :str
116
120
  return false unless type == :string
117
- if value
118
- value == node.children.first
119
- else
120
- true
121
- end
121
+ test_value(node.children.first)
122
122
 
123
123
  when :sym
124
124
  return false unless type == :symbol
125
- if value
126
- value == node.children.first
127
- else
128
- true
129
- end
125
+ test_value(node.children.first)
130
126
 
131
127
  when :regexp
132
128
  type == :regexp
133
-
129
+ test_value(node.children.first)
130
+
134
131
  end
135
132
  end
136
133
  end
@@ -162,7 +159,14 @@ module Querly
162
159
  end
163
160
 
164
161
  def test_name(node)
165
- name.any? {|n| n === node.children[1] }
162
+ name.map do |n|
163
+ case n
164
+ when String
165
+ n.to_sym
166
+ else
167
+ n
168
+ end
169
+ end.any? {|n| n === node.children[1] }
166
170
  end
167
171
 
168
172
  def test_node(node)
@@ -17,19 +17,23 @@ expr: constant { result = Expr::Constant.new(path: val[0]) }
17
17
  | send
18
18
  | SELF { result = Expr::Self.new }
19
19
  | EXCLAMATION expr { result = Expr::Not.new(pattern: val[1]) }
20
- | BOOL { result = Expr::Literal.new(type: :bool, value: val[0]) }
21
- | STRING { result = Expr::Literal.new(type: :string, value: val[0]) }
22
- | INT { result = Expr::Literal.new(type: :int, value: val[0]) }
23
- | FLOAT { result = Expr::Literal.new(type: :float, value: val[0]) }
24
- | SYMBOL { result = Expr::Literal.new(type: :symbol, value: val[0]) }
25
- | NUMBER { result = Expr::Literal.new(type: :number, value: val[0]) }
26
- | REGEXP { result = Expr::Literal.new(type: :regexp, value: nil) }
20
+ | BOOL { result = Expr::Literal.new(type: :bool, values: val[0]) }
21
+ | literal { result = val[0] }
22
+ | literal AS META { result = val[0].with_values(resolve_meta(val[2])) }
27
23
  | DSTR { result = Expr::Dstr.new() }
28
24
  | UNDERBAR { result = Expr::Any.new }
29
25
  | NIL { result = Expr::Nil.new }
30
26
  | LPAREN expr RPAREN { result = val[1] }
31
27
  | IVAR { result = Expr::Ivar.new(name: val[0]) }
32
28
 
29
+ literal:
30
+ STRING { result = Expr::Literal.new(type: :string, values: val[0]) }
31
+ | INT { result = Expr::Literal.new(type: :int, values: val[0]) }
32
+ | FLOAT { result = Expr::Literal.new(type: :float, values: val[0]) }
33
+ | SYMBOL { result = Expr::Literal.new(type: :symbol, values: val[0]) }
34
+ | NUMBER { result = Expr::Literal.new(type: :number, values: val[0]) }
35
+ | REGEXP { result = Expr::Literal.new(type: :regexp, values: nil) }
36
+
33
37
  args: { result = nil }
34
38
  | expr { result = Argument::Expr.new(expr: val[0], tail: nil)}
35
39
  | expr COMMA args { result = Argument::Expr.new(expr: val[0], tail: val[2]) }
@@ -55,6 +59,7 @@ key_value: keyword COLON expr { result = { key: val[0], value: val[2], negated:
55
59
 
56
60
  method_name: METHOD
57
61
  | EXCLAMATION
62
+ | AS
58
63
  | META { result = resolve_meta(val[0]) }
59
64
 
60
65
  method_name_or_ident: method_name
@@ -66,10 +71,10 @@ keyword: LIDENT | UIDENT
66
71
  constant: UIDENT { result = [val[0]] }
67
72
  | UIDENT COLONCOLON constant { result = [val[0]] + val[2] }
68
73
 
69
- send: LIDENT block { result = val[1] != nil ? Expr::Send.new(receiver: Expr::Any.new, name: val[0], args: Argument::AnySeq.new, block: val[1]) : Expr::Vcall.new(name: val[0]) }
70
- | UIDENT block { result = Expr::Send.new(receiver: Expr::Any.new, name: val[0], block: val[1]) }
71
- | method_name { result = Expr::Send.new(receiver: Expr::Any.new, name: val[0], block: nil) }
72
- | method_name_or_ident LPAREN args RPAREN block { result = Expr::Send.new(receiver: Expr::Any.new,
74
+ send: LIDENT block { result = val[1] != nil ? Expr::Send.new(receiver: nil, name: val[0], args: Argument::AnySeq.new, block: val[1]) : Expr::Vcall.new(name: val[0]) }
75
+ | UIDENT block { result = Expr::Send.new(receiver: nil, name: val[0], block: val[1]) }
76
+ | method_name { result = Expr::Send.new(receiver: nil, name: val[0], block: nil) }
77
+ | method_name_or_ident LPAREN args RPAREN block { result = Expr::Send.new(receiver: nil,
73
78
  name: val[0],
74
79
  args: val[2],
75
80
  block: val[4]) }
@@ -122,9 +127,9 @@ def next_token
122
127
  case
123
128
  when input.eos?
124
129
  [false, false]
125
- when input.scan(/true/)
130
+ when input.scan(/true\b/)
126
131
  [:BOOL, true]
127
- when input.scan(/false/)
132
+ when input.scan(/false\b/)
128
133
  [:BOOL, false]
129
134
  when input.scan(/nil/)
130
135
  [:NIL, false]
@@ -147,6 +152,8 @@ def next_token
147
152
  when input.scan(/:\w+/)
148
153
  s = input.matched
149
154
  [:SYMBOL, s[1, s.size - 1].to_sym]
155
+ when input.scan(/as\b/)
156
+ [:AS, :as]
150
157
  when input.scan(/{}/)
151
158
  [:WITH_BLOCK, nil]
152
159
  when input.scan(/!{}/)
data/lib/querly/pp/cli.rb CHANGED
@@ -55,27 +55,20 @@ module Querly
55
55
 
56
56
  def run_haml
57
57
  require "haml"
58
- if Haml::VERSION >= '5.0.0'
59
- raise <<~ERROR
60
- HAML 5.0+ is detected.
61
- `querly-pp haml` does not work on HAML 5.0+.
62
- Use `haml -d` instead.
63
- ERROR
64
- end
65
-
66
58
  load_libs
67
-
68
59
  source = stdin.read
69
60
 
70
- options = Haml::Options.new
71
-
72
- parser = Haml::Parser.new(source, options)
73
- parser.parse
74
-
75
- compiler = Haml::Compiler.new(options)
76
- compiler.compile(parser.root)
61
+ if Haml::VERSION >= '5.0.0'
62
+ stdout.print Haml::Engine.new(source).precompiled
63
+ else
64
+ options = Haml::Options.new
65
+ parser = Haml::Parser.new(source, options)
66
+ parser.parse
67
+ compiler = Haml::Compiler.new(options)
68
+ compiler.compile(parser.root)
77
69
 
78
- stdout.print compiler.precompiled
70
+ stdout.print compiler.precompiled
71
+ end
79
72
  end
80
73
  end
81
74
  end
data/lib/querly/rule.rb CHANGED
@@ -116,7 +116,7 @@ module Querly
116
116
  when /\A\/(.*)\/\Z/
117
117
  Regexp.new($1)
118
118
  else
119
- v.to_sym
119
+ v
120
120
  end
121
121
  end
122
122
  end
@@ -11,11 +11,10 @@ module Querly
11
11
  def each(&block)
12
12
  if block_given?
13
13
  paths.each do |path|
14
- case
15
- when path.file?
16
- load_script_from_path path, &block
17
- when path.directory?
14
+ if path.directory?
18
15
  enumerate_files_in_dir(path, &block)
16
+ else
17
+ load_script_from_path path, &block
19
18
  end
20
19
  end
21
20
  else
@@ -1,3 +1,3 @@
1
1
  module Querly
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -0,0 +1,94 @@
1
+ # Overview
2
+
3
+ The configuration file, default name is `querly.yml`, will look like the following.
4
+
5
+ ```yml
6
+ rules:
7
+ ...
8
+ preprocessor:
9
+ ...
10
+ check:
11
+ ...
12
+ ```
13
+
14
+ # rules
15
+
16
+ `rules` is array of rule hash.
17
+
18
+ ```yml
19
+ - id: com.sideci.json
20
+ pattern: Net::HTTP
21
+ message: "Should use HTTPClient instead of Net::HTTP"
22
+ justification:
23
+ - No exception!
24
+ before:
25
+ - "Net::HTTP.get(url)"
26
+ after:
27
+ - HTTPClient.new.get_content(url)
28
+ ```
29
+
30
+ The rule hash contains following keys:
31
+
32
+ * `id` Identifier of the rule, must be unique (string)
33
+ * `pattern` Patterns to find out (string, or array of string)
34
+ * `message` Error message to explain why the code fragment needs special care (string)
35
+ * `justification` When the *bad use* is allowed (string, or array of string)
36
+ * `before` Sample ruby code to find out (string, or array of string)
37
+ * `after` Sample ruby code to be fixed (string, or array of string)
38
+
39
+ # preprocessor
40
+
41
+ When your project contains `.slim`, `.haml`, or any templates which contains Ruby code, preprocessor is to translate the templates to Ruby code.
42
+ `preprocessor` is a hash; key of extension of the templates, value of command line.
43
+
44
+ ```yml
45
+ .slim: slimrb --compile
46
+ .haml: bundle exec querly-pp haml -I lib -r your_custom_plugin
47
+ ```
48
+
49
+ The command will be executed with stdin of template code, and should emit ruby code to stdout.
50
+
51
+ ## querly-pp
52
+
53
+ Querly 0.2.0 ships with `querly-pp` command line tool which compiles given HAML source to Ruby script.
54
+ `-I` and `-r` options can be used to use plugins.
55
+
56
+ # check
57
+
58
+ Define set of rules to check for each file.
59
+
60
+ ```yml
61
+ check:
62
+ - path: /test
63
+ rules:
64
+ - com.acme.corp
65
+ - append: com.acme.corp
66
+ - except: com.acme.corp
67
+ - only: com.acme.corp
68
+ - path: /test/unit
69
+ rules:
70
+ - append:
71
+ tags: foo bar
72
+ - except:
73
+ tags: foo bar
74
+ - only:
75
+ tags: foo bar
76
+ ```
77
+
78
+ * `path` Files to apply the rules in `.gitignore` syntax
79
+ * `rules` Rules to check
80
+
81
+ All matching `check` element against given file name will be applied, sequentially.
82
+
83
+ * `/lib/bar.rb` => no checks will be applied (all rules)
84
+ * `/test/test_helper.rb` => `/test` check will be applied
85
+ * `/test/unit/account_test.rb` => `/test` and `/test/unit` checks will be applied
86
+
87
+ ## Rules
88
+
89
+ You can use `append:`, `except:` and `only:` operation.
90
+
91
+ * `append:` appends rules to current rule set
92
+ * `except:` removes rules from current rule set
93
+ * `only:` update current rule set
94
+
@@ -0,0 +1,35 @@
1
+ In this page, I will show some rules I have written. They are all real rules from my repos.
2
+
3
+ # `js: true` option with feature spec
4
+
5
+ I see some of Feature Spec scenarios have `js: true` option, and others do not. The reason they look strange to me is some scenarios without `js: true` depend on JavaScript. I changed one of the `js: true` to `js: false`, and run the specs again. They run! What is happening?? The `js` does not stand for *JavaScript*?? What else?
6
+
7
+ The magic happens in `rails_helper.rb`.
8
+
9
+ ```rb
10
+ Capybara.configure do |config|
11
+ config.default_driver = :poltergeist
12
+ config.javascript_driver = :poltergeist
13
+ end
14
+ ```
15
+
16
+ Okay, `js: true` does not make any sense, because both `default_driver` and `javascript_driver` are same.
17
+
18
+ Should we fix all of the scenarios now? If we leave them, new teammates will misunderstand `js: true` does something important and required. However, we don't want to fix them now. It does not do anything bad right now. So, my conclusion is *I will do that, but not now* 😸
19
+
20
+ It's the time to add a new Querly rule. When someone tries to add new scenario with `js: true`, tell the person that it does not make any sense.
21
+
22
+ ```yaml
23
+ - id: sample.scenario_with_js_option
24
+ pattern: "scenario(..., js: _, ...)"
25
+ message: |
26
+ You do not need js:true option
27
+
28
+ We are using Poltergeist as both default_driver and javascript_driver!
29
+ before:
30
+ - "scenario 'hello world', js: true, type: :feature do end"
31
+ after:
32
+ - "scenario 'foo bar' do end"
33
+ ```
34
+
35
+ No new `js: true` scenario will be written. Our new teammate may try to write that. But Querly will tell they don't have to do that, instead of me.
@@ -0,0 +1,168 @@
1
+ # Syntax
2
+
3
+ ## Toplevel
4
+
5
+ * *expr*
6
+ * *expr* `[` *kind* `]` (kinded expr)
7
+ * *expr* `[!` *kind* `]` (negated kinded expr)
8
+
9
+ ## expr
10
+
11
+ * `_` (any expr)
12
+ * *method* (method call, with any receiver and any args)
13
+ * *method* `(` *args* `)` *block_spec* (method call with any receiver)
14
+ * *receiver* *method* (method call with any args)
15
+ * *receiver* *method* `(` *args* `)` *block_spec* (method call)
16
+ * *literal*
17
+ * `self` (self)
18
+ * `!` *expr*
19
+
20
+ ### block_spec
21
+
22
+ * (no spec)
23
+ * `{}` (method call should be with block)
24
+ * `!{}` (method call should not be with block)
25
+
26
+ ### receiver
27
+
28
+ * *expr* `.` (receiver matching with the pattern)
29
+ * *expr* `...` (some receiver in the chain matching with the pattern)
30
+
31
+ ### Examples
32
+
33
+ * `p(_)` `p` call with one argument, any receiver
34
+ * `self.p(1)` `p` call with `1`, receiver is `self` or omitted.
35
+ * `foo.bar.baz` `baz` call with receiver of `bar` call of receiver of `foo` call
36
+ * `update_attribute(:symbol:, :string:)` `update_attribute` call with symbol and string literals
37
+ * `File.open(...) !{}` `File.open` call but without block
38
+
39
+ ```rb
40
+ p 1 # p(_) matches
41
+ p 2 # p(_) matches
42
+ p 1, 2, 3 # p(_) does not match
43
+
44
+ p(1) # self.p(1) matches
45
+
46
+ foo(1).bar {|x| x+1 }.baz(3) # foo.bar.baz matches
47
+ (1+2).foo.bar(*args).baz.bla # foo.bar.baz matches, partially
48
+ foo.xyz.bar.baz # foo.bar.baz does not match
49
+
50
+ update_attribute(:name, "hoge") # f(:symbol:, :string:) matches
51
+ update_attribute(:name, name) # f(:symbol:, :string:) does not match
52
+
53
+ foo.bar.baz # foo.bar.baz matches
54
+ foo.bar.baz # foo...baz matches
55
+ bar.foo.baz # foo...bar...baz does not match
56
+ ```
57
+
58
+ ## args & kwargs
59
+
60
+ ### args
61
+
62
+ * *expr* `,` *args*
63
+ * *expr* `,` *kwargs*
64
+ * *expr*
65
+ * `...` `,` *kwargs* (any argument sequence, followed by keyword arguments)
66
+ * `...` (any argument sequence, including any keyword arguments)
67
+
68
+ ### Literals
69
+
70
+ * `123` (integer)
71
+ * `1.23` (float)
72
+ * `:foobar` (symbol)
73
+ * `:symbol:` (any symbol literal)
74
+ * `:string:` (any string literal)
75
+ * `:dstr:` (any dstr `"hi #{name}"`)
76
+ * `true`, `false` (true and false)
77
+ * `nil` (nil)
78
+ * `:number:`, `:int:`, `:float:` (any number, any integer, any float)
79
+ * `:bool:` (true or false)
80
+
81
+ ### kwargs
82
+
83
+ * *symbol* `:` *expr* `,` ...
84
+ * `!` *symbol* `:` *expr* `,` ...
85
+ * `...`
86
+ * `&` *expr*
87
+
88
+ ### Examples
89
+
90
+ ```rb
91
+ f(1,2,3) # f(...), f(1,2,...), and f(1, ...) matches
92
+ # f(_,_), f(0, ...) does not match
93
+
94
+ JSON.load(string, symbolize_names: true) # JSON.load(..., symbolize_names: true) matches
95
+ # JSON.load(symbolize_names: true) does not match
96
+
97
+ record.update(email: email, name: name) # update(name: _, email: _) matches
98
+ # update(name: _) does not match
99
+ # update(name: _, ...) matches
100
+ # update(!id: _, ...) matches
101
+
102
+ article.try(&:author) # try(&:symbol:) matches
103
+ article.try(:author) # try(&:symbol:) does not match
104
+ article.try {|x| x.author } # try(&:symbol:) does not match
105
+ ```
106
+
107
+ ## kind
108
+
109
+ * `conditional` (When expr appears in *conditional* context)
110
+ * `discarded` (When expr appears in *discarded* context)
111
+
112
+ Kind allows you to find out something like:
113
+
114
+ * `save` call but does not check its result for error recovery
115
+
116
+ *conditional* context is
117
+
118
+ * Condition of `if` construct
119
+ * Condition of loop constructs
120
+ * LHS of `&&` and `||`
121
+
122
+ ```rb
123
+ # record.save is in conditional context
124
+ unless record.save
125
+ # error recovery
126
+ end
127
+
128
+ # record.save is not in conditional context
129
+ x = record.save
130
+
131
+ # record.save is in conditional context
132
+ record.save or abort()
133
+ ```
134
+
135
+ *discarded* context is where the value of the expression is completely discarded, a bit looser than *conditional*.
136
+
137
+ ```rb
138
+ def f()
139
+ # record.save is in discarded context
140
+ foo()
141
+ record.save()
142
+ bar
143
+ end
144
+ ```
145
+
146
+ # Difference from Ruby
147
+
148
+ * Method call parenthesis cannot be omitted (if omitted, it means *any arguments*)
149
+ * `+`, `-`, `[]` or other *operator* should be written as method calls like `_.+(_)`, `[]=(:string:, _)`
150
+
151
+ # Testing
152
+
153
+ You can test patterns by `querly console .` command interactively.
154
+
155
+ ```
156
+ Querly 0.1.0, interactive console
157
+
158
+ Commands:
159
+ - find PATTERN Find PATTERN from given paths
160
+ - reload! Reload program from paths
161
+ - quit
162
+
163
+ Loading... ready!
164
+ >
165
+ ```
166
+
167
+ Also `querly test` will help you.
168
+ It test configuration file by checking patterns in rules against `before` and `after` examples.
data/template.yml ADDED
@@ -0,0 +1,69 @@
1
+ rules:
2
+ - id: sample.debug_print
3
+ pattern:
4
+ - self.p
5
+ - self.pp
6
+ message: Delete debug print
7
+ examples:
8
+ - before: |
9
+ pp some: error
10
+
11
+ - id: sample.file.open
12
+ pattern: File.open(...) !{}
13
+ message: |
14
+ Use block to read/write file
15
+
16
+ If you use block, the open method closes file implicitly.
17
+ You don't have to close files explicitly.
18
+ examples:
19
+ - before: |
20
+ io = File.open("foo.txt")
21
+ io.write("hello world")
22
+ io.close
23
+ after: |
24
+ File.open("foo.txt") do |io|
25
+ io.write("hello world")
26
+ end
27
+
28
+ - id: sample.exception
29
+ pattern: Exception
30
+ message: |
31
+ You probablly should use StandardError
32
+
33
+ If you are trying to define error class, inherit that from StandardError.
34
+ justification:
35
+ - You are sure you want to define an exception which is not rescued by default
36
+ examples:
37
+ - before: class MyError < Exception; end
38
+ after: class MyError < StandardError; end
39
+
40
+ - id: sample.test.assert_equal_size
41
+ pattern:
42
+ subject: "assert_equal(:int: as 'zero, _.'size, ...)"
43
+ where:
44
+ zero: 0
45
+ size:
46
+ - size
47
+ - count
48
+ message: |
49
+ Comparing size of something with 0 can be written using assert_empty
50
+ examples:
51
+ - before: |
52
+ assert_equal 0, some.size
53
+ after: |
54
+ assert_empty some.size
55
+ - before: |
56
+ assert_equal 0, some.count
57
+ after: |
58
+ assert_empty some.count
59
+
60
+ preprocessor:
61
+ .slim: slimrb --compile
62
+
63
+ checks:
64
+ - path: /
65
+ rules:
66
+ except: sample.test
67
+ - path: /test
68
+ rules:
69
+ add: sample.test
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: querly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-27 00:00:00.000000000 Z
11
+ date: 2017-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -180,9 +180,13 @@ files:
180
180
  - lib/querly/script.rb
181
181
  - lib/querly/script_enumerator.rb
182
182
  - lib/querly/version.rb
183
+ - manual/configuration.md
184
+ - manual/examples.md
185
+ - manual/patterns.md
183
186
  - querly.gemspec
184
187
  - rules/sample.yml
185
188
  - sample.yaml
189
+ - template.yml
186
190
  homepage: https://github.com/soutaro/querly
187
191
  licenses: []
188
192
  metadata: {}
@@ -202,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
206
  version: '0'
203
207
  requirements: []
204
208
  rubyforge_project:
205
- rubygems_version: 2.6.8
209
+ rubygems_version: 2.6.10
206
210
  signing_key:
207
211
  specification_version: 4
208
212
  summary: Pattern Based Checking Tool for Ruby