Skip to content

Commit

Permalink
feat: add LÖVE filesystem support
Browse files Browse the repository at this point in the history
- Add hasLove() to robustly detect LÖVE runtime
- Update loadFile() to handle LÖVE filesystem
- Add explicit error handling for file loading
- Add type checking for returned data
- Fix luacheck warnings for love global
  • Loading branch information
flexiondotorg committed Jan 12, 2025
1 parent f4e6e80 commit 3c4c746
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 5 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ It provides an intuitive API for managing translations, with support for:
- Multiple locale fallbacks
- Array-based translations
- File-based translation loading
- Seamless LÖVE game engine integration for filesystem paths

### Requirements
- Lua 5.1+ or LuaJIT
- Lua 5.1-5.4 or LuaJIT 2.0-2.1
- LÖVE 11.0+ (*optional*)

### Quick example

Here's a quick example:

```lua
Expand Down
37 changes: 34 additions & 3 deletions smiti18n/init.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-- luacheck: globals love
local unpack = unpack or table.unpack -- lua 5.2 compat
local i18n = {}

Expand Down Expand Up @@ -28,6 +29,11 @@ local function dotSplit(str)
return fields, length
end

local function hasLove()
local success, loveEngine = pcall(function() return love end)
return success and type(loveEngine) == 'table' and type(loveEngine.filesystem) == 'table'
end

local function isPluralTable(t)
return type(t) == 'table' and type(t.other) == 'string'
end
Expand Down Expand Up @@ -235,10 +241,35 @@ function i18n.load(data)
end

function i18n.loadFile(path)
local chunk = assert(loadfile(path))
local data = chunk()
local data
if hasLove() then
-- LÖVE filesystem handling
local loveEngine = love -- store reference to avoid luacheck warning
local contents, readErr = loveEngine.filesystem.read(path)
if not contents then
error("Could not load i18n file: " .. tostring(readErr))
end
-- Load string as Lua code - use loadstring for 5.1, load for 5.2+
local chunk, parseErr = (loadstring or load)(contents, path)
if not chunk then
error("Could not parse i18n file: " .. tostring(parseErr))
end
data = chunk()
else
-- Standard Lua file handling
local chunk, err = loadfile(path)
if not chunk then
error("Could not load i18n file: " .. tostring(err))
end
data = chunk()
end

if type(data) ~= 'table' then
error("i18n file must return a table")
end

i18n.load(data)
end
end

setmetatable(i18n, {__call = function(_, ...) return i18n.translate(...) end})

Expand Down
49 changes: 48 additions & 1 deletion spec/i18n_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,60 @@ describe('i18n', function()
end)

describe('loadFile', function()
it("Loads a bunch of stuff", function()
after_each(function()
_G.love = nil
i18n.reset()
end)

it("loads a bunch of stuff", function()
i18n.loadFile('spec/en.lua')
assert.equal('Hello!', i18n('hello'))
local balance = i18n('balance', {value = 0})
assert.equal('Your account balance is 0.', balance)
assert.same({"one", "two", "three"}, i18n('array'))
end)

it('uses LÖVE filesystem when available', function()
_G.love = {
filesystem = {
read = function(path)
if path == 'test.lua' then
return [[return { en = { test = "LÖVE File" } }]]
end
return nil, "File not found"
end
}
}

i18n.loadFile('test.lua')
assert.equal('LÖVE File', i18n('test'))
end)

it('falls back to standard Lua IO when love has no filesystem', function()
_G.love = {}
i18n.loadFile('spec/en.lua')
assert.equal('Hello!', i18n('hello'))
end)

it('errors when file returns non-table', function()
assert.error_matches(function()
i18n.loadFile('spec/invalid_return.lua')
end, "i18n file must return a table")
end)

it('errors when LÖVE file returns non-table', function()
_G.love = {
filesystem = {
read = function(path)
return "return 123"
end
}
}

assert.error_matches(function()
i18n.loadFile('test.lua')
end, "i18n file must return a table")
end)
end)

describe('arrays', function()
Expand Down
1 change: 1 addition & 0 deletions spec/invalid_return.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
return 123 -- Returns a number instead of a table for testing error case

0 comments on commit 3c4c746

Please # to comment.