-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update to version 1.1.0. fix dependencies. code refactoring.
- Loading branch information
RokuRnD
committed
Jan 25, 2017
1 parent
d15a372
commit 79452b4
Showing
67 changed files
with
5,160 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
1. Run import_unit_test_framework.bat or ./import_unit_test_framework.sh or | ||
place the UnitTestFramework.brs file to the testFramework folder manually. | ||
2. Sideload the app to the box. | ||
3. To run the tests, issue the following ECP command: | ||
curl -d '' 'http://{Roku Device IP Address}:8060/launch/dev?RunTests=true' | ||
|
||
Documentation: https://github.com/rokudev/unit-testing-framework |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
copy /Y /B ..\..\..\UnitTestFramework.brs source\testFramework\UnitTestFramework.brs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/bash | ||
cat ../../../UnitTestFramework.brs > source/testFramework/UnitTestFramework.brs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# | ||
# Copyright (c) 2017 Roku, Inc. All rights reserved. | ||
# Roku Channel Manifest File | ||
# Full spec at bit.ly/roku-manifest-file | ||
# | ||
|
||
## Channel Details | ||
title=unit_test_fw_sample | ||
major_version=1 | ||
minor_version=1 | ||
build_version=0 | ||
|
||
## Channel Assets | ||
### Main Menu Icons / Channel Poster Artwork | ||
#### Image sizes are FHD: 540x405px | HD: 290x218px | SD: 214x144px | ||
mm_icon_focus_hd=pkg:/images/MainMenu_Icon_Center_HD.png | ||
mm_icon_focus_sd=pkg:/images/MainMenu_Icon_Center_SD43.png | ||
|
||
### Legacy Required Manifest Attributes | ||
#### Image sizes are HD: 108x69px | SD: 248x140px | ||
mm_icon_side_hd=pkg:/images/MainMenu_Icon_Side_HD.png | ||
mm_icon_side_sd=pkg:/images/MainMenu_Icon_Side_SD43.png | ||
|
||
### Splash Screen + Loading Screen Artwork | ||
#### Image sizes are FHD: 1920x1080px | HD: 1280x720px | SD: 720x480px | ||
splash_screen_fhd=pkg:/images/splash_fhd.jpg | ||
splash_screen_hd=pkg:/images/splash_hd.jpg | ||
splash_screen_sd=pkg:/images/splash_sd.jpg | ||
|
||
ui_resolutions=hd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
' ********** Copyright 2017 Roku Corp. All Rights Reserved. ********** | ||
|
||
'**************************************************************** | ||
'Common channel utility functions | ||
'**************************************************************** | ||
'contains: | ||
' - RSG help utilities | ||
' - string utils functionality | ||
' - parse functionality | ||
'**************************************************************** | ||
|
||
|
||
|
||
'================================================================ | ||
' RSG help utilities | ||
'================================================================ | ||
|
||
|
||
|
||
'***************************************************************** | ||
' Copies all fields from associative array to content node. | ||
' Generally used for transforming parsed conetent from feed | ||
' to special node type that is used by other RSG nodes. | ||
' @param contentList As Object - associative array | ||
' @return As Object - valid ContentNode | ||
'***************************************************************** | ||
function Utils_ContentList2Node(contentList as Object) as Object | ||
result = createObject("roSGNode","ContentNode") | ||
|
||
for each itemAA in contentList | ||
item = createObject("roSGNode", "ContentNode") | ||
for each field in itemAA | ||
if item.hasField(field) | ||
item[field] = itemAA[field] | ||
end if | ||
end for | ||
result.appendChild(item) | ||
end for | ||
|
||
return result | ||
end function | ||
|
||
|
||
'***************************************************************** | ||
' Copies ContentNode to anouther ContentNode. | ||
' Generally used for contentNode copying with some filtering. | ||
' @param node As Object - node to copy | ||
' @param nodeType as String - type of new node | ||
' @param fieldsFilterAA as Object - roAA of fields to filter | ||
' @return As Object - copied node | ||
'***************************************************************** | ||
Function Utils_CopyNodeContent(node as Object, nodeType = "ContentNode" as String, fieldsFilterAA = {} as Object) | ||
item = createObject("roSGNode", nodeType) | ||
|
||
if node = invalid then return item | ||
|
||
existingFields = {} | ||
newFields = {} | ||
|
||
'AA of node read-only fields for filtering' | ||
if fieldsFilterAA = invalid OR fieldsFilterAA.Count() = 0 | ||
fieldsFilterAA = { | ||
focusedChild : "focusedChild" | ||
change : "change" | ||
} | ||
end if | ||
|
||
for each field in node.getFields() | ||
if item.hasField(field) AND NOT fieldsFilterAA.doesExist(field) | ||
existingFields[field] = node[field] | ||
else | ||
newFields[field] = node[field] | ||
end if | ||
end for | ||
|
||
item.setFields(existingFields) | ||
item.addFields(newFields) | ||
|
||
return item | ||
End Function | ||
|
||
'***************************************************************** | ||
' This will return the parent node that goes as parameter | ||
' otherwise return m.top. | ||
' Used for getting valid parent node of requested node. | ||
' @param nodeName As String - node name | ||
' @return As Object - valid parent Node | ||
'***************************************************************** | ||
function Utils_getParent(nodeName as String) as Object | ||
node = m.top | ||
|
||
while node <> invalid and lCase(node.subtype()) <> lCase(nodeName) | ||
node = node.getParent() | ||
end while | ||
|
||
return node | ||
end function | ||
|
||
'***************************************************************** | ||
' Add next panel to the Sliding Panel | ||
' Simple wrapper function that helps configure and add node | ||
' for RSG Sliding Panels (classes that allow you set up panels | ||
' of content that slide on and off the display screen.) | ||
' When the createNextPanlOnItemFocus field is true, | ||
' the nextPanel field should be set to a Panel node to the next panel to | ||
' add to the PanelSet in response to the createNextPanelIndex field being set. | ||
' It must be set immediately in repsonse to createNextPanelIndex field being set. | ||
' @param nextPanelName As Object - name of panel to add | ||
' @param data As Object - data to set in new panel | ||
' @param goBackCount As Object - back functionality | ||
' @param isLeftOnly As Object - check is only left panel | ||
'***************************************************************** | ||
sub Utils_addNextPanel(nextPanelName as Object, data = {} as Object, goBackCount = 1 as Integer,isLeftOnly = invalid as object) | ||
isSimplePanel = m.top.parentSubtype(m.top.subtype()) = "Panel" | ||
|
||
if isSimplePanel and not m.top.hasField("nextPanel") | ||
m.top.addField("nextPanel", "node", true) | ||
end if | ||
|
||
if type(nextPanelName) = "roString" | ||
newPanel = createObject("roSGNode", nextPanelName) | ||
if newPanel <> invalid | ||
if isLeftOnly <> invalid and type(isLeftOnly) = "roBoolean" | ||
newPanel.leftOnly = isLeftOnly | ||
end if | ||
m.top.nextPanel = newPanel | ||
if newPanel.hasField("data") | ||
newPanel.data = data | ||
end if | ||
m.top.nextPanel.goBackCount = goBackCount | ||
if isSimplePanel | ||
parentPanelSet = Utils_getParent("PanelSet") | ||
parentPanelSet.appendChild(m.top.nextPanel) | ||
m.top.setFocus(false) | ||
m.top.nextPanel.setFocus(true) | ||
end if | ||
else | ||
?"failed to create new panel" | ||
end if | ||
end if | ||
end sub | ||
|
||
'***************************************************************** | ||
' Set necessary properties to overhang node | ||
' Wrapper function that helps configurate properlyglobal Overhang node. | ||
' The Overhang node provides a information bar that is displayed at the top of | ||
' a screen in many Roku channels. The regions occupied by the overhang | ||
' can be filled with either a solid color or a bitmap. | ||
' @param title As String - title | ||
' @param optionsAvaliable As Object - are options avaliable | ||
' @param showOptions As Object - show avaliable options | ||
'***************************************************************** | ||
sub Utils_setOverhangData(title as String, optionsAvaliable = false as boolean, showOptions = optionsAvaliable as Boolean) | ||
overhang = m.global.overhang | ||
if overhang <> invalid | ||
overhang.showOptions = showOptions | ||
overhang.optionsAvailable = optionsAvaliable | ||
overhang.title = title | ||
end if | ||
end sub | ||
|
||
|
||
'================================================================ | ||
' string utils functionality | ||
'================================================================ | ||
|
||
|
||
|
||
'***************************************************************** | ||
' Utils_Join - join strings array to string with delimiter | ||
' Returns a new string with all data in array that | ||
' are separated with delimiter. | ||
' @param array As Object - strings array | ||
' @param delim As String - delimiter | ||
' @return As Dynamic - joined string | ||
'***************************************************************** | ||
Function Utils_Join(array As Object, delim = "" As String) As String | ||
result = "" | ||
If type(array) = "roArray" Then | ||
For i = 0 To array.Count() - 1 | ||
item = array[i] | ||
If NOT (LCase(type(item)) = "rostring" or LCase(type(item)) = "string") Then | ||
item = "" | ||
End If | ||
If i > 0 Then | ||
result = result + delim | ||
End If | ||
result = result + item | ||
Next | ||
End If | ||
Return result | ||
End Function | ||
|
||
|
||
|
||
'================================================================ | ||
' parse functionality | ||
'================================================================ | ||
|
||
|
||
|
||
'***************************************************************** | ||
' Utils_ParseXML - parse string XML into object | ||
' Checks if input is valid XML String and parse it to | ||
' valid roXMLElement that can be used to contain an XML tree.' | ||
' @param str As String - string to parse | ||
' @return As Dynamic - roXmlElement object or invalid | ||
'***************************************************************** | ||
Function Utils_ParseXML(str As String) As dynamic | ||
if str = invalid return invalid | ||
xml = CreateObject("roXMLElement") | ||
if not xml.Parse(str) return invalid | ||
return xml | ||
End Function |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
' ********** Copyright 2017 Roku Corp. All Rights Reserved. ********** | ||
|
||
'Channel entry point | ||
sub RunUserInterface(args) | ||
if args.RunTests = "true" and type(TestRunner) = "Function" then | ||
Runner = TestRunner() | ||
Runner.logger.SetVerbosity(2) | ||
Runner.logger.SetEcho(true) | ||
Runner.SetFailFast(true) | ||
Runner.Run() | ||
end if | ||
end sub | ||
|
||
' Part of channel specific logic, where you will work with some | ||
' external resources, like REST API, etc. You may get raw data from feed, then | ||
' parse it and return as a native BrightScript object(roAA, roArray, etc) | ||
' with some proper Content Meta-Data structure. | ||
' | ||
' If you will have a complex parsing process with a lot of external resourses, | ||
' then it will be a good practice to move all logic to separate files. | ||
Function GetApiArray() | ||
url = CreateObject("roUrlTransfer") | ||
'External resource | ||
url.SetUrl("http://api.delvenetworks.com/rest/organizations/59021fabe3b645968e382ac726cd6c7b/channels/1cfd09ab38e54f48be8498e0249f5c83/media.rss") | ||
rsp = url.GetToString() | ||
|
||
'Utility function for XML parsing. | ||
'Bassed on native Bright Script XML parser. | ||
responseXML = Utils_ParseXML(rsp) | ||
If responseXML <> invalid then | ||
responseXML = responseXML.GetChildElements() | ||
responseArray = responseXML.GetChildElements() | ||
End if | ||
|
||
'The result will be roArray object. | ||
result = [] | ||
|
||
if responseArray <> invalid AND GetInterface(responseArray, "ifArray") <> invalid then | ||
'Work with parsed XML and add to roArray some data. | ||
for each xmlItem in responseArray | ||
if xmlItem.getName() = "item" | ||
itemAA = xmlItem.GetChildElements() | ||
if itemAA <> invalid | ||
item = {} | ||
for each xmlItem in itemAA | ||
if xmlItem.getName() = "media:content" | ||
item.stream = {url : xmlItem.getAttributes().url} | ||
item.url = xmlItem.getAttributes().url | ||
item.streamFormat = "mp4" | ||
mediaContent = xmlItem.GetChildElements() | ||
for each mediaContentItem in mediaContent | ||
if mediaContentItem.getName() = "media:thumbnail" | ||
item.HDPosterUrl = mediaContentItem.getattributes().url | ||
item.hdBackgroundImageUrl = mediaContentItem.getattributes().url | ||
end if | ||
end for | ||
else | ||
item[xmlItem.getName()] = xmlItem.getText() | ||
end if | ||
end for | ||
result.push(item) | ||
end if | ||
end if | ||
end for | ||
end if | ||
return result | ||
End Function | ||
|
||
'---------------------------------------------------------------- | ||
' Prepends a prefix to every entry in Assoc Array | ||
' | ||
' @return An Assoc Array with new values if all values are Strings | ||
' or invalid if one or more value is not String. | ||
'---------------------------------------------------------------- | ||
Function AddPrefixToAAItems(AssocArray as Object) as Object | ||
prefix = "prefix__" | ||
|
||
for each key in AssocArray | ||
'Get current item | ||
item = AssocArray[key] | ||
|
||
'Check if current item is string | ||
if GetInterface(item, "ifString") <> invalid then | ||
'Prepend a prefix to current item | ||
item = prefix + item | ||
else | ||
'Return invalid if item is not string | ||
return invalid | ||
end if | ||
end for | ||
|
||
return AssocArray | ||
End Function |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
1. Run import_unit_test_framework.bat or ./import_unit_test_framework.sh or | ||
place the UnitTestFramework.brs file to the testFramework folder manually. | ||
2. Sideload the app to the box. | ||
3. To run the tests, issue the following ECP command: | ||
curl -d '' 'http://{Roku Device IP Address}:8060/launch/dev?RunTests=true' | ||
|
||
Documentation: https://github.com/rokudev/unit-testing-framework |
Oops, something went wrong.