add gs
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"language": {
|
||||
"mode": "nonstrict"
|
||||
},
|
||||
"lint": {
|
||||
"LocalShadow": "fatal",
|
||||
"ImplicitReturn": "fatal"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
local AnalyticsService = game:GetService("RbxAnalyticsService")
|
||||
local RunService = game:GetService("RunService")
|
||||
local UserInputService = game:GetService("UserInputService")
|
||||
|
||||
local SETTINGS_HUB_INVITE_RELEASE_STREAM_TIME = 10
|
||||
|
||||
local function getPlatformTarget()
|
||||
local platformTarget = "unknownLua"
|
||||
local platformEnum = Enum.Platform.None
|
||||
|
||||
-- the call to GetPlatform is wrapped in a pcall() because the Testing Service
|
||||
-- executes the scripts in the wrong authorization level
|
||||
pcall(function()
|
||||
platformEnum = UserInputService:GetPlatform()
|
||||
end)
|
||||
|
||||
-- bucket the platform based on consumer platform
|
||||
local isDesktopClient = (platformEnum == Enum.Platform.Windows) or (platformEnum == Enum.Platform.OSX)
|
||||
|
||||
local isMobileClient = (platformEnum == Enum.Platform.IOS) or (platformEnum == Enum.Platform.Android)
|
||||
isMobileClient = isMobileClient or (platformEnum == Enum.Platform.UWP)
|
||||
|
||||
local isConsole = (platformEnum == Enum.Platform.XBox360) or (platformEnum == Enum.Platform.XBoxOne)
|
||||
isConsole = isConsole or (platformEnum == Enum.Platform.PS3) or (platformEnum == Enum.Platform.PS4)
|
||||
isConsole = isConsole or (platformEnum == Enum.Platform.WiiU)
|
||||
|
||||
-- assign a target based on the form factor
|
||||
if isDesktopClient then
|
||||
platformTarget = "client"
|
||||
elseif isMobileClient then
|
||||
platformTarget = "mobile"
|
||||
elseif isConsole then
|
||||
platformTarget = "console"
|
||||
else
|
||||
-- if we don't have a name for the form factor, report it here so that we can eventually track it down
|
||||
platformTarget = platformTarget .. tostring(platformEnum)
|
||||
end
|
||||
|
||||
return platformTarget
|
||||
end
|
||||
|
||||
local EventStream = {}
|
||||
EventStream.__index = EventStream
|
||||
|
||||
function EventStream.new(overridePlatformTarget, overrideAnalyticsImpl)
|
||||
local self = {}
|
||||
setmetatable(self, EventStream)
|
||||
|
||||
self._analyticsImpl = overrideAnalyticsImpl or AnalyticsService
|
||||
self._platformTarget = overridePlatformTarget or getPlatformTarget()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function EventStream:setRBXEventStream(eventContext, eventName, additionalArgs)
|
||||
additionalArgs = additionalArgs or {}
|
||||
-- this function sends reports to the server in batches, not real-time
|
||||
self._analyticsImpl:SetRBXEventStream(self._platformTarget, eventContext, eventName, additionalArgs)
|
||||
|
||||
if not self.timerSteppedConnection then
|
||||
local lastGameTime = time()
|
||||
self.timerSteppedConnection = RunService.Stepped:Connect(function(gameTime)
|
||||
if gameTime - lastGameTime > SETTINGS_HUB_INVITE_RELEASE_STREAM_TIME then
|
||||
self:releaseRBXEventStream()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function EventStream:releaseRBXEventStream()
|
||||
self._analyticsImpl:ReleaseRBXEventStream(self._platformTarget)
|
||||
if self.timerSteppedConnection then
|
||||
self.timerSteppedConnection:Disconnect()
|
||||
self.timerSteppedConnection = nil
|
||||
end
|
||||
end
|
||||
|
||||
return EventStream
|
||||
@@ -0,0 +1,97 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local HttpService = game:GetService("HttpService")
|
||||
|
||||
local LuaApp = CorePackages.AppTempCommon.LuaApp
|
||||
|
||||
local Promise = require(LuaApp.Promise)
|
||||
|
||||
local DEFAULT_THROTTLING_PRIORITY = Enum.ThrottlingPriority.Extreme
|
||||
local DEFAULT_POST_ASYNC_CONTENT_TYPE = Enum.HttpContentType.ApplicationJson
|
||||
|
||||
-- httpRequest : (table, optional) an object that implements the same http functions as the data model
|
||||
return function(httpImpl)
|
||||
|
||||
local function doHttpPost(url, options)
|
||||
local jsonPayload
|
||||
assert(options.postBody, "Expected a postBody to be specified with this request")
|
||||
if type(options.postBody) == "table" then
|
||||
jsonPayload = HttpService:JSONEncode(options.postBody)
|
||||
elseif type(options.postBody) == "string" then
|
||||
jsonPayload = options.postBody
|
||||
else
|
||||
error("Expected postBody to be a string or table")
|
||||
end
|
||||
|
||||
if not options.contentType then
|
||||
options.contentType = DEFAULT_POST_ASYNC_CONTENT_TYPE
|
||||
end
|
||||
|
||||
if not options.throttlingPriority then
|
||||
options.throttlingPriority = DEFAULT_THROTTLING_PRIORITY
|
||||
end
|
||||
|
||||
return function()
|
||||
return httpImpl:PostAsyncFullUrl(
|
||||
url,
|
||||
jsonPayload,
|
||||
options.throttlingPriority,
|
||||
options.contentType
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function doHttpGet(url)
|
||||
return function()
|
||||
return httpImpl:GetAsyncFullUrl(url, DEFAULT_THROTTLING_PRIORITY)
|
||||
end
|
||||
end
|
||||
|
||||
-- return the request function
|
||||
-- url : (string)
|
||||
-- requestMethod : (string) "GET", "POST"
|
||||
-- args : (table, optional)
|
||||
-- options.throttlingPriority : (Enum.ThrottlingPriority, optional)
|
||||
-- options.contentType : (Enum.HttpContentType, optional)
|
||||
-- options.postBody : (string, optional ("POST" only))
|
||||
-- RETURNS : (promise<HttpResponse or string>)
|
||||
return function(url, requestMethod, options)
|
||||
assert(type(url) == "string", "Expected url to be a string")
|
||||
assert(type(requestMethod) == "string", "Expected requestMethod to be a string")
|
||||
assert(not options or type(options) == "table", "Expected options to be a table")
|
||||
requestMethod = string.upper(requestMethod)
|
||||
|
||||
local httpFunction
|
||||
if requestMethod == "POST" then
|
||||
httpFunction = doHttpPost(url, options)
|
||||
elseif requestMethod == "GET" then
|
||||
httpFunction = doHttpGet(url)
|
||||
else
|
||||
error(string.format("Unsupported requestMethod : %s", requestMethod or "nil"))
|
||||
end
|
||||
|
||||
return Promise.new(function(resolve, reject)
|
||||
if httpFunction then
|
||||
spawn(function()
|
||||
local success, response = pcall(httpFunction)
|
||||
|
||||
if success then
|
||||
local jsonSuccess, decodedJson = pcall(function()
|
||||
return HttpService:JSONDecode(response)
|
||||
end)
|
||||
if jsonSuccess then
|
||||
resolve({
|
||||
responseBody = decodedJson,
|
||||
})
|
||||
else
|
||||
reject(decodedJson)
|
||||
end
|
||||
else
|
||||
reject(response)
|
||||
end
|
||||
end)
|
||||
else
|
||||
reject()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
return function()
|
||||
local httpRequest = require(script.Parent.httpRequest)
|
||||
|
||||
local function createTestRequestFunc(testResponse)
|
||||
local requestService = {}
|
||||
function requestService:GetAsyncFullUrl()
|
||||
return testResponse
|
||||
end
|
||||
function requestService:PostAsyncFullUrl()
|
||||
return testResponse
|
||||
end
|
||||
|
||||
return httpRequest(requestService)
|
||||
end
|
||||
|
||||
it("should return a function", function()
|
||||
expect(httpRequest()).to.be.ok()
|
||||
expect(type(httpRequest())).to.equal("function")
|
||||
end)
|
||||
|
||||
it("should validate its inputs", function()
|
||||
local testRequest = createTestRequestFunc()
|
||||
local function testParams(url, requestMethod, args)
|
||||
return function()
|
||||
testRequest(url, requestMethod, args)
|
||||
end
|
||||
end
|
||||
|
||||
local validUrl = "friends.roblox.com"
|
||||
local validMethod = "GET"
|
||||
local validArgs = {}
|
||||
|
||||
-- url checks
|
||||
expect(testParams(nil, validMethod, validArgs)).to.throw()
|
||||
expect(testParams(123, validMethod, validArgs)).to.throw()
|
||||
expect(testParams({}, validMethod, validArgs)).to.throw()
|
||||
expect(testParams(true, validMethod, validArgs)).to.throw()
|
||||
expect(testParams(function() end, validMethod, validArgs)).to.throw()
|
||||
|
||||
-- request method checks
|
||||
expect(testParams(validUrl, nil, validArgs)).to.throw()
|
||||
expect(testParams(validUrl, 123, validArgs)).to.throw()
|
||||
expect(testParams(validUrl, {}, validArgs)).to.throw()
|
||||
expect(testParams(validUrl, true, validArgs)).to.throw()
|
||||
expect(testParams(validUrl, function() end, validArgs)).to.throw()
|
||||
|
||||
-- args checks
|
||||
expect(testParams(validUrl, validMethod, 123)).to.throw()
|
||||
expect(testParams(validUrl, validMethod, "Test")).to.throw()
|
||||
expect(testParams(validUrl, validMethod, true)).to.throw()
|
||||
expect(testParams(validUrl, validMethod, function() end)).to.throw()
|
||||
end)
|
||||
|
||||
it("should throw an error if the requestMethod isn't supported", function()
|
||||
local testRequest = createTestRequestFunc("foo")
|
||||
|
||||
expect(function()
|
||||
testRequest("testUrl", "GIVEANDTAKE")
|
||||
end).to.throw()
|
||||
end)
|
||||
end
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
return function(targetString, blacklistedCharacter)
|
||||
local charactersArray = {}
|
||||
local indexArray = {}
|
||||
for index, byte in utf8.codes(targetString) do
|
||||
local graphemeCharacter = utf8.char(byte)
|
||||
table.insert(charactersArray, 1, graphemeCharacter)
|
||||
table.insert(indexArray, 1, index)
|
||||
end
|
||||
for index, graphemeCharacter in ipairs(charactersArray) do
|
||||
if graphemeCharacter ~= blacklistedCharacter then
|
||||
return targetString:sub(1, indexArray[index])
|
||||
end
|
||||
end
|
||||
|
||||
return ""
|
||||
end
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
return function()
|
||||
local trimCharacterFromEndString = require(script.Parent.trimCharacterFromEndString)
|
||||
|
||||
describe("single byte characters", function()
|
||||
it("should not trim a string if it does not end with passed character", function()
|
||||
local passedString = "testing"
|
||||
local passedCharacter = "/"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(passedString)
|
||||
end)
|
||||
|
||||
it("should trim a string if it ends with a single instance of the passed character", function()
|
||||
local passedString = "testing/"
|
||||
local passedCharacter = "/"
|
||||
local expectedString = "testing"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
|
||||
end)
|
||||
|
||||
it("should trim a string if it ends with multiple instances of the passed character", function()
|
||||
local passedString = "testing///"
|
||||
local passedCharacter = "/"
|
||||
local expectedString = "testing"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
|
||||
end)
|
||||
|
||||
it("should do nothing if the passed character is empty", function()
|
||||
local passedString = "hunter2"
|
||||
local passedCharacter = ""
|
||||
local expectedString = "hunter2"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("multiple byte characters", function()
|
||||
it("should not trim a string if it does not end with passed character", function()
|
||||
local passedString = "testing"
|
||||
local passedCharacter = "🐶"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(passedString)
|
||||
end)
|
||||
|
||||
it("should trim a string if it ends with a single instance of the passed character", function()
|
||||
local passedString = "testing🐶"
|
||||
local passedCharacter = "🐶"
|
||||
local expectedString = "testing"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
|
||||
end)
|
||||
|
||||
it("should trim a string if it ends with multiple instances of the passed character", function()
|
||||
local passedString = "testing🐶🐶🐶"
|
||||
local passedCharacter = "🐶"
|
||||
local expectedString = "testing"
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("a string with all blacklisted characters", function()
|
||||
it("should return a empty string", function()
|
||||
local passedString = "pppppppppppp"
|
||||
local passedCharacter = "p"
|
||||
local expectedString = ""
|
||||
|
||||
expect(trimCharacterFromEndString(passedString, passedCharacter)).to.equal(expectedString)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user