Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F625355
config_spec.lua
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
12 KB
Referenced Files
None
Subscribers
None
config_spec.lua
View Options
--[[
Tests for src/core/config.lua
Config module: loading .env, get/set values, typed access (number, boolean, list).
]]
describe
(
'core.config'
,
function
()
local
config
local
tmpfile
-- Write a temporary .env file for testing
local
function
write_env
(
content
)
tmpfile
=
os.tmpname
()
local
f
=
io.open
(
tmpfile
,
'w'
)
f
:
write
(
content
)
f
:
close
()
return
tmpfile
end
before_each
(
function
()
-- Clear the cached module so each test gets a fresh config
package.loaded
[
'src.core.config'
]
=
nil
config
=
require
(
'src.core.config'
)
end
)
after_each
(
function
()
if
tmpfile
then
os.remove
(
tmpfile
)
tmpfile
=
nil
end
end
)
describe
(
'load()'
,
function
()
it
(
'should load a valid .env file'
,
function
()
local
path
=
write_env
(
'FOO=bar
\n
BAZ=qux
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'bar'
,
config
.
get
(
'FOO'
))
assert
.
are
.
equal
(
'qux'
,
config
.
get
(
'BAZ'
))
end
)
it
(
'should not error on missing .env file'
,
function
()
assert
.
has_no
.
errors
(
function
()
config
.
load
(
'/tmp/nonexistent_env_file_'
..
os.time
())
end
)
end
)
it
(
'should ignore empty lines'
,
function
()
local
path
=
write_env
(
'FOO=bar
\n\n\n
BAZ=qux
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'bar'
,
config
.
get
(
'FOO'
))
assert
.
are
.
equal
(
'qux'
,
config
.
get
(
'BAZ'
))
end
)
it
(
'should ignore comment lines'
,
function
()
local
path
=
write_env
(
'# This is a comment
\n
FOO=bar
\n
# Another comment
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'bar'
,
config
.
get
(
'FOO'
))
end
)
it
(
'should strip surrounding double quotes from values'
,
function
()
local
path
=
write_env
(
'FOO="hello world"
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'hello world'
,
config
.
get
(
'FOO'
))
end
)
it
(
'should strip surrounding single quotes from values'
,
function
()
local
path
=
write_env
(
"FOO='hello world'
\n
"
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'hello world'
,
config
.
get
(
'FOO'
))
end
)
it
(
'should strip inline comments from unquoted values'
,
function
()
local
path
=
write_env
(
'FOO=bar # this is a comment
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'bar'
,
config
.
get
(
'FOO'
))
end
)
it
(
'should handle values with equals signs'
,
function
()
local
path
=
write_env
(
'FOO=bar=baz
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'bar=baz'
,
config
.
get
(
'FOO'
))
end
)
it
(
'should trim whitespace around keys and values'
,
function
()
local
path
=
write_env
(
' FOO = bar
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'bar'
,
config
.
get
(
'FOO'
))
end
)
end
)
describe
(
'get()'
,
function
()
it
(
'should return the value for a known key'
,
function
()
local
path
=
write_env
(
'MY_KEY=my_value
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'my_value'
,
config
.
get
(
'MY_KEY'
))
end
)
it
(
'should return default when key is missing'
,
function
()
local
path
=
write_env
(
'OTHER_KEY=other
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'fallback'
,
config
.
get
(
'NONEXISTENT'
,
'fallback'
))
end
)
it
(
'should return nil when key is missing and no default'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
assert
.
is_nil
(
config
.
get
(
'NONEXISTENT'
))
end
)
it
(
'should fall back to os.getenv for empty .env values'
,
function
()
local
path
=
write_env
(
'EMPTY_KEY=
\n
'
)
config
.
load
(
path
)
-- This will either return nil or whatever the OS env has
local
result
=
config
.
get
(
'EMPTY_KEY'
,
'default_val'
)
assert
.
is_not_nil
(
result
)
end
)
it
(
'should auto-load .env if not explicitly loaded'
,
function
()
-- Just calling get() without load() should not error
assert
.
has_no
.
errors
(
function
()
config
.
get
(
'ANYTHING'
)
end
)
end
)
end
)
describe
(
'get_number()'
,
function
()
it
(
'should return a number for numeric values'
,
function
()
local
path
=
write_env
(
'PORT=8080
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
8080
,
config
.
get_number
(
'PORT'
))
end
)
it
(
'should return default for non-numeric values'
,
function
()
local
path
=
write_env
(
'PORT=abc
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
3000
,
config
.
get_number
(
'PORT'
,
3000
))
end
)
it
(
'should return default when key is missing'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
assert
.
are
.
equal
(
5432
,
config
.
get_number
(
'DB_PORT'
,
5432
))
end
)
it
(
'should return nil when key is missing and no default'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
assert
.
is_nil
(
config
.
get_number
(
'MISSING'
))
end
)
it
(
'should handle float values'
,
function
()
local
path
=
write_env
(
'RATE=1.5
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
1.5
,
config
.
get_number
(
'RATE'
))
end
)
it
(
'should handle negative numbers'
,
function
()
local
path
=
write_env
(
'OFFSET=-10
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
-
10
,
config
.
get_number
(
'OFFSET'
))
end
)
end
)
describe
(
'is_enabled()'
,
function
()
it
(
'should return true for "true"'
,
function
()
local
path
=
write_env
(
'FLAG=true
\n
'
)
config
.
load
(
path
)
assert
.
is_true
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return true for "1"'
,
function
()
local
path
=
write_env
(
'FLAG=1
\n
'
)
config
.
load
(
path
)
assert
.
is_true
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return true for "yes"'
,
function
()
local
path
=
write_env
(
'FLAG=yes
\n
'
)
config
.
load
(
path
)
assert
.
is_true
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return true case-insensitively for "TRUE"'
,
function
()
local
path
=
write_env
(
'FLAG=TRUE
\n
'
)
config
.
load
(
path
)
assert
.
is_true
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return true case-insensitively for "Yes"'
,
function
()
local
path
=
write_env
(
'FLAG=Yes
\n
'
)
config
.
load
(
path
)
assert
.
is_true
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return false for "false"'
,
function
()
local
path
=
write_env
(
'FLAG=false
\n
'
)
config
.
load
(
path
)
assert
.
is_false
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return false for "0"'
,
function
()
local
path
=
write_env
(
'FLAG=0
\n
'
)
config
.
load
(
path
)
assert
.
is_false
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return false for "no"'
,
function
()
local
path
=
write_env
(
'FLAG=no
\n
'
)
config
.
load
(
path
)
assert
.
is_false
(
config
.
is_enabled
(
'FLAG'
))
end
)
it
(
'should return false for missing key'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
assert
.
is_false
(
config
.
is_enabled
(
'MISSING'
))
end
)
it
(
'should return false for arbitrary string'
,
function
()
local
path
=
write_env
(
'FLAG=maybe
\n
'
)
config
.
load
(
path
)
assert
.
is_false
(
config
.
is_enabled
(
'FLAG'
))
end
)
end
)
describe
(
'get_list()'
,
function
()
it
(
'should split comma-separated values into a table'
,
function
()
local
path
=
write_env
(
'ITEMS=a,b,c
\n
'
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'ITEMS'
)
assert
.
are
.
equal
(
3
,
#
list
)
assert
.
are
.
equal
(
'a'
,
list
[
1
])
assert
.
are
.
equal
(
'b'
,
list
[
2
])
assert
.
are
.
equal
(
'c'
,
list
[
3
])
end
)
it
(
'should trim whitespace around items'
,
function
()
local
path
=
write_env
(
'ITEMS= a , b , c
\n
'
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'ITEMS'
)
assert
.
are
.
equal
(
3
,
#
list
)
assert
.
are
.
equal
(
'a'
,
list
[
1
])
assert
.
are
.
equal
(
'b'
,
list
[
2
])
assert
.
are
.
equal
(
'c'
,
list
[
3
])
end
)
it
(
'should convert numeric items to numbers'
,
function
()
local
path
=
write_env
(
'IDS=100,200,300
\n
'
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'IDS'
)
assert
.
are
.
equal
(
3
,
#
list
)
assert
.
are
.
equal
(
100
,
list
[
1
])
assert
.
are
.
equal
(
200
,
list
[
2
])
assert
.
are
.
equal
(
300
,
list
[
3
])
end
)
it
(
'should return empty table for missing key'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'MISSING'
)
assert
.
are
.
same
({},
list
)
end
)
it
(
'should return empty table for empty value'
,
function
()
local
path
=
write_env
(
'ITEMS=
\n
'
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'ITEMS'
)
assert
.
are
.
same
({},
list
)
end
)
it
(
'should handle single-item list'
,
function
()
local
path
=
write_env
(
'ITEMS=only
\n
'
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'ITEMS'
)
assert
.
are
.
equal
(
1
,
#
list
)
assert
.
are
.
equal
(
'only'
,
list
[
1
])
end
)
it
(
'should handle mixed numeric and string items'
,
function
()
local
path
=
write_env
(
'ITEMS=100,hello,300
\n
'
)
config
.
load
(
path
)
local
list
=
config
.
get_list
(
'ITEMS'
)
assert
.
are
.
equal
(
100
,
list
[
1
])
assert
.
are
.
equal
(
'hello'
,
list
[
2
])
assert
.
are
.
equal
(
300
,
list
[
3
])
end
)
end
)
describe
(
'convenience accessors'
,
function
()
it
(
'should return bot_token'
,
function
()
local
path
=
write_env
(
'BOT_TOKEN=12345:ABCDEF
\n
'
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'12345:ABCDEF'
,
config
.
bot_token
())
end
)
it
(
'should return bot_admins as a list'
,
function
()
local
path
=
write_env
(
'BOT_ADMINS=221714512,123456
\n
'
)
config
.
load
(
path
)
local
admins
=
config
.
bot_admins
()
assert
.
are
.
equal
(
2
,
#
admins
)
assert
.
are
.
equal
(
221714512
,
admins
[
1
])
end
)
it
(
'should return bot_name with default'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
assert
.
are
.
equal
(
'mattata'
,
config
.
bot_name
())
end
)
it
(
'should return database config with defaults'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
local
db
=
config
.
database
()
assert
.
are
.
equal
(
'postgres'
,
db
.
host
)
assert
.
are
.
equal
(
5432
,
db
.
port
)
assert
.
are
.
equal
(
'mattata'
,
db
.
database
)
end
)
it
(
'should return redis config with defaults'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
local
rc
=
config
.
redis_config
()
assert
.
are
.
equal
(
'redis'
,
rc
.
host
)
assert
.
are
.
equal
(
6379
,
rc
.
port
)
assert
.
are
.
equal
(
0
,
rc
.
db
)
end
)
it
(
'should return polling config with defaults'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
local
p
=
config
.
polling
()
assert
.
are
.
equal
(
60
,
p
.
timeout
)
assert
.
are
.
equal
(
100
,
p
.
limit
)
end
)
it
(
'should return webhook config'
,
function
()
local
path
=
write_env
(
'WEBHOOK_ENABLED=true
\n
WEBHOOK_URL=https://example.com
\n
WEBHOOK_PORT=8443
\n
'
)
config
.
load
(
path
)
local
wh
=
config
.
webhook
()
assert
.
is_true
(
wh
.
enabled
)
assert
.
are
.
equal
(
'https://example.com'
,
wh
.
url
)
assert
.
are
.
equal
(
8443
,
wh
.
port
)
end
)
it
(
'should return debug status'
,
function
()
local
path
=
write_env
(
'DEBUG=true
\n
'
)
config
.
load
(
path
)
assert
.
is_true
(
config
.
debug
())
end
)
it
(
'should return ai config with defaults'
,
function
()
local
path
=
write_env
(
''
)
config
.
load
(
path
)
local
ai
=
config
.
ai
()
assert
.
is_false
(
ai
.
enabled
)
assert
.
are
.
equal
(
'gpt-4o'
,
ai
.
openai_model
)
end
)
end
)
describe
(
'VERSION'
,
function
()
it
(
'should be 2.1'
,
function
()
assert
.
are
.
equal
(
'2.1'
,
config
.
VERSION
)
end
)
end
)
end
)
File Metadata
Details
Attached
Mime Type
application/javascript
Expires
Sat, Nov 14, 11:22 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
130540
Default Alt Text
config_spec.lua (12 KB)
Attached To
Mode
R69 mattata
Attached
Detach File
Event Timeline