roku_builder 4.7.2 → 4.8.0

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.
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,