Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

refactor: optimize code and improve test coverage #14

Merged
merged 3 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .actrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--secret-file=$HOME/.config/act/secrets
--artifact-server-path=./artifacts
--pull=false
48 changes: 41 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,44 @@ jobs:
run: |
luacov
cat luacov.report.out
{
echo "# Test Coverage Summary - ${{ matrix.lua-version }}"
echo ""
echo "| File | Hits | Missed | Coverage |"
echo "|------|------|---------|----------|"
grep "^smiti18n/.*[0-9]" luacov.report.out | sort -u | sed -E 's/^([^|]+[^ ])[[:space:]]+([0-9]+)[[:space:]]+([0-9]+)[[:space:]]+([0-9.]+)%[[:space:]]*$/| \1 | \2 | \3 | \4% |/'
} >> $GITHUB_STEP_SUMMARY
cp luacov.report.out luacov-${{ matrix.lua-version }}.txt
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: luacov-${{ matrix.lua-version }}.txt
path: luacov-${{ matrix.lua-version }}.txt
- name: Create coverage table script
run: |
cat > coverage-table.lua << 'EOF'
local output = {
string.format("# Test Coverage Summary - %s\n", os.getenv("LUA_VERSION")),
"| File | Hits | Missed | Coverage |\n",
"|------|------|---------|----------|\n"
}

local rows = {}
local total_line = ""
for line in io.lines("luacov.report.out") do
local file, hits, missed, coverage = line:match("^([%w%p]+)%s+(%d+)%s+(%d+)%s+([%d%.]+)%%")
if file then
local row = string.format("| %s | %s | %s | %s%% |\n", file, hits, missed, coverage)
if file == "Total" then
total_line = row
else
table.insert(rows, row)
end
end
end

table.sort(rows)
for _, row in ipairs(rows) do
table.insert(output, row)
end
table.insert(output, total_line)
io.open(os.getenv("GITHUB_STEP_SUMMARY"), "w"):write(table.concat(output))
EOF
chmod +x coverage-table.lua
- name: Create coverage summary
env:
LUA_VERSION: ${{ matrix.lua-version }}
run: lua coverage-table.lua
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
artifacts/*
13 changes: 5 additions & 8 deletions smiti18n/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ local interpolate = require(currentFilePath .. '.interpolate')
local variants = require(currentFilePath .. '.variants')
local version = require(currentFilePath .. '.version')

i18n.plural, i18n.interpolate, i18n.variants, i18n.version, i18n._VERSION =
plural, interpolate, variants, version, version
i18n.plural = plural
i18n.interpolate = interpolate
i18n.variants = variants
i18n.version = version
i18n._VERSION = version

-- private stuff

Expand Down Expand Up @@ -75,12 +78,6 @@ local function assertFunctionOrNil(functionName, paramName, value)
end

local function defaultPluralizeFunction(loc, count)
if not loc then
loc = i18n.getLocale()
if type(loc) == "table" then
loc = loc[1]
end
end
return plural.get(variants.root(loc), count)
end

Expand Down
8 changes: 1 addition & 7 deletions smiti18n/interpolate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,7 @@ local function escapePercentages(string)
end

local function unescapePercentages(string)
return string:gsub("(%%%%)(.?)", function(_, char)
if FORMAT_CHARS[char] then
return "%" .. char
else
return "%%" .. char
end
end)
return string:gsub("(%%%%)(.?)", "%%")
end

local function interpolateString(pattern, variables)
Expand Down
120 changes: 120 additions & 0 deletions spec/i18n_interpolate_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,124 @@ describe('smiti18n.interpolate', function()
})
)
end)

-- Add new tests here, before the final end)
describe('Multiple format specifiers', function()
it("handles multiple numeric formats in one string", function()
assert.equal(
"Int: 42, Float: 3.14, Exp: 1.23e+06",
interpolate(
"Int: %s, Float: %s, Exp: %s",
{"42", "3.14", "1.23e+06"}))
end)

it("handles repeated format specifiers", function()
assert.equal(
"Value is 42 and also 42",
interpolate("Value is %s and also %s", {"42", "42"}))
end)

it("handles escaped format chars correctly", function()
assert.equal(
"Format: %d",
interpolate("Format: %%d")
)
end)
end)

describe('Edge cases', function()
it("handles simple variable references", function()
assert.equal(
"Value: test",
interpolate("Value: %{val}", {val = "test"}))
end)

it("handles invalid format specifiers gracefully", function()
assert.error(function()
interpolate("%d", {"not a number"})
end)
end)

it("ignores escaped format specifiers", function()
assert.equal(
"Raw %<num>.d here",
interpolate("Raw %%<num>.d here", {num = 42}))
end)

it("handles escaped format characters", function()
assert.equal("100%", interpolate("100%%"))
assert.equal("50% complete", interpolate("50%% complete"))
end)

it("handles format specifiers", function()
assert.equal("Test %s", interpolate("Test %%s"))
assert.equal("Value %d", interpolate("Value %%d"))
end)
end)

describe('unescapePercentages', function()
it('handles escaped format chars correctly', function()
local result = interpolate("Format: %%d")
assert.equal("Format: %d", result)
end)

it('handles single values with escapes', function()
local result = interpolate("Number: %%d %d", {42})
assert.equal("Number: %d 42", result)
end)

it('handles multiple escapes', function()
-- Test double %% (escapes to single %)
local result = interpolate("Test: %%d%%d", {})
assert.equal("Test: %d%d", result)

-- Test triple %%% with value
result = interpolate("Value: %%%d", {123})
assert.equal("Value: %123", result)
end)

it('handles special format characters differently', function()
-- Test format character that exists in FORMAT_CHARS table (like s,d,f)
local result = interpolate("Test: %%s %%d %%f", {})
assert.equal("Test: %s %d %f", result)

-- Test non-format character (z is not in FORMAT_CHARS)
result = interpolate("Test: %%z", {})
assert.equal("Test: %z", result) -- Updated expectation - all %% are converted to %
end)

it('exercises all format character paths', function()
-- Test format character (d) with proper value
local result = interpolate("Test: %%%d %%d", {42})
assert.equal("Test: %42 %d", result)

-- Test non-format character with escaped %
result = interpolate("Test: %%k", {})
assert.equal("Test: %k", result)

-- Mix both in single test to ensure branches are hit
result = interpolate("Mix: %%%d %%x", {99})
assert.equal("Mix: %99 %x", result)
end)
end)

describe('getInterpolationKey', function()
it("finds first valid interpolation key", function()
assert.equal(
"name",
interpolate.getInterpolationKey("Text %{name}", {name = "test"}))
end)

it("returns nil when no valid keys found", function()
assert.is_nil(
interpolate.getInterpolationKey("No vars here")
)
end)

it("handles format specifiers", function()
assert.equal(
"num",
interpolate.getInterpolationKey("Format %<num>.d here", {num = 42}))
end)
end)
end)
Loading
Loading