neuroncheck 0.1.0 → 0.1.1

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.
@@ -3,243 +3,243 @@ require 'neuroncheck/utils'
3
3
  require 'neuroncheck/plugin'
4
4
 
5
5
  module NeuronCheckSystem
6
- # 期待する値に対応する、適切なマッチャを取得
7
- def self.get_appropriate_matcher(expected, declared_caller_locations)
8
- case expected
9
- when DeclarationContext # 誤って「self」と記載した場合
10
- raise DeclarationError, "`self` cannot be used in declaration - use `:self` instead"
11
- when :self # self
12
- SelfMatcher.new(declared_caller_locations) # 値がselfであるかどうかチェック
13
-
14
- when String, Symbol, Integer
15
- ValueEqualMatcher.new(expected, declared_caller_locations) # 値が等しいかどうかをチェック
16
- when true, false, nil
17
- ObjectIdenticalMathcer.new(expected, declared_caller_locations) # オブジェクトが同一かどうかをチェック
18
- when Class, Module
19
- KindOfMatcher.new(expected, declared_caller_locations) # 所属/継承しているかどうかをチェック
20
- when Range
21
- RangeMatcher.new(expected, declared_caller_locations) # 範囲チェック
22
- when Regexp
23
- RegexpMatcher.new(expected, declared_caller_locations) # 正規表現チェック
24
- # when Encoding
25
- # EncodingMatcher.new(expected, declared_caller_locations) # エンコーディングチェック
26
-
27
- when Array
28
- OrMatcher.new(expected, declared_caller_locations) # ORチェック
29
-
30
- when Plugin::Keyword # プラグインによって登録されたキーワードの場合
31
- KeywordPluginMatcher.new(expected, declared_caller_locations)
32
-
33
- else
34
- raise DeclarationError, "#{expected.class.name} cannot be usable for NeuronCheck check parameter\n value: #{expected.inspect}"
35
- end
36
-
37
- end
38
-
39
- class MatcherBase
40
- attr_accessor :declared_caller_locations
41
-
42
- def initialize(expected, declared_caller_locations)
43
- @expected = expected
44
- @declared_caller_locations = declared_caller_locations
45
- end
46
-
47
- def match?(value, self_object)
48
- raise NotImplementedError
49
- end
50
-
51
- def get_error_message(signature_decl, context_caption, value, phrase_after_but: 'was')
52
- locs = Utils.backtrace_locations_to_captions(@declared_caller_locations)
53
-
54
- ret = ""
55
- ret.concat(<<MSG)
6
+ # 期待する値に対応する、適切なマッチャを取得
7
+ def self.get_appropriate_matcher(expected, declared_caller_locations)
8
+ case expected
9
+ when DeclarationContext # 誤って「self」と記載した場合
10
+ raise DeclarationError, "`self` cannot be used in declaration - use `:self` instead"
11
+ when :self # self
12
+ SelfMatcher.new(declared_caller_locations) # 値がselfであるかどうかチェック
13
+
14
+ when String, Symbol, Integer
15
+ ValueEqualMatcher.new(expected, declared_caller_locations) # 値が等しいかどうかをチェック
16
+ when true, false, nil
17
+ ObjectIdenticalMathcer.new(expected, declared_caller_locations) # オブジェクトが同一かどうかをチェック
18
+ when Class, Module
19
+ KindOfMatcher.new(expected, declared_caller_locations) # 所属/継承しているかどうかをチェック
20
+ when Range
21
+ RangeMatcher.new(expected, declared_caller_locations) # 範囲チェック
22
+ when Regexp
23
+ RegexpMatcher.new(expected, declared_caller_locations) # 正規表現チェック
24
+ # when Encoding
25
+ # EncodingMatcher.new(expected, declared_caller_locations) # エンコーディングチェック
26
+
27
+ when Array
28
+ OrMatcher.new(expected, declared_caller_locations) # ORチェック
29
+
30
+ when Plugin::Keyword # プラグインによって登録されたキーワードの場合
31
+ KeywordPluginMatcher.new(expected, declared_caller_locations)
32
+
33
+ else
34
+ raise DeclarationError, "#{expected.class.name} cannot be usable for NeuronCheck check parameter\n value: #{expected.inspect}"
35
+ end
36
+
37
+ end
38
+
39
+ class MatcherBase
40
+ attr_accessor :declared_caller_locations
41
+
42
+ def initialize(expected, declared_caller_locations)
43
+ @expected = expected
44
+ @declared_caller_locations = declared_caller_locations
45
+ end
46
+
47
+ def match?(value, self_object)
48
+ raise NotImplementedError
49
+ end
50
+
51
+ def get_error_message(signature_decl, context_caption, value, phrase_after_but: 'was')
52
+ locs = Utils.backtrace_locations_to_captions(@declared_caller_locations)
53
+
54
+ ret = ""
55
+ ret.concat(<<MSG)
56
56
  #{context_caption} must be #{expected_caption}, but #{phrase_after_but} #{Utils.truncate(value.inspect, 40)}
57
57
  got: #{value.inspect}
58
58
  MSG
59
59
 
60
- if signature_decl and signature_decl.assigned_method then
61
- ret.concat(<<MSG)
60
+ if signature_decl and signature_decl.assigned_method then
61
+ ret.concat(<<MSG)
62
62
  signature: #{signature_decl.signature_caption}
63
63
  MSG
64
- end
64
+ end
65
65
 
66
- if locs.size >= 1 then
67
- ret.concat(<<MSG)
66
+ if locs.size >= 1 then
67
+ ret.concat(<<MSG)
68
68
  declared at: #{locs.join("\n" + ' ' * 15)}
69
69
 
70
70
  MSG
71
- end
72
-
73
- ret
74
- end
75
-
76
- def expected_caption
77
- raise NotImplementedError
78
- end
79
-
80
- def expected_short_caption
81
- @expected.inspect
82
- end
83
-
84
- def meta_info_as_json
85
- re = {}
86
- re['type'] = self.class.name.split('::')[-1]
87
- re['expected'] = @expected
88
-
89
- re
90
- end
91
- end
92
-
93
- # 値が == で等しいことを判定する
94
- class ValueEqualMatcher < MatcherBase
95
- def match?(value, self_object)
96
- @expected == value
97
- end
98
-
99
- def expected_caption
100
- @expected.inspect
101
- end
102
- end
103
-
104
- # オブジェクトとして同一であることを判定する
105
- class ObjectIdenticalMathcer < MatcherBase
106
- def match?(value, self_object)
107
- @expected.equal?(value)
108
- end
109
-
110
- def expected_caption
111
- @expected.inspect
112
- end
113
- end
114
-
115
- # 値が指定されたClass / Moduleに所属していることを判定する (kind_of?判定)
116
- class KindOfMatcher < MatcherBase
117
- def match?(value, self_object)
118
- value.kind_of?(@expected)
119
- end
120
-
121
- def expected_caption
122
- @expected.name
123
- end
124
-
125
- def meta_info_as_json
126
- super.update('expected' => @expected.name)
127
- end
128
- end
129
-
130
-
131
- # 指定した範囲に含まれている値であることを判定する
132
- class RangeMatcher < MatcherBase
133
- def match?(value, self_object)
134
- @expected.include?(value)
135
- end
136
-
137
- def expected_caption
138
- "included in #{@expected.inspect}"
139
- end
140
- end
141
-
142
- # 指定した正規表現にマッチする文字列であることを判定する
143
- class RegexpMatcher < MatcherBase
144
- def match?(value, self_object)
145
- (value.kind_of?(String) and @expected =~ value)
146
- end
147
-
148
- def expected_caption
149
- "String that matches with #{@expected.inspect}"
150
- end
151
- end
152
-
153
- # # 指定したエンコーディングを持つ文字列であることを判定する
154
- # class EncodingMatcher < MatcherBase
155
- # def match?(value, self_object)
156
- # (value.kind_of?(String) and Encoding.compatible?(value, @expected))
157
- # end
158
- #
159
- # def expected_caption
160
- # "String that is compatible #{@expected.name} encoding"
161
- # end
162
- #
163
- # def expected_short_caption
164
- # "String compatible to #{@expected.name}"
165
- # end
166
- #
167
- # end
168
-
169
- # OR条件。渡されたマッチャ複数のうち、どれか1つでも条件を満たせばOK
170
- class OrMatcher < MatcherBase
171
- def initialize(child_expecteds, declared_caller_locations)
172
- @child_matchers = child_expecteds.map{|x| NeuronCheckSystem.get_appropriate_matcher(x, declared_caller_locations)}
173
- @declared_caller_locations = declared_caller_locations
174
- end
175
-
176
- def match?(value, self_object)
177
- # どれか1つにマッチすればOK
178
- @child_matchers.any?{|x| x.match?(value, self_object)}
179
- end
180
-
181
- def expected_caption
182
- captions = @child_matchers.map{|x| x.expected_caption}
183
-
184
- Utils.string_join_using_or_conjunction(captions)
185
- end
186
- def expected_short_caption
187
- '[' + @child_matchers.map{|x| x.expected_short_caption}.join(', ') + ']'
188
- end
189
-
190
- def meta_info_as_json
191
- super.update('child_matchers' => @child_matchers.map{|x| x.meta_info_as_json})
192
- end
193
- end
194
-
195
-
196
- # selfであるかどうかを判定 (通常はreturns用)
197
- class SelfMatcher < MatcherBase
198
- def initialize(declared_caller_locations)
199
- @declared_caller_locations = declared_caller_locations
200
- end
201
-
202
- def match?(value, self_object)
203
- self_object.equal?(value)
204
- end
205
-
206
- def expected_caption
207
- "self"
208
- end
209
- def expected_short_caption
210
- "self"
211
- end
212
- end
213
-
214
- # プラグインで追加されたキーワード用
215
- class KeywordPluginMatcher < MatcherBase
216
- def initialize(keyword, declared_caller_locations)
217
- @keyword = keyword
218
- @declared_caller_locations = declared_caller_locations
219
- end
220
-
221
- def match?(value, self_object)
222
- @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations, self_object)
223
- @keyword.match?(value)
224
- end
225
-
226
- def expected_caption
227
- @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations)
228
- @keyword.expected_caption
229
- end
230
-
231
- def expected_short_caption
232
- @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations)
233
- @keyword.expected_short_caption
234
- end
235
-
236
- def meta_info_as_json
237
- @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations)
238
- super.update('keyword' => keyword_name, 'expected_caption' => expected_caption).tap{|x| x.delete('expected')}.update(@keyword.get_params_as_json)
239
- end
240
-
241
- def keyword_name
242
- (@keyword.class).instance_variable_get(:@keyword_name).to_s
243
- end
244
- end
71
+ end
72
+
73
+ ret
74
+ end
75
+
76
+ def expected_caption
77
+ raise NotImplementedError
78
+ end
79
+
80
+ def expected_short_caption
81
+ @expected.inspect
82
+ end
83
+
84
+ def meta_info_as_json
85
+ re = {}
86
+ re['type'] = self.class.name.split('::')[-1]
87
+ re['expected'] = @expected
88
+
89
+ re
90
+ end
91
+ end
92
+
93
+ # 値が == で等しいことを判定する
94
+ class ValueEqualMatcher < MatcherBase
95
+ def match?(value, self_object)
96
+ @expected == value
97
+ end
98
+
99
+ def expected_caption
100
+ @expected.inspect
101
+ end
102
+ end
103
+
104
+ # オブジェクトとして同一であることを判定する
105
+ class ObjectIdenticalMathcer < MatcherBase
106
+ def match?(value, self_object)
107
+ @expected.equal?(value)
108
+ end
109
+
110
+ def expected_caption
111
+ @expected.inspect
112
+ end
113
+ end
114
+
115
+ # 値が指定されたClass / Moduleに所属していることを判定する (kind_of?判定)
116
+ class KindOfMatcher < MatcherBase
117
+ def match?(value, self_object)
118
+ value.kind_of?(@expected)
119
+ end
120
+
121
+ def expected_caption
122
+ @expected.name
123
+ end
124
+
125
+ def meta_info_as_json
126
+ super.update('expected' => @expected.name)
127
+ end
128
+ end
129
+
130
+
131
+ # 指定した範囲に含まれている値であることを判定する
132
+ class RangeMatcher < MatcherBase
133
+ def match?(value, self_object)
134
+ @expected.include?(value)
135
+ end
136
+
137
+ def expected_caption
138
+ "included in #{@expected.inspect}"
139
+ end
140
+ end
141
+
142
+ # 指定した正規表現にマッチする文字列であることを判定する
143
+ class RegexpMatcher < MatcherBase
144
+ def match?(value, self_object)
145
+ (value.kind_of?(String) and @expected =~ value)
146
+ end
147
+
148
+ def expected_caption
149
+ "String that matches with #{@expected.inspect}"
150
+ end
151
+ end
152
+
153
+ # # 指定したエンコーディングを持つ文字列であることを判定する
154
+ # class EncodingMatcher < MatcherBase
155
+ # def match?(value, self_object)
156
+ # (value.kind_of?(String) and Encoding.compatible?(value, @expected))
157
+ # end
158
+ #
159
+ # def expected_caption
160
+ # "String that is compatible #{@expected.name} encoding"
161
+ # end
162
+ #
163
+ # def expected_short_caption
164
+ # "String compatible to #{@expected.name}"
165
+ # end
166
+ #
167
+ # end
168
+
169
+ # OR条件。渡されたマッチャ複数のうち、どれか1つでも条件を満たせばOK
170
+ class OrMatcher < MatcherBase
171
+ def initialize(child_expecteds, declared_caller_locations)
172
+ @child_matchers = child_expecteds.map{|x| NeuronCheckSystem.get_appropriate_matcher(x, declared_caller_locations)}
173
+ @declared_caller_locations = declared_caller_locations
174
+ end
175
+
176
+ def match?(value, self_object)
177
+ # どれか1つにマッチすればOK
178
+ @child_matchers.any?{|x| x.match?(value, self_object)}
179
+ end
180
+
181
+ def expected_caption
182
+ captions = @child_matchers.map{|x| x.expected_caption}
183
+
184
+ Utils.string_join_using_or_conjunction(captions)
185
+ end
186
+ def expected_short_caption
187
+ '[' + @child_matchers.map{|x| x.expected_short_caption}.join(', ') + ']'
188
+ end
189
+
190
+ def meta_info_as_json
191
+ super.update('child_matchers' => @child_matchers.map{|x| x.meta_info_as_json})
192
+ end
193
+ end
194
+
195
+
196
+ # selfであるかどうかを判定 (通常はreturns用)
197
+ class SelfMatcher < MatcherBase
198
+ def initialize(declared_caller_locations)
199
+ @declared_caller_locations = declared_caller_locations
200
+ end
201
+
202
+ def match?(value, self_object)
203
+ self_object.equal?(value)
204
+ end
205
+
206
+ def expected_caption
207
+ "self"
208
+ end
209
+ def expected_short_caption
210
+ "self"
211
+ end
212
+ end
213
+
214
+ # プラグインで追加されたキーワード用
215
+ class KeywordPluginMatcher < MatcherBase
216
+ def initialize(keyword, declared_caller_locations)
217
+ @keyword = keyword
218
+ @declared_caller_locations = declared_caller_locations
219
+ end
220
+
221
+ def match?(value, self_object)
222
+ @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations, self_object)
223
+ @keyword.match?(value)
224
+ end
225
+
226
+ def expected_caption
227
+ @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations)
228
+ @keyword.expected_caption
229
+ end
230
+
231
+ def expected_short_caption
232
+ @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations)
233
+ @keyword.expected_short_caption
234
+ end
235
+
236
+ def meta_info_as_json
237
+ @keyword.api = Plugin::KeywordAPI.new(@declared_caller_locations)
238
+ super.update('keyword' => keyword_name, 'expected_caption' => expected_caption).tap{|x| x.delete('expected')}.update(@keyword.get_params_as_json)
239
+ end
240
+
241
+ def keyword_name
242
+ (@keyword.class).instance_variable_get(:@keyword_name).to_s
243
+ end
244
+ end
245
245
  end