From 3f654ef2a63f6216d541ba2016dd6771304014f0 Mon Sep 17 00:00:00 2001 From: Richard Ward Date: Tue, 30 Dec 2025 14:14:52 +0000 Subject: [PATCH] config: tsx,packages,icons (6 files) --- fakemui/icons/ViewCarousel.tsx | 10 ++ fakemui/icons/ViewDay.tsx | 10 ++ fakemui/icons/ViewWeek.tsx | 10 ++ .../seed/scripts/tests/pagination.cases.json | 159 ++++++++++++++++++ .../seed/scripts/tests/pagination.test.lua | 56 ++++++ .../seed/scripts/lua/retro_helpers.lua | 106 ++++++------ 6 files changed, 298 insertions(+), 53 deletions(-) create mode 100644 fakemui/icons/ViewCarousel.tsx create mode 100644 fakemui/icons/ViewDay.tsx create mode 100644 fakemui/icons/ViewWeek.tsx create mode 100644 packages/data_table/seed/scripts/tests/pagination.cases.json create mode 100644 packages/data_table/seed/scripts/tests/pagination.test.lua diff --git a/fakemui/icons/ViewCarousel.tsx b/fakemui/icons/ViewCarousel.tsx new file mode 100644 index 000000000..ab19dab23 --- /dev/null +++ b/fakemui/icons/ViewCarousel.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { Icon, IconProps } from './Icon' + +export const ViewCarousel = (props: IconProps) => ( + + + + + +) diff --git a/fakemui/icons/ViewDay.tsx b/fakemui/icons/ViewDay.tsx new file mode 100644 index 000000000..1181a9d03 --- /dev/null +++ b/fakemui/icons/ViewDay.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { Icon, IconProps } from './Icon' + +export const ViewDay = (props: IconProps) => ( + + + + + +) diff --git a/fakemui/icons/ViewWeek.tsx b/fakemui/icons/ViewWeek.tsx new file mode 100644 index 000000000..c0d6a5110 --- /dev/null +++ b/fakemui/icons/ViewWeek.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { Icon, IconProps } from './Icon' + +export const ViewWeek = (props: IconProps) => ( + + + + + +) diff --git a/packages/data_table/seed/scripts/tests/pagination.cases.json b/packages/data_table/seed/scripts/tests/pagination.cases.json new file mode 100644 index 000000000..8b010d225 --- /dev/null +++ b/packages/data_table/seed/scripts/tests/pagination.cases.json @@ -0,0 +1,159 @@ +{ + "calculate": [ + { + "desc": "First page of many", + "total": 100, + "page": 1, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": false, + "expected_has_next": true + }, + { + "desc": "Middle page", + "total": 100, + "page": 5, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": true, + "expected_has_next": true + }, + { + "desc": "Last page", + "total": 100, + "page": 10, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": true, + "expected_has_next": false + }, + { + "desc": "Single page", + "total": 5, + "page": 1, + "per_page": 10, + "expected_pages": 1, + "expected_has_prev": false, + "expected_has_next": false + }, + { + "desc": "Partial last page", + "total": 95, + "page": 10, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": true, + "expected_has_next": false + }, + { + "desc": "Large dataset first page", + "total": 1000, + "page": 1, + "per_page": 25, + "expected_pages": 40, + "expected_has_prev": false, + "expected_has_next": true + }, + { + "desc": "Large dataset middle page", + "total": 1000, + "page": 20, + "per_page": 25, + "expected_pages": 40, + "expected_has_prev": true, + "expected_has_next": true + }, + { + "desc": "Large dataset last page", + "total": 1000, + "page": 40, + "per_page": 25, + "expected_pages": 40, + "expected_has_prev": true, + "expected_has_next": false + }, + { + "desc": "Small per_page value", + "total": 50, + "page": 3, + "per_page": 5, + "expected_pages": 10, + "expected_has_prev": true, + "expected_has_next": true + }, + { + "desc": "Large per_page value", + "total": 50, + "page": 1, + "per_page": 100, + "expected_pages": 1, + "expected_has_prev": false, + "expected_has_next": false + }, + { + "desc": "Odd total with even per_page", + "total": 99, + "page": 1, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": false, + "expected_has_next": true + }, + { + "desc": "Even total with odd per_page", + "total": 100, + "page": 1, + "per_page": 7, + "expected_pages": 15, + "expected_has_prev": false, + "expected_has_next": true + }, + { + "desc": "Second page of two", + "total": 15, + "page": 2, + "per_page": 10, + "expected_pages": 2, + "expected_has_prev": true, + "expected_has_next": false + } + ], + "render": [ + { + "desc": "Renders first page", + "total": 100, + "page": 1, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": false, + "expected_has_next": true + }, + { + "desc": "Renders middle page", + "total": 100, + "page": 5, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": true, + "expected_has_next": true + }, + { + "desc": "Renders last page", + "total": 100, + "page": 10, + "per_page": 10, + "expected_pages": 10, + "expected_has_prev": true, + "expected_has_next": false + }, + { + "desc": "Renders single page", + "total": 5, + "page": 1, + "per_page": 10, + "expected_pages": 1, + "expected_has_prev": false, + "expected_has_next": false + } + ] +} diff --git a/packages/data_table/seed/scripts/tests/pagination.test.lua b/packages/data_table/seed/scripts/tests/pagination.test.lua new file mode 100644 index 000000000..8c439030a --- /dev/null +++ b/packages/data_table/seed/scripts/tests/pagination.test.lua @@ -0,0 +1,56 @@ +-- Pagination tests +-- Uses lua_test framework with parameterized test cases + +describe("Pagination", function() + local cases = load_cases("pagination.cases.json") + local pagination = require("pagination") + + describe("calculate", function() + it_each(cases.calculate, "$desc", function(tc) + local result = pagination.calculate(tc.total, tc.page, tc.per_page) + expect(result.total).toBe(tc.total) + expect(result.page).toBe(tc.page) + expect(result.per_page).toBe(tc.per_page) + expect(result.pages).toBe(tc.expected_pages) + expect(result.has_prev).toBe(tc.expected_has_prev) + expect(result.has_next).toBe(tc.expected_has_next) + end) + end) + + describe("render", function() + it_each(cases.render, "$desc", function(tc) + local state = pagination.calculate(tc.total, tc.page, tc.per_page) + local result = pagination.render(state) + expect(result.type).toBe("pagination") + expect(result.props.current).toBe(tc.page) + expect(result.props.total).toBe(tc.expected_pages) + expect(result.props.show_prev).toBe(tc.expected_has_prev) + expect(result.props.show_next).toBe(tc.expected_has_next) + expect(result.props.on_prev).toBe("prev_page") + expect(result.props.on_next).toBe("next_page") + end) + end) + + describe("edge cases", function() + it("handles zero items", function() + local result = pagination.calculate(0, 1, 10) + expect(result.pages).toBe(0) + expect(result.has_prev).toBe(false) + expect(result.has_next).toBe(false) + end) + + it("handles single item", function() + local result = pagination.calculate(1, 1, 10) + expect(result.pages).toBe(1) + expect(result.has_prev).toBe(false) + expect(result.has_next).toBe(false) + end) + + it("handles exact page boundary", function() + local result = pagination.calculate(100, 1, 10) + expect(result.pages).toBe(10) + expect(result.has_prev).toBe(false) + expect(result.has_next).toBe(true) + end) + end) +end) diff --git a/packages/media_center/seed/scripts/lua/retro_helpers.lua b/packages/media_center/seed/scripts/lua/retro_helpers.lua index cf2e74a07..c82dd96e5 100644 --- a/packages/media_center/seed/scripts/lua/retro_helpers.lua +++ b/packages/media_center/seed/scripts/lua/retro_helpers.lua @@ -326,11 +326,11 @@ retro_helpers.MOTION = { end, } ---- Execute a motion then press a button ---- @param session_id string ---- @param motion function Motion from MOTION table ---- @param button string Button to press after motion ---- @param player? number +---Execute a motion then press a button +---@param session_id string Session identifier +---@param motion function Motion from MOTION table +---@param button string Button to press after motion +---@param player? number Player number (default 0) function retro_helpers.special_move(session_id, motion, button, player) motion(session_id, player) retro_helpers.tap(session_id, button, player) @@ -459,8 +459,8 @@ retro_helpers.SHADERS = { bilinear = "Bilinear (smooth)", } ---- Get available cores from the daemon ---- @return LibretroCore[] +---Get available cores from the daemon +---@return LibretroCore[] cores List of available cores function retro_helpers.get_available_cores() local response = http.get("/api/v1/retro/cores") if response.status == 200 then @@ -469,9 +469,9 @@ function retro_helpers.get_available_cores() return {} end ---- Get recommended core for a ROM file ---- @param rom_path string Path to the ROM ---- @return LibretroCore|nil +---Get recommended core for a ROM file +---@param rom_path string Path to the ROM +---@return LibretroCore|nil core Recommended core or nil if none found function retro_helpers.get_core_for_rom(rom_path) local response = http.post("/api/v1/retro/detect-core", { rom_path = rom_path @@ -482,10 +482,10 @@ function retro_helpers.get_core_for_rom(rom_path) return nil end ---- Start a new gaming session ---- @param config RetroSessionConfig ---- @return string|nil session_id ---- @return string|nil error +---Start a new gaming session +---@param config RetroSessionConfig Session configuration +---@return string|nil session_id Session ID if successful +---@return string|nil error Error message if failed function retro_helpers.start_session(config) local response = http.post("/api/v1/retro/sessions", { rom_path = config.rom_path, @@ -503,18 +503,18 @@ function retro_helpers.start_session(config) return nil, response.json.error or "Failed to start session" end ---- Stop a gaming session ---- @param session_id string ---- @return boolean success +---Stop a gaming session +---@param session_id string Session identifier +---@return boolean success Whether stop was successful function retro_helpers.stop_session(session_id) local response = http.delete("/api/v1/retro/sessions/" .. session_id) return response.status == 200 or response.status == 204 end ---- Pause/resume a session ---- @param session_id string ---- @param paused boolean ---- @return boolean success +---Pause or resume a session +---@param session_id string Session identifier +---@param paused boolean True to pause, false to resume +---@return boolean success Whether operation was successful function retro_helpers.set_paused(session_id, paused) local response = http.patch("/api/v1/retro/sessions/" .. session_id, { paused = paused @@ -522,9 +522,9 @@ function retro_helpers.set_paused(session_id, paused) return response.status == 200 end ---- Get session state ---- @param session_id string ---- @return RetroSessionState|nil +---Get session state +---@param session_id string Session identifier +---@return RetroSessionState|nil state Session state or nil if not found function retro_helpers.get_session_state(session_id) local response = http.get("/api/v1/retro/sessions/" .. session_id) if response.status == 200 then @@ -533,8 +533,8 @@ function retro_helpers.get_session_state(session_id) return nil end ---- List all active sessions ---- @return RetroSessionState[] +---List all active sessions +---@return RetroSessionState[] sessions Array of active sessions function retro_helpers.list_sessions() local response = http.get("/api/v1/retro/sessions") if response.status == 200 then @@ -545,11 +545,11 @@ end -- Save State Management ---- Create a save state ---- @param session_id string ---- @param slot? number Slot number (0-9), or -1 for auto ---- @param description? string Optional description ---- @return SaveState|nil +---Create a save state +---@param session_id string Session identifier +---@param slot? number Slot number (0-9), or -1 for auto +---@param description? string Optional description +---@return SaveState|nil state Save state info or nil if failed function retro_helpers.save_state(session_id, slot, description) local response = http.post("/api/v1/retro/sessions/" .. session_id .. "/states", { slot = slot or -1, @@ -561,18 +561,18 @@ function retro_helpers.save_state(session_id, slot, description) return nil end ---- Load a save state ---- @param session_id string ---- @param slot number Slot number to load ---- @return boolean success +---Load a save state +---@param session_id string Session identifier +---@param slot number Slot number to load +---@return boolean success Whether load was successful function retro_helpers.load_state(session_id, slot) local response = http.post("/api/v1/retro/sessions/" .. session_id .. "/states/" .. slot .. "/load") return response.status == 200 end ---- List save states for a session ---- @param session_id string ---- @return SaveState[] +---List save states for a session +---@param session_id string Session identifier +---@return SaveState[] states Array of save states function retro_helpers.list_save_states(session_id) local response = http.get("/api/v1/retro/sessions/" .. session_id .. "/states") if response.status == 200 then @@ -581,10 +581,10 @@ function retro_helpers.list_save_states(session_id) return {} end ---- Delete a save state ---- @param session_id string ---- @param state_id string ---- @return boolean success +---Delete a save state +---@param session_id string Session identifier +---@param state_id string State identifier +---@return boolean success Whether delete was successful function retro_helpers.delete_save_state(session_id, state_id) local response = http.delete("/api/v1/retro/sessions/" .. session_id .. "/states/" .. state_id) return response.status == 200 or response.status == 204 @@ -592,11 +592,11 @@ end -- Input handling ---- Send button input ---- @param session_id string ---- @param player number Player number (0-3) ---- @param button string Button name (a, b, x, y, start, select, up, down, left, right, l, r) ---- @param pressed boolean True for press, false for release +---Send button input +---@param session_id string Session identifier +---@param player number Player number (0-3) +---@param button string Button name (a, b, x, y, start, select, up, down, left, right, l, r) +---@param pressed boolean True for press, false for release function retro_helpers.send_input(session_id, player, button, pressed) http.post("/api/v1/retro/sessions/" .. session_id .. "/input", { player = player, @@ -605,12 +605,12 @@ function retro_helpers.send_input(session_id, player, button, pressed) }) end ---- Send analog stick input ---- @param session_id string ---- @param player number ---- @param stick string "left" or "right" ---- @param x number -1.0 to 1.0 ---- @param y number -1.0 to 1.0 +---Send analog stick input +---@param session_id string Session identifier +---@param player number Player number (0-3) +---@param stick string "left" or "right" +---@param x number -1.0 to 1.0 horizontal axis +---@param y number -1.0 to 1.0 vertical axis function retro_helpers.send_analog(session_id, player, stick, x, y) http.post("/api/v1/retro/sessions/" .. session_id .. "/input/analog", { player = player,