diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ca984a4 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: ClockworkSquirrel diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae5b53c --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.rbxlx.lock +*.rbxl.lock + +*.rbxlx +*.rbxl + +*.rbxmx +*.rbxm + +roblox.toml +/dist diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ea52370 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "packages/TestEZ"] + path = packages/TestEZ + url = https://github.com/Roblox/testez/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..26f81c3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "TestEZ", + "type": "PowerShell", + "request": "launch", + "script": "${workspaceFolder}/test/test.ps1", + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..10952a0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rojo.releaseBranch": "7.x" +} \ No newline at end of file diff --git a/README.md b/README.md index b735e6b..6131157 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,125 @@ -# colour-utils - Colour utility module for Roblox +# ColourUtils +ColourUtils provides handy methods for manipulating colours for your UI in Roblox. + +## Installation +* [Grab a copy from the Library (Toolbox)](https://www.roblox.com/library/6573728888) +* [Sync in with Rojo](https://rojo.space) +* [Download the model from GitHub releases](/releases/latest) + +## Usage +Here's a quick example of how ColourUtils can be used: + +```lua +local ColourUtils = require(path.to.ColourUtils) +local TextLabel = path.to.awesome.TextLabel + +local Background = ColourUtils.Hex.fromHex("#00A2FF") +local Foreground = ColourUtils.Emphasise(Background, 0.9) + +TextLabel.BackgroundColor3 = Background +TextLabel.TextColor3 = Foreground +``` + +Here's how you might use ColourUtils to generate an "accessible" text colour, [as recommended by the W3C accessibility guidelines](https://www.w3.org/TR/2008/REC-WCAG20-20081211/#visual-audio-contrast-contrast): +```lua +local ColourUtils = require(game.ServerScriptService.ColourUtils) +local TextLabel = game.StarterGui.ScreenGui.TextLabel + +local function GetAccessibleTextColour(background: Color3): Color3 + local darkThemeText = Color3.new(1, 1, 1) + local lightThemeText = ColourUtils.Lighten(Color3.new(), .13) + + local contrastRatio = ColourUtils.GetContrastRatio(background, darkThemeText) + + return contrastRatio >= 3 and darkThemeText or lightThemeText +end + +TextLabel.BackgroundColor3 = ColourUtils.Hex.fromHex("#00a2ff") +TextLabel.TextColor3 = GetAccessibleTextColour(TextLabel.BackgroundColor3) +``` + +# Documentation +## API Overview +* `ColourUtils.Darken(colour: Color3, coefficient: number): Color3` +* `ColourUtils.Lighten(colour: Color3, coefficient: number): Color3` +* `ColourUtils.Emphasise(colour: Color3, coefficient: number): Color3` +* `ColourUtils.GetContrastRatio(foreground: Color3, background: Color3): number` +* `ColourUtils.GetLuminance(colour: Color3): number` +* `ColourUtils.Hex.fromHex(hex: string): Color3` +* `ColourUtils.Hex.toHex(colour: Color3): string` +* `ColourUtils.Int.fromInt(int: number): Color3` +* `ColourUtils.Int.toInt(colour: Color3): number` + +## API Methods +### Darken +Darkens a colour. +#### Arguments +colour (`Color3`) - The `Color3` to darken\ +coefficient (`number`) - A multiplier in the range of 0-1 +#### Returns +colour `Color3` - The darkened `Color3` + +### Lighten +Lightens a colour. +#### Arguments +colour (`Color3`) - The `Color3` to lighten\ +coefficient (`number`) - A multiplier in the range of 0-1 +#### Returns +colour `Color3` - The lightened `Color3` + +### Emphasise +Automatically darken a light colour or lighten a dark colour, depending on it luminance. +#### Arguments +colour (`Color3`) - The `Color3` to affect\ +coefficient (`number`) - A multiplier in the range of 0-1 +#### Returns +colour `Color3` - The lightened or darkened `Color3` + +### GetLuminance +Get the relative brightness of a given `Color3`, using the [formula provided by WCAG](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests). +#### Arguments +colour (`Color3`) - The `Color3` to get luminance of +#### Returns +luminance (`number`) - The relative luminance of the given `Color3`, in the range of 0-1 + +### GetContrastRatio +Calculates the contrast ratio between two colours, using the [formula provided by WCAG](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests). +#### Arguments +background (`Color3`) - A `Color3` value representing the background\ +foreground (`Color3`) - A `Color3` value representing the foreground +#### Returns +ratio (`number`) - The contrast ratio of two two given colours, in the range of 0-21. + +## Hex +Hex is a submodule which enables conversion between Hex colour strings (e.g. `#8697F6`) and `Color3` values. + +### fromHex +Converts a hex string into a `Color3`. This method accepts hex strings of any length (but will only respect the first 6 characters); with or without a preceding hash (`#`). +#### Arguments +hex (`string`) - A hex colour string +#### Returns +colour (`Color3`) - The `Color3` representation of the given hex colour + +### toHex +Converts a `Color3` into a hex value. Note that this method does not prepend a hash (`#`) to the beginning of the string. +#### Arguments +colour (`Color3`) - A `Color3` to convert to hex +#### Returns +hex (`string`) - The resulting hex code of the given `Color3` + +## Int +Like the Hex submodule, Int allows for conversion between integers (e.g. `8820726` or `0x8697F6`) and `Color3` values. + +### fromInt +Converts an integer into a `Color3`. +#### Arguments +integer (`number`) - An integer representing a colour +#### Returns +colour (`Color3`) - The `Color3` representation of the given hex colour + +### toInt +Converts a `Color3` into an integer value. +#### Arguments +colour (`Color3`) - A `Color3` to convert to an integer +#### Returns +int (`number`) - The resulting integer of the given `Color3` diff --git a/default.project.json b/default.project.json new file mode 100644 index 0000000..098cfcf --- /dev/null +++ b/default.project.json @@ -0,0 +1,6 @@ +{ + "name": "ColourUtils", + "tree": { + "$path": "src" + } + } diff --git a/packages/TestEZ b/packages/TestEZ new file mode 160000 index 0000000..25d957d --- /dev/null +++ b/packages/TestEZ @@ -0,0 +1 @@ +Subproject commit 25d957d4d5c4c02a52843ef43e72f21f973c2908 diff --git a/selene.toml b/selene.toml new file mode 100644 index 0000000..49fb47e --- /dev/null +++ b/selene.toml @@ -0,0 +1 @@ +std = "roblox+testez" diff --git a/src/Darken.lua b/src/Darken.lua new file mode 100644 index 0000000..9e03736 --- /dev/null +++ b/src/Darken.lua @@ -0,0 +1,20 @@ +local clamp = math.clamp + +local fmt = string.format + +local ERR_INVALID_TYPE = "darken(...): The `%s` argument must be a %s, but you passed %q (%s)" + +local function clampColour(colour: Color3) + local red = clamp(colour.R, 0, 1) + local green = clamp(colour.G, 0, 1) + local blue = clamp(colour.B, 0, 1) + + return Color3.new(red, green, blue) +end + +return function(colour: Color3, coefficient: number): Color3 + assert(typeof(colour) == "Color3", fmt(ERR_INVALID_TYPE, "colour", "Color3", tostring(colour), typeof(colour))) + assert(type(coefficient) == "number", fmt(ERR_INVALID_TYPE, "coefficient", "number", tostring(coefficient), typeof(coefficient))) + + return clampColour(colour:Lerp(Color3.new(), coefficient)) +end diff --git a/src/Darken.spec.lua b/src/Darken.spec.lua new file mode 100644 index 0000000..3a8897a --- /dev/null +++ b/src/Darken.spec.lua @@ -0,0 +1,43 @@ +return function() + local Darken = require(script.Parent.Darken) + + it("throws if argument is not a Color3", function() + expect(pcall(Darken, true)).to.equal(false) + end) + + it("doesn't modify black", function() + expect(Darken(Color3.new(), .1)).to.equal(Color3.new()) + end) + + it("doesn't overshoot if an above-range coefficient is supplied", function() + expect(Darken(Color3.new(0, .5, 1), 1.5)).to.equal(Color3.new()) + end) + + it("doesn't overshoot if a below-range coefficient is supplied", function() + expect(Darken(Color3.new(0, .5, 1), -1.5)).to.equal(Color3.new(0, 1, 1)) + end) + + it("darkens white by 10% when coefficient is 0.1", function() + local colour = Darken(Color3.new(1, 1, 1), .1) + + expect(colour.R).to.be.near(.9, .01) + expect(colour.G).to.be.near(.9, .01) + expect(colour.B).to.be.near(.9, .01) + end) + + it("darkens red by 50% when coefficient is 0.5", function() + local colour = Darken(Color3.new(1, 0, 0), .5) + + expect(colour.R).to.be.near(.5, .01) + expect(colour.G).to.equal(0) + expect(colour.B).to.equal(0) + end) + + it("darkens grey by 50% when coefficient is 0.5", function() + expect(Darken(Color3.new(.5, .5, .5), .5)).to.equal(Color3.new(.25, .25, .25)) + end) + + it("doesn't modify colours when coefficient is 0", function() + expect(Darken(Color3.new(1, 1, 1), 0)).to.equal(Color3.new(1, 1, 1)) + end) +end diff --git a/src/Emphasise.lua b/src/Emphasise.lua new file mode 100644 index 0000000..f56f295 --- /dev/null +++ b/src/Emphasise.lua @@ -0,0 +1,7 @@ +local GetLuminance = require(script.Parent.GetLuminance) +local Lighten = require(script.Parent.Lighten) +local Darken = require(script.Parent.Darken) + +return function(colour: Color3, coefficient: number): Color3 + return GetLuminance(colour) > .5 and Darken(colour, coefficient) or Lighten(colour, coefficient) +end diff --git a/src/Emphasise.spec.lua b/src/Emphasise.spec.lua new file mode 100644 index 0000000..74ea284 --- /dev/null +++ b/src/Emphasise.spec.lua @@ -0,0 +1,15 @@ +return function() + local Emphasise = require(script.Parent.Emphasise) + local Lighten = require(script.Parent.Lighten) + local Darken = require(script.Parent.Darken) + + it("lightens a dark colour with the coefficient provided", function() + local colour = Color3.fromRGB(1, 2, 3) + expect(Emphasise(colour, .4)).to.equal(Lighten(colour, .4)) + end) + + it("darkens a light colour with the coefficient provided", function() + local colour = Color3.fromRGB(250, 240, 230) + expect(Emphasise(colour, .3)).to.equal(Darken(colour, .3)) + end) +end diff --git a/src/GetContrastRatio.lua b/src/GetContrastRatio.lua new file mode 100644 index 0000000..ef015cb --- /dev/null +++ b/src/GetContrastRatio.lua @@ -0,0 +1,18 @@ +local GetLuminance = require(script.Parent.GetLuminance) + +local max = math.max +local min = math.min + +local fmt = string.format + +local ERR_INVALID_TYPE = "getContrastRatio(...): The `%s` argument must be a Color3, but you passed %q (%s)" + +return function(foreground: Color3, background: Color3): number + assert(typeof(foreground) == "Color3", fmt(ERR_INVALID_TYPE, "foreground", tostring(foreground), typeof(foreground))) + assert(typeof(background) == "Color3", fmt(ERR_INVALID_TYPE, "background", tostring(background), typeof(background))) + + local lumA = GetLuminance(foreground) + local lumB = GetLuminance(background) + + return (max(lumA, lumB) + .05) / (min(lumA, lumB) + .05) +end diff --git a/src/GetContrastRatio.spec.lua b/src/GetContrastRatio.spec.lua new file mode 100644 index 0000000..03c2a3c --- /dev/null +++ b/src/GetContrastRatio.spec.lua @@ -0,0 +1,39 @@ +return function() + local GetContrastRatio = require(script.Parent.GetContrastRatio) + + it("throws if arguments are not Color3s", function() + expect(pcall(GetContrastRatio, Color3.new(), true)).to.equal(false) + expect(pcall(GetContrastRatio, true, Color3.new())).to.equal(false) + expect(pcall(GetContrastRatio, 100, true)).to.equal(false) + end) + + it("returns a number between 0-21", function() + local result = GetContrastRatio(Color3.new(), Color3.new(1, 1, 1)) + expect(result >= 0 and result <= 21).to.be.equal(true) + end) + + it("returns a ratio for black:white", function() + local result = GetContrastRatio(Color3.new(), Color3.new(1, 1, 1)) + expect(result).to.be.equal(21) + end) + + it("returns a ratio for black:black", function() + local result = GetContrastRatio(Color3.new(), Color3.new()) + expect(result).to.be.equal(1) + end) + + it("returns a ratio for white:white", function() + local result = GetContrastRatio(Color3.new(1, 1, 1), Color3.new(1, 1, 1)) + expect(result).to.be.equal(1) + end) + + it("returns a ratio for dark grey:light grey", function() + local result = GetContrastRatio(Color3.fromRGB(112, 112, 112), Color3.fromRGB(230, 230, 230)) + expect(result).to.be.near(3.96, .01) + end) + + it("returns a ratio for black:light grey", function() + local result = GetContrastRatio(Color3.new(), Color3.fromRGB(136, 136, 136)) + expect(result).to.be.near(5.92, .01) + end) +end diff --git a/src/GetLuminance.lua b/src/GetLuminance.lua new file mode 100644 index 0000000..1580817 --- /dev/null +++ b/src/GetLuminance.lua @@ -0,0 +1,19 @@ +local fmt = string.format + +local ERR_INVALID_TYPE = "getLuminance(...): The `%s` argument must be a %s, but you passed %q (%s)" + +local function transformValue(value: number): number + return value <= .03928 and value / 12.92 or ((value + .055) / 1.055) ^ 2.4 +end + +return function(colour: Color3): number + assert(typeof(colour) == "Color3", fmt(ERR_INVALID_TYPE, "colour", "Color3", tostring(colour), typeof(colour))) + + local red = transformValue(colour.R) + local green = transformValue(colour.G) + local blue = transformValue(colour.B) + + local lum = fmt("%.3f", .2126 * red + .7152 * green + .0722 * blue) + + return tonumber(lum) +end diff --git a/src/GetLuminance.spec.lua b/src/GetLuminance.spec.lua new file mode 100644 index 0000000..75e3c07 --- /dev/null +++ b/src/GetLuminance.spec.lua @@ -0,0 +1,19 @@ +return function() + local GetLuminance = require(script.Parent.GetLuminance) + + it("throws if argument is not a Color3", function() + expect(pcall(GetLuminance, 100)).to.equal(false) + end) + + it("returns a valid luminance for black", function() + expect(GetLuminance(Color3.new())).to.equal(0) + end) + + it("returns a valid luminance for white", function() + expect(GetLuminance(Color3.new(1, 1, 1))).to.equal(1) + end) + + it("returns a valid luminance for mid grey", function() + expect(GetLuminance(Color3.fromRGB(127, 127, 127))).to.equal(.212) + end) +end diff --git a/src/Hex.lua b/src/Hex.lua new file mode 100644 index 0000000..2073a65 --- /dev/null +++ b/src/Hex.lua @@ -0,0 +1,52 @@ +local sub = string.sub +local gsub = string.gsub +local fmt = string.format +local rep = string.rep +local split = string.split + +local HEX_EXCLUDE_PATTERN = "[^A-Fa-f0-9]" +local HEX_FORMAT_PATTERN = "%.2x%.2x%.2x" + +local ERR_NOT_TYPE = "%s(...): The argument must be a %s, but you passed %q (%s)" + +local function FromHex(hex: string): Color3 + assert(type(hex) == "string", fmt(ERR_NOT_TYPE, "fromHex", "string", tostring(hex), typeof(hex))) + + hex = gsub(hex, HEX_EXCLUDE_PATTERN, "") + + if #hex == 3 then + local characters = split(hex, "") + local finalHex = "" + + for _, character in ipairs(characters) do + finalHex ..= rep(character, 2) + end + + hex = finalHex + elseif #hex < 6 then + hex = fmt("%s%s", hex, rep(hex, 6 - #hex)) + end + + local red = tonumber(sub(hex, 1, 2), 16) + local green = tonumber(sub(hex, 3, 4), 16) + local blue = tonumber(sub(hex, 5, 6), 16) + + return Color3.fromRGB(red, green, blue) +end + +local function ToHex(colour: Color3): string + assert(typeof(colour) == "Color3", fmt(ERR_NOT_TYPE, "toHex", "Color3", tostring(colour), typeof(colour))) + + local red = colour.R * 255 + local green = colour.G * 255 + local blue = colour.B * 255 + + local hex = fmt(HEX_FORMAT_PATTERN, red, green, blue) + + return hex +end + +return { + fromHex = FromHex, + toHex = ToHex, +} diff --git a/src/Hex.spec.lua b/src/Hex.spec.lua new file mode 100644 index 0000000..53450a6 --- /dev/null +++ b/src/Hex.spec.lua @@ -0,0 +1,36 @@ +return function() + local Hex = require(script.Parent.Hex) + + describe("toHex(...)", function() + it("throws if argument is not a Color3", function() + expect(pcall(Hex.toHex, true)).to.equal(false) + end) + + it("converts a Color3 to hex", function() + expect(Hex.toHex(Color3.fromRGB(0, 162, 255))).to.equal("00a2ff") + end) + end) + + describe("fromHex(...)", function() + it("throws if argument is not a string", function() + expect(pcall(Hex.fromHex, true)).to.equal(false) + end) + + it("converts a standard 6-character hex code to Color3", function() + expect(Hex.fromHex("#00A2FF")).to.equal(Color3.fromRGB(0, 162, 255)) + end) + + it("converts a 3-character hex code to Color3", function() + expect(Hex.fromHex("#a3d")).to.equal(Color3.fromRGB(170, 51, 221)) + end) + + it("converts irregular hex codes to Color3", function() + expect(Hex.fromHex("#f")).to.equal(Color3.new(1, 1, 1)) + expect(Hex.fromHex("#9e")).to.equal(Color3.fromRGB(158, 158, 158)) + end) + + it("returns \"black\" if argument is an empty string", function() + expect(Hex.fromHex("")).to.equal(Color3.new()) + end) + end) +end diff --git a/src/Int.lua b/src/Int.lua new file mode 100644 index 0000000..909355c --- /dev/null +++ b/src/Int.lua @@ -0,0 +1,34 @@ +local floor = math.floor +local fmt = string.format + +local rshift = bit32.rshift +local lshift = bit32.lshift +local band = bit32.band + +local ERR_NOT_TYPE = "%s(...): The argument must be a %s, but you passed %q (%s)" + +local function FromInt(int: number): Color3 + assert(type(int) == "number", fmt(ERR_NOT_TYPE, "fromInt", "number", tostring(int), typeof(int))) + int = floor(int) + + local red = band(rshift(int, 16), 255) + local green = band(rshift(int, 8), 255) + local blue = band(int, 255) + + return Color3.fromRGB(red, green, blue) +end + +local function ToInt(colour: Color3): number + assert(typeof(colour) == "Color3", fmt(ERR_NOT_TYPE, "toInt", "Color3", tostring(colour), typeof(colour))) + + local int = floor(colour.R * 255) + int = lshift(int, 8) + floor(colour.G * 255) + int = lshift(int, 8) + floor(colour.B * 255) + + return int +end + +return { + fromInt = FromInt, + toInt = ToInt, +} diff --git a/src/Int.spec.lua b/src/Int.spec.lua new file mode 100644 index 0000000..cce2cae --- /dev/null +++ b/src/Int.spec.lua @@ -0,0 +1,27 @@ +return function() + local Int = require(script.Parent.Int) + + describe("toInt(...)", function() + it("throws if argument is not a Color3", function() + expect(pcall(Int.toInt, true)).to.equal(false) + end) + + it("converts a Color3 to an integer", function() + expect(Int.toInt(Color3.new())).to.equal(0) + expect(Int.toInt(Color3.fromRGB(0, 162, 255))).to.equal(0x00A2FF) + expect(Int.toInt(Color3.new(1, 1, 1))).to.equal(0xFFFFFF) + end) + end) + + describe("fromInt(...)", function() + it("throws if argument is not a number", function() + expect(pcall(Int.fromInt, true)).to.equal(false) + end) + + it("converts a number to Color3", function() + expect(Int.fromInt(0)).to.equal(Color3.new()) + expect(Int.fromInt(0x00A2FF)).to.equal(Color3.fromRGB(0, 162, 255)) + expect(Int.fromInt(0xFFFFFF)).to.equal(Color3.new(1, 1, 1)) + end) + end) +end diff --git a/src/Lighten.lua b/src/Lighten.lua new file mode 100644 index 0000000..d99cc51 --- /dev/null +++ b/src/Lighten.lua @@ -0,0 +1,20 @@ +local clamp = math.clamp + +local fmt = string.format + +local ERR_INVALID_TYPE = "lighten(...): The `%s` argument must be a %s, but you passed %q (%s)" + +local function clampColour(colour: Color3) + local red = clamp(colour.R, 0, 1) + local green = clamp(colour.G, 0, 1) + local blue = clamp(colour.B, 0, 1) + + return Color3.new(red, green, blue) +end + +return function(colour: Color3, coefficient: number): Color3 + assert(typeof(colour) == "Color3", fmt(ERR_INVALID_TYPE, "colour", "Color3", tostring(colour), typeof(colour))) + assert(type(coefficient) == "number", fmt(ERR_INVALID_TYPE, "coefficient", "number", tostring(coefficient), typeof(coefficient))) + + return clampColour(colour:Lerp(Color3.new(1, 1, 1), coefficient)) +end diff --git a/src/Lighten.spec.lua b/src/Lighten.spec.lua new file mode 100644 index 0000000..2dd7e87 --- /dev/null +++ b/src/Lighten.spec.lua @@ -0,0 +1,44 @@ +return function() + local Lighten = require(script.Parent.Lighten) + + it("throws if argument is not a Color3", function() + expect(pcall(Lighten, true)).to.equal(false) + end) + + it("doesn't modify white", function() + expect(Lighten(Color3.new(1, 1, 1), .1)).to.equal(Color3.new(1, 1, 1)) + end) + + it("doesn't overshoot if an above-range coefficient is supplied", function() + expect(Lighten(Color3.new(0, .5, 1), 1.5)).to.equal(Color3.new(1, 1, 1)) + end) + + it("doesn't overshoot if a below-range coefficient is supplied", function() + expect(Lighten(Color3.new(0, .5, 1), -1.5)).to.equal(Color3.new(0, 0, 1)) + end) + + it("lightens black to white when coefficient is 1", function() + expect(Lighten(Color3.new(0, 0, 0), 1)).to.equal(Color3.new(1, 1, 1)) + end) + + it("lightens black by 10% when coefficient is 0.1", function() + local colour = Lighten(Color3.new(0, 0, 0), .1) + + expect(colour.R).to.be.near(.1, .01) + expect(colour.G).to.be.near(.1, .01) + expect(colour.B).to.be.near(.1, .01) + end) + + it("lightens red by 50% when coefficient is 0.5", function() + local colour = Lighten(Color3.new(1, 0, 0), .5) + expect(colour).to.equal(Color3.new(1, .5, .5)) + end) + + it("lightens grey by 50% when coefficient is 0.5", function() + expect(Lighten(Color3.new(.5, .5, .5), .5)).to.equal(Color3.new(.75, .75, .75)) + end) + + it("doesn't modify colours when coefficient is 0", function() + expect(Lighten(Color3.new(.5, .5, .5), 0)).to.equal(Color3.new(.5, .5, .5)) + end) +end diff --git a/src/init.lua b/src/init.lua new file mode 100644 index 0000000..4c83f9c --- /dev/null +++ b/src/init.lua @@ -0,0 +1,11 @@ +local module = { + Darken = require(script.Darken), + Emphasise = require(script.Emphasise), + GetContrastRatio = require(script.GetContrastRatio), + GetLuminance = require(script.GetLuminance), + Hex = require(script.Hex), + Int = require(script.Int), + Lighten = require(script.Lighten), +} + +return module diff --git a/test.project.json b/test.project.json new file mode 100644 index 0000000..20b0d44 --- /dev/null +++ b/test.project.json @@ -0,0 +1,24 @@ +{ + "name": "colour-utils-test", + "tree": { + "$className": "DataModel", + "ServerScriptService": { + "$className": "ServerScriptService", + "ColourUtils": { + "$path": "src" + } + }, + "TestService": { + "$className": "TestService", + "$properties": { + "ExecuteWithStudioRun": true + }, + "TestEZ": { + "$path": "packages/TestEZ/src" + }, + "TestRunner": { + "$path": "test/test-runner.server.lua" + } + } + } +} diff --git a/test/build.ps1 b/test/build.ps1 new file mode 100644 index 0000000..3060abd --- /dev/null +++ b/test/build.ps1 @@ -0,0 +1,2 @@ +rojo build .\default.project.json -o .\dist\ColourUtils.rbxm +rojo build .\default.project.json -o .\dist\ColourUtils.rbxmx diff --git a/test/test-runner.server.lua b/test/test-runner.server.lua new file mode 100644 index 0000000..d78d7d5 --- /dev/null +++ b/test/test-runner.server.lua @@ -0,0 +1,8 @@ +local ServerScripts = game:GetService("ServerScriptService") +local TestService = game:GetService("TestService") + +local TestEZ = require(TestService.TestEZ) + +TestEZ.TestBootstrap:run({ + ServerScripts.ColourUtils, +}) diff --git a/test/test.ps1 b/test/test.ps1 new file mode 100644 index 0000000..c1ac2fc --- /dev/null +++ b/test/test.ps1 @@ -0,0 +1,2 @@ +rojo build .\test.project.json -o .\test\TestPlace.rbxlx +run-in-roblox --place .\test\TestPlace.rbxlx --script .\test\test-runner.server.lua diff --git a/testez.toml b/testez.toml new file mode 100644 index 0000000..adc2434 --- /dev/null +++ b/testez.toml @@ -0,0 +1,67 @@ +# TestEZ +[[afterAll.args]] +type = "function" + +[[afterEach.args]] +type = "function" + +[[beforeAll.args]] +type = "function" + +[[beforeEach.args]] +type = "function" + +[[describe.args]] +type = "string" + +[[describe.args]] +type = "function" + +[[describeFOCUS.args]] +type = "string" + +[[describeFOCUS.args]] +type = "function" + +[[describeSKIP.args]] +type = "string" + +[[describeSKIP.args]] +type = "function" + +[[expect.args]] +type = "any" + +[[FIXME.args]] +type = "string" +required = false + +[FOCUS] +args = [] + +[[it.args]] +type = "string" + +[[it.args]] +type = "function" + +[[itFIXME.args]] +type = "string" + +[[itFIXME.args]] +type = "function" + +[[itFOCUS.args]] +type = "string" + +[[itFOCUS.args]] +type = "function" + +[[itSKIP.args]] +type = "string" + +[[itSKIP.args]] +type = "function" + +[SKIP] +args = []