roku_builder 4.7.2 → 4.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +8 -0
  3. data/Gemfile.lock +4 -2
  4. data/lib/roku_builder/hash.rb +3 -0
  5. data/lib/roku_builder/manifest.rb +4 -0
  6. data/lib/roku_builder/plugins/analyzer.rb +102 -0
  7. data/lib/roku_builder/plugins/inspector_config.json +358 -0
  8. data/lib/roku_builder/plugins/line_inspector.rb +50 -0
  9. data/lib/roku_builder/plugins/loader.rb +17 -0
  10. data/lib/roku_builder/plugins/manifest_attributes.json +229 -0
  11. data/lib/roku_builder/plugins/manifest_inspector.rb +142 -0
  12. data/lib/roku_builder/plugins/raf_inspector.rb +74 -0
  13. data/lib/roku_builder/version.rb +1 -1
  14. data/lib/roku_builder.rb +2 -0
  15. data/roku_builder.gemspec +1 -0
  16. data/test/roku_builder/plugins/test_analyzer.rb +344 -0
  17. data/test/roku_builder/plugins/test_loader.rb +9 -0
  18. data/test/roku_builder/test_config_parser.rb +1 -1
  19. data/test/roku_builder/test_files/analyzer_test/analyzer_config.json +1 -0
  20. data/test/roku_builder/test_files/analyzer_test/images/focus.png +0 -0
  21. data/test/roku_builder/test_files/analyzer_test/images/focus_hd.png +0 -0
  22. data/test/roku_builder/test_files/analyzer_test/images/focus_sd.png +0 -0
  23. data/test/roku_builder/test_files/analyzer_test/images/splash.png +0 -0
  24. data/test/roku_builder/test_files/analyzer_test/images/splash_hd.png +0 -0
  25. data/test/roku_builder/test_files/analyzer_test/images/splash_sd.png +0 -0
  26. data/test/roku_builder/test_files/analyzer_test/images/too_small.png +0 -0
  27. data/test/roku_builder/test_files/analyzer_test/manifest_depricated_attribute +9 -0
  28. data/test/roku_builder/test_files/analyzer_test/manifest_duplicate_attribute +9 -0
  29. data/test/roku_builder/test_files/analyzer_test/manifest_empty_value +9 -0
  30. data/test/roku_builder/test_files/analyzer_test/manifest_has_value +9 -0
  31. data/test/roku_builder/test_files/analyzer_test/manifest_incorrect_image_resolution +8 -0
  32. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_equals +9 -0
  33. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_float +9 -0
  34. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_integer +8 -0
  35. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_negative +8 -0
  36. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_not_equal +8 -0
  37. data/test/roku_builder/test_files/analyzer_test/manifest_invalid_value_starts_with +8 -0
  38. data/test/roku_builder/test_files/analyzer_test/manifest_missing_attribute +7 -0
  39. data/test/roku_builder/test_files/analyzer_test/manifest_missing_file +8 -0
  40. data/test/roku_builder/test_files/analyzer_test/manifest_raf +9 -0
  41. data/test/roku_builder/test_files/analyzer_test/manifest_template +8 -0
  42. data/test/roku_builder/test_files/analyzer_test/test.pkg +0 -0
  43. data/test/roku_builder/test_helper.rb +2 -2
  44. metadata +72 -2
@@ -0,0 +1,344 @@
1
+ # ********** Copyright Viacom, Inc. Apache 2.0 **********
2
+
3
+ require_relative "../test_helper.rb"
4
+
5
+ module RokuBuilder
6
+ class AnalyzerTest < Minitest::Test
7
+ def setup
8
+ Logger.set_testing
9
+ RokuBuilder.class_variable_set(:@@dev, false)
10
+ RokuBuilder.setup_plugins
11
+ register_plugins(Analyzer)
12
+ @config, @options = build_config_options_objects(AnalyzerTest, {analyze: true, working: true, quiet_analyze: true}, false)
13
+ @root_dir = @config.root_dir
14
+ @device_config = @config.device_config
15
+ FileUtils.cp(File.join(@root_dir, "manifest_template"), File.join(@root_dir, "manifest"))
16
+ @request_stubs = []
17
+ analyzer_config = nil
18
+ File.open(File.join(@root_dir, "analyzer_config.json")) do |file|
19
+ analyzer_config = file.read
20
+ end
21
+ @request_stubs.push(stub_request(:get, "http://devtools.web.roku.com/static-code-analyzer/config.json").
22
+ to_return(status: 200, body: analyzer_config, headers: {}))
23
+ folder = File.join(@root_dir, "source")
24
+ Dir.mkdir(folder) unless File.exist?(folder)
25
+ end
26
+ def teardown
27
+ manifest = File.join(@root_dir, "manifest")
28
+ FileUtils.rm(manifest) if File.exist?(manifest)
29
+ @request_stubs.each {|req| remove_request_stub(req)}
30
+ end
31
+ def test_analyzer_parse_commands
32
+ parser = OptionParser.new
33
+ options = {}
34
+ Analyzer.parse_options(parser: parser, options: options)
35
+ argv = ["roku", "--analyze"]
36
+ parser.parse! argv
37
+ assert options[:analyze]
38
+ end
39
+ def test_clean_app
40
+ warnings = test
41
+ assert_equal Array, warnings.class
42
+ end
43
+ def test_manifest_duplicate_attribute
44
+ warnings = test_manifest("manifest_duplicate_attribute")
45
+ assert_equal 1, warnings.count
46
+ assert_match(/title/, warnings[0][:message])
47
+ assert_equal 2, warnings[0][:line]
48
+ assert_equal "manifest", warnings[0][:path]
49
+ end
50
+ def test_manifest_depricated_attribute
51
+ warnings = test_manifest("manifest_depricated_attribute")
52
+ assert_equal 1, warnings.count
53
+ assert_match(/subtitle/, warnings[0][:message])
54
+ assert_equal 2, warnings[0][:line]
55
+ assert_equal "manifest", warnings[0][:path]
56
+ end
57
+ def test_manifest_empty_value
58
+ warnings = test_manifest("manifest_empty_value")
59
+ assert_equal 1, warnings.count
60
+ assert_match(/empty/, warnings[0][:message])
61
+ assert_equal 9, warnings[0][:line]
62
+ assert_equal "manifest", warnings[0][:path]
63
+ end
64
+ def test_manifest_invalid_value_integer
65
+ warnings = test_manifest("manifest_invalid_value_integer")
66
+ assert_equal 1, warnings.count
67
+ assert_match(/major_version/, warnings[0][:message])
68
+ assert_match(/bad/, warnings[0][:message])
69
+ assert_equal 2, warnings[0][:line]
70
+ assert_equal "manifest", warnings[0][:path]
71
+ end
72
+ def test_manifest_invalid_value_float
73
+ warnings = test_manifest("manifest_invalid_value_float")
74
+ assert_equal 1, warnings.count
75
+ assert_match(/rsg_version/, warnings[0][:message])
76
+ assert_match(/1/, warnings[0][:message])
77
+ assert_equal 9, warnings[0][:line]
78
+ assert_equal "manifest", warnings[0][:path]
79
+ end
80
+ def test_manifest_invalid_value_negative
81
+ warnings = test_manifest("manifest_invalid_value_negative")
82
+ assert_equal 1, warnings.count
83
+ assert_match(/major_version/, warnings[0][:message])
84
+ assert_match(/-1/, warnings[0][:message])
85
+ assert_equal 2, warnings[0][:line]
86
+ assert_equal "manifest", warnings[0][:path]
87
+ end
88
+ def test_manifest_invalid_value_not_equal
89
+ warnings = test_manifest("manifest_invalid_value_not_equal")
90
+ assert_equal 1, warnings.count
91
+ assert_match(/build_version/, warnings[0][:message])
92
+ assert_match(/0/, warnings[0][:message])
93
+ assert_equal 4, warnings[0][:line]
94
+ assert_equal "manifest", warnings[0][:path]
95
+ end
96
+ def test_manifest_invalid_value_equals
97
+ warnings = test_manifest("manifest_invalid_value_equals")
98
+ assert_equal 1, warnings.count
99
+ assert_match(/screensaver_private/, warnings[0][:message])
100
+ assert_match(/2/, warnings[0][:message])
101
+ assert_equal 9, warnings[0][:line]
102
+ assert_equal "manifest", warnings[0][:path]
103
+ end
104
+ def test_manifest_invalid_value_starts_with
105
+ warnings = test_manifest("manifest_invalid_value_starts_with")
106
+ refute_equal 0, warnings.count
107
+ assert_match(/mm_icon_focus_hd/, warnings[0][:message])
108
+ assert_match(/bad/, warnings[0][:message])
109
+ assert_match(/invalid value/, warnings[0][:message])
110
+ assert_equal 5, warnings[0][:line]
111
+ assert_equal "manifest", warnings[0][:path]
112
+ end
113
+ def test_manifest_has_value
114
+ warnings = test_manifest("manifest_has_value")
115
+ assert_equal 1, warnings.count
116
+ assert_match(/rsg_version/, warnings[0][:message])
117
+ assert_match(/1.0/, warnings[0][:message])
118
+ assert_equal 9, warnings[0][:line]
119
+ assert_equal "manifest", warnings[0][:path]
120
+ end
121
+ def test_manifest_missing_file
122
+ warnings = test_manifest("manifest_missing_file")
123
+ assert_equal 1, warnings.count
124
+ assert_match(/mm_icon_focus_hd/, warnings[0][:message])
125
+ assert_match(/missing.png/, warnings[0][:message])
126
+ assert_equal 5, warnings[0][:line]
127
+ assert_equal "manifest", warnings[0][:path]
128
+ end
129
+ def test_manifest_missing_attribute
130
+ warnings = test_manifest("manifest_missing_attribute")
131
+ assert_equal 1, warnings.count
132
+ assert_match(/title/, warnings[0][:message])
133
+ assert_equal "manifest", warnings[0][:path]
134
+ refute warnings[0][:line]
135
+ end
136
+ def test_manifest_incorrect_image_resolution
137
+ warnings = test_manifest("manifest_incorrect_image_resolution")
138
+ assert_equal 1, warnings.count
139
+ assert_match(/mm_icon_focus_hd/, warnings[0][:message])
140
+ assert_match(/too_small.png/, warnings[0][:message])
141
+ assert_match(/336x210/, warnings[0][:message])
142
+ assert_match(/1x1/, warnings[0][:message])
143
+ assert_equal 5, warnings[0][:line]
144
+ assert_equal "manifest", warnings[0][:path]
145
+ end
146
+ def test_line_inspector_depricated_component
147
+ warnings = test_file(text: "\"roVideoScreen\"")
148
+ assert_equal 1, warnings.count
149
+ assert_match(/deprecated/, warnings[0][:message])
150
+ assert_match(/roVideoScreen/, warnings[0][:message])
151
+ end
152
+ def test_line_inspector_depricated_component_xml_file
153
+ warnings = test_file(text: "\"roVideoScreen\"", file: "test.xml")
154
+ assert_equal 1, warnings.count
155
+ assert_match(/roVideoScreen/, warnings[0][:message])
156
+ end
157
+ def test_line_inspector_depricated_component_in_comment
158
+ warnings = test_file(text: "'\"roVideoScreen\"")
159
+ assert_equal 0, warnings.count
160
+ end
161
+ def test_line_inspector_depricated_component_before_comment
162
+ warnings = test_file(text: "\"roVideoScreen\"'comment")
163
+ assert_equal 1, warnings.count
164
+ assert_match(/roVideoScreen/, warnings[0][:message])
165
+ end
166
+ def test_line_inspector_depricated_component_in_xml_comment
167
+ warnings = test_file(text: "<!-- \"roVideoScreen\" -->", file: "test.xml")
168
+ assert_equal 0, warnings.count
169
+ end
170
+ def test_line_inspector_depricated_component_before_xml_comment
171
+ warnings = test_file(text: "\"roVideoScreen\" <!-- comment -->", file: "test.xml")
172
+ assert_equal 1, warnings.count
173
+ end
174
+ def test_line_inspector_depricated_component_after_xml_comment
175
+ warnings = test_file(text: "<!-- comment -->\"roVideoScreen\"", file: "test.xml")
176
+ assert_equal 1, warnings.count
177
+ end
178
+ def test_line_inspector_depricated_component_in_xml_multiline_comment
179
+ warnings = test_file(text: "<!-- line1 \n\"roVideoScreen\"\n line3 -->", file: "test.xml")
180
+ assert_equal 0, warnings.count
181
+ end
182
+ def test_line_inspector_depricated_component_in_xml_multiline_comment_start
183
+ warnings = test_file(text: "<!-- \"roVideoScreen\"\n line2 -->", file: "test.xml")
184
+ assert_equal 0, warnings.count
185
+ end
186
+ def test_line_inspector_depricated_component_in_xml_multiline_comment
187
+ warnings = test_file(text: "<!-- line1 \n\"roVideoScreen\"-->", file: "test.xml")
188
+ assert_equal 0, warnings.count
189
+ end
190
+ def test_line_inspector_depricated_component_before_xml_multiline_comment
191
+ warnings = test_file(text: "\"roVideoScreen\"<!-- line1 \n line2 -->", file: "test.xml")
192
+ assert_equal 1, warnings.count
193
+ end
194
+ def test_line_inspector_depricated_component_after_xml_multiline_comment
195
+ warnings = test_file(text: "<!-- line1 \n line2 -->\"roVideoScreen\"", file: "test.xml")
196
+ assert_equal 1, warnings.count
197
+ end
198
+ def test_line_inspector_stop_command
199
+ warnings = test_file(text: "test\nstop\n")
200
+ assert_equal 1, warnings.count
201
+ assert_equal 1, warnings[0][:line]
202
+ end
203
+ def test_raf_constructor_present_import_missing
204
+ use_manifest("manifest_raf")
205
+ warnings = test_file(text: "roku_ads()")
206
+ assert warnings.count > 0
207
+ assert_match(/constructor call is present.*import is missing/, warnings.first[:message])
208
+ end
209
+ def test_raf_constructor_present_manifest_missing
210
+ warnings = test_file(text: "library \"roku_ads.brs\"\nroku_ads()")
211
+ assert warnings.count > 0
212
+ assert_match(/manifest entry is missing/, warnings.first[:message])
213
+ end
214
+ def test_raf_constructor_missing_manifest_present
215
+ use_manifest("manifest_raf")
216
+ warnings = test_file(text: "library \"roku_ads.brs\"")
217
+ assert warnings.count > 0
218
+ assert_match(/constructor call is not present/, warnings.first[:message])
219
+ end
220
+ def test_raf_manifest_present_import_missing
221
+ use_manifest("manifest_raf")
222
+ warnings = test_file(text: "roku_ads()")
223
+ assert warnings.count > 0
224
+ assert_match(/manifest entry is present.*import is missing/, warnings.last[:message])
225
+ end
226
+ def test_raf_constructor_missing_import_present
227
+ use_manifest("manifest_raf")
228
+ warnings = test_file(text: "library \"roku_ads.brs\"")
229
+ assert warnings.count > 0
230
+ assert_match(/constructor call is not present.*import is present/, warnings.last[:message])
231
+ end
232
+ def test_raf_proper_intergration
233
+ use_manifest("manifest_raf")
234
+ warnings = test_file(text: "library \"roku_ads.brs\"\nroku_ads()")
235
+ assert_equal 1, warnings.count
236
+ assert_match(/integrated properly/, warnings[0][:message])
237
+ end
238
+ def test_raf_proper_intergration_different_case
239
+ use_manifest("manifest_raf")
240
+ warnings = test_file(text: "library \"Roku_Ads.brs\"\nRoku_Ads()")
241
+ assert_equal 1, warnings.count
242
+ assert_match(/integrated properly/, warnings[0][:message])
243
+ end
244
+ def test_macosx_directory
245
+ config = good_config(AnalyzerTest)
246
+ config[:projects][:project1][:folders].push("Test__MACOSX")
247
+ @config, @options = build_config_options_objects(AnalyzerTest, {analyze: true, working: true, quiet_analyze: true}, false, config)
248
+ folder = File.join(@root_dir, "Test__MACOSX")
249
+ Dir.mkdir(folder) unless File.exist?(folder)
250
+ warnings = test
251
+ assert_equal 1, warnings.count
252
+ assert_match(/MACOSX directory/, warnings[0][:message])
253
+ Dir.rmdir(folder) if File.exist?(folder)
254
+ end
255
+ def test_extranious_files_zip
256
+ warnings = test_file(text: "nothing", file: "test.zip")
257
+ assert_equal 1, warnings.count
258
+ assert_match(/extraneous file/, warnings[0][:message])
259
+ end
260
+ def test_extranious_files_md
261
+ warnings = test_file(text: "nothing", file: "test.md")
262
+ assert_equal 1, warnings.count
263
+ assert_match(/extraneous file/, warnings[0][:message])
264
+ end
265
+ def test_extranious_files_pkg
266
+ warnings = test_file(text: "nothing", file: "test.pkg")
267
+ assert_equal 1, warnings.count
268
+ assert_match(/extraneous file/, warnings[0][:message])
269
+ end
270
+ def test_source_directory
271
+ folder = File.join(@root_dir, "source")
272
+ Dir.rmdir(folder) if File.exist?(folder)
273
+ warnings = test
274
+ assert_equal 1, warnings.count
275
+ assert_match(/"source".*not exist/, warnings[0][:message])
276
+ end
277
+ def test_manifest_file
278
+ FileUtils.rm(File.join(@root_dir, "manifest"))
279
+ warnings = test
280
+ assert_equal 1, warnings.count
281
+ assert_match(/Manifest.*missing/, warnings[0][:message])
282
+ end
283
+ def test_logging_error
284
+ test_logger_with_file_content(text: "stop", severity: :error)
285
+ end
286
+ def test_logging_warning
287
+ test_logger_with_file_content(text: "\"roCaptionRenderer\"", severity: :warn)
288
+ end
289
+ def test_logging_info
290
+ test_logger_with_file_content(text: "\"roSGScreen\"", severity: :info)
291
+ end
292
+
293
+
294
+ private
295
+
296
+ def test_manifest(manifest_file = nil)
297
+ if manifest_file
298
+ use_manifest(manifest_file)
299
+ end
300
+ test
301
+ end
302
+
303
+ def use_manifest(manifest_file)
304
+ FileUtils.cp(File.join(@root_dir, manifest_file), File.join(@root_dir, "manifest"))
305
+ end
306
+
307
+ def test_file(text:, file: nil, quiet: true)
308
+ file ||= "test.brs"
309
+ test_file = File.join(@root_dir, "source", file)
310
+ File.open(test_file, "w") do |file|
311
+ file.write(text)
312
+ end
313
+ warnings = test(quiet)
314
+ FileUtils.rm(test_file) if File.exist?(test_file)
315
+ warnings
316
+ end
317
+
318
+ def test_logger_with_file_content(text:, severity:)
319
+ logger = Minitest::Mock.new
320
+
321
+ logger.expect(:level=, nil, [Integer])
322
+ logger.expect(:formatter=, nil, [Proc])
323
+ logger.expect(severity, nil, [String])
324
+
325
+ ::Logger.stub :new, logger do
326
+ warnings = test_file(text: text, quiet: false)
327
+ end
328
+
329
+ logger.verify
330
+ end
331
+
332
+ def test(quiet=true)
333
+ analyzer = Analyzer.new(config: @config)
334
+ analyzer.analyze(options: @options, quiet: quiet)
335
+ end
336
+
337
+ def print_all(warnings)
338
+ warnings.each do |warning|
339
+ puts warning[:message]
340
+ end
341
+ end
342
+ end
343
+ end
344
+
@@ -112,5 +112,14 @@ module RokuBuilder
112
112
  loader.delete(options: @options)
113
113
  end
114
114
  end
115
+ def test_copy_files
116
+ loader = Loader.new(config: @config)
117
+ Dir.mktmpdir do |dir|
118
+ loader.copy(options: @options, path: dir)
119
+ assert File.exist?(File.join(dir, "manifest"))
120
+ assert File.exist?(File.join(dir, "source", "b"))
121
+ assert File.exist?(File.join(dir, "source", "c", "d"))
122
+ end
123
+ end
115
124
  end
116
125
  end
@@ -196,7 +196,7 @@ module RokuBuilder
196
196
  assert_equal "/tmp/project2", configs[:project][:directory]
197
197
  end
198
198
 
199
- def test_manifest_config_project_directory_select
199
+ def test_manifest_config_project_directory_select_full_path
200
200
  options = build_options({validate: true, working: true})
201
201
  options.define_singleton_method(:source_commands){[:validate]}
202
202
  config = good_config(ConfigParserTest)
@@ -0,0 +1 @@
1
+ {"lineInspectors":[{"regex":"\"roCaptionRenderer\"","severity":"warning","message":"Found deprecated \"roCaptionRenderer\"","category":"deprecatedComponents"},{"regex":"\"roCodeRegistrationScreen\"","severity":"warning","message":"Found deprecated \"roCodeRegistrationScreen\"","category":"deprecatedComponents"},{"regex":"\"roGridScreen\"","severity":"warning","message":"Found deprecated \"roGridScreen\"","category":"deprecatedComponents"},{"regex":"\"roKeyboardScreen\"","severity":"warning","message":"Found deprecated \"roKeyboardScreen\"","category":"deprecatedComponents"},{"regex":"\"roListScreen\"","severity":"warning","message":"Found deprecated \"roListScreen\"","category":"deprecatedComponents"},{"regex":"\"roMessageDialog\"","severity":"warning","message":"Found deprecated \"roMessageDialog\"","category":"deprecatedComponents"},{"regex":"\"roOneLineDialog\"","severity":"warning","message":"Found deprecated \"roOneLineDialog\"","category":"deprecatedComponents"},{"regex":"\"roParagraphScreen\"","severity":"warning","message":"Found deprecated \"roParagraphScreen\"","category":"deprecatedComponents"},{"regex":"\"roPinEntryDialog\"","severity":"warning","message":"Found deprecated \"roPinEntryDialog\"","category":"deprecatedComponents"},{"regex":"\"roPosterScreen\"","severity":"warning","message":"Found deprecated \"roPosterScreen\"","category":"deprecatedComponents"},{"regex":"\"roSearchHistory\"","severity":"warning","message":"Found deprecated \"roSearchHistory\"","category":"deprecatedComponents"},{"regex":"\"roSearchScreen\"","severity":"warning","message":"Found deprecated \"roSearchScreen\"","category":"deprecatedComponents"},{"regex":"\"roSGGridScreen\"","severity":"warning","message":"Found deprecated \"roSGGridScreen\"","category":"deprecatedComponents"},{"regex":"\"roSlideShow\"","severity":"warning","message":"Found deprecated \"roSlideShow\"","category":"deprecatedComponents"},{"regex":"\"roSpringboardScreen\"","severity":"warning","message":"Found deprecated \"roSpringboardScreen\"","category":"deprecatedComponents"},{"regex":"\"roTextScreen\"","severity":"warning","message":"Found deprecated \"roTextScreen\"","category":"deprecatedComponents"},{"regex":"\"roVideoScreen\"","severity":"warning","message":"Found deprecated \"roVideoScreen\"","category":"deprecatedComponents"},{"regex":"\"roImageCanvas\"","severity":"warning","message":"Found deprecated \"roImageCanvas\"","category":"deprecatedComponents"},{"regex":"\"roCaptionRendererEvent\"","severity":"warning","message":"Found deprecated \"roCaptionRendererEvent\"","category":"deprecatedComponents"},{"regex":"\"roCodeRegistrationScreenEvent\"","severity":"warning","message":"Found deprecated \"roCodeRegistrationScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roGridScreenEvent\"","severity":"warning","message":"Found deprecated \"roGridScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roKeyboardScreenEvent\"","severity":"warning","message":"Found deprecated \"roKeyboardScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roListScreenEvent\"","severity":"warning","message":"Found deprecated \"roListScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roMessageDialogEvent\"","severity":"warning","message":"Found deprecated \"roMessageDialogEvent\"","category":"deprecatedComponents"},{"regex":"\"roOneLineDialogEvent\"","severity":"warning","message":"Found deprecated \"roOneLineDialogEvent\"","category":"deprecatedComponents"},{"regex":"\"roParagraphScreenEvent\"","severity":"warning","message":"Found deprecated \"roParagraphScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roPinEntryDialogEvent\"","severity":"warning","message":"Found deprecated \"roPinEntryDialogEvent\"","category":"deprecatedComponents"},{"regex":"\"roPosterScreenEvent\"","severity":"warning","message":"Found deprecated \"roPosterScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roSearchScreenEvent\"","severity":"warning","message":"Found deprecated \"roSearchScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roSGGridScreenEvent\"","severity":"warning","message":"Found deprecated \"roSGGridScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roSlideShowEvent\"","severity":"warning","message":"Found deprecated \"roSlideShowEvent\"","category":"deprecatedComponents"},{"regex":"\"roSpringboardScreenEvent\"","severity":"warning","message":"Found deprecated \"roSpringboardScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roTextScreenEvent\"","severity":"warning","message":"Found deprecated \"roTextScreenEvent\"","category":"deprecatedComponents"},{"regex":"\"roImageCanvasEvent\"","severity":"warning","message":"Found deprecated \"roImageCanvasEvent\"","category":"deprecatedComponents"},{"regexMatch":"^.*:\\s*stop\\b.*$|^(.*[^.\\s])?\\s*\\bstop\\b\\s*([^:\\s].*)?$","regex":"([^.{,\"\\s]|^)\\s*\\bstop\\b","severity":"error","message":"STOP command is present"},{"regex":"(\"ChannelStore\"|\"roChannelStore\")","severity":"info","message":"Usage of ChannelStore is spotted. Roku billing might be integrated."},{"regex":"\"roSGScreen\"","severity":"info","message":"This is an RSG channel"},{"regex":"\"TimeGrid\"","severity":"warning","message":"TimeGrid component is found"},{"regex":"\"roTuner\"","severity":"warning","message":"roTuner component is found"},{"regex":"\"roProgramGuide\"","severity":"warning","message":"roProgramGuide component is found"}],"inspectors":{"manifestDuplicateAttribute":{"severity":"warning","message":"Found duplicate attribute in manifest: \"{0}\"","category":"manifest"},"manifestDeprecatedAttribute":{"severity":"warning","message":"Found deprecated attribute in manifest: \"{0}\"","category":"manifest"},"manifestEmptyValue":{"severity":"error","message":"\"{0}\" attribute in manifest has an empty value","category":"manifest"},"manifestInvalidValue":{"severity":"error","message":"\"{0}\" attribute in manifest has invalid value: \"{1}\"","category":"manifest"},"manifestHasValue":{"severity":"warning","message":"\"{0}\" attribute in manifest has value \"{1}\"","category":"manifest"},"manifestMissingFile":{"severity":"error","message":"\"{0}\" file used for \"{1}\" attribute is missing","category":"manifest"},"manifestMissingAttribute":{"severity":"error","message":"Manifest is missing a required attribute: \"{0}\"","category":"manifest"},"manifestIncorrectImageResolution":{"severity":"error","message":"\"{0}\" image used for \"{1}\" attribute has incorrect resolution: \"{2}\". Valid resolution is \"{3}\".","category":"manifest"},"rafConstructorPresentImportMissing":{"severity":"error","message":"RAF constructor call is present but library import is missing","category":"raf"},"rafConstructorPresentManifestMissing":{"severity":"error","message":"RAF constructor call is present but manifest entry is missing","category":"raf"},"rafConstructorMissingManifestPresent":{"severity":"warning","message":"RAF constructor call is not present but manifest entry is present","category":"raf"},"rafManifestPresentImportMissing":{"severity":"warning","message":"RAF manifest entry is present but library import is missing","category":"raf"},"rafConstructorMissingImportPresent":{"severity":"warning","message":"RAF constructor call is not present but library import is present","category":"raf"},"rafProperIntegration":{"severity":"info","message":"RAF is integrated properly","category":"raf"},"packageMacosxDirectory":{"severity":"error","message":"Package includes __MACOSX directory","category":"package"},"packageExtraneousFiles":{"severity":"error","message":"Package contains extraneous file","category":"package"},"packageSourceDirectory":{"severity":"error","message":"\"source\" directory does not exist","category":"package"},"packageManifestFile":{"severity":"error","message":"Manifest file is missing","category":"package"}},"logCategories":{"uncategorized":"Uncategorized","deprecatedComponents":"Deprecated components","manifest":"Manifest","raf":"RAF","package":"Package"}}
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ subtitle=test
3
+ major_version=1
4
+ minor_version=0
5
+ build_version=1
6
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
7
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
8
+ splash_screen_hd=pkg:/images/splash_hd.png
9
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ title=Test
3
+ major_version=1
4
+ minor_version=0
5
+ build_version=1
6
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
7
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
8
+ splash_screen_hd=pkg:/images/splash_hd.png
9
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
9
+ empty
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
9
+ rsg_version=1.0
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/too_small.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
9
+ screensaver_private=2
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
9
+ rsg_version=1
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=bad
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=-1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=0
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=bad
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,7 @@
1
+ major_version=1
2
+ minor_version=0
3
+ build_version=1
4
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
5
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
6
+ splash_screen_hd=pkg:/images/splash_hd.png
7
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/missing.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -0,0 +1,9 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
9
+ bs_libs_required=roku_ads_lib
@@ -0,0 +1,8 @@
1
+ title=Test
2
+ major_version=1
3
+ minor_version=0
4
+ build_version=1
5
+ mm_icon_focus_hd=pkg:/images/focus_hd.png
6
+ mm_icon_focus_sd=pkg:/images/focus_sd.png
7
+ splash_screen_hd=pkg:/images/splash_hd.png
8
+ splash_screen_sd=pkg:/images/splash_sd.png
@@ -77,7 +77,7 @@ def good_config(klass=nil)
77
77
  default: :project1,
78
78
  project1: {
79
79
  directory: root_dir,
80
- folders: ["resources","source"],
80
+ folders: ["images","source"],
81
81
  files: ["manifest"],
82
82
  app_name: "<app name>",
83
83
  stage_method: :git,
@@ -93,7 +93,7 @@ def good_config(klass=nil)
93
93
  },
94
94
  project2: {
95
95
  directory: root_dir,
96
- folders: ["resources","source"],
96
+ folders: ["images","source"],
97
97
  files: ["manifest"],
98
98
  app_name: "<app name>",
99
99
  stage_method: :script,