251 lines
6.0 KiB
Go
251 lines
6.0 KiB
Go
package gluaurl
|
|
|
|
import "github.com/yuin/gopher-lua"
|
|
import "testing"
|
|
import "os"
|
|
import "bytes"
|
|
import "io"
|
|
import "strings"
|
|
|
|
func TestParse(t *testing.T) {
|
|
output, err := evalScript(`
|
|
local url = require("url")
|
|
|
|
parsed = url.parse("http://bob:secret@example.com:8080/products?page=2#something")
|
|
|
|
print(parsed.scheme)
|
|
print(parsed.username)
|
|
print(parsed.password)
|
|
print(parsed.host)
|
|
print(parsed.path)
|
|
print(parsed.query)
|
|
print(parsed.fragment)
|
|
`)
|
|
|
|
if err != nil {
|
|
t.Errorf("Failed to evaluate script: %s", err)
|
|
} else {
|
|
if expected := `http
|
|
bob
|
|
secret
|
|
example.com:8080
|
|
/products
|
|
page=2
|
|
something
|
|
`; expected != output {
|
|
t.Errorf("Expected output does not match actual output\nExpected: %s\nActual: %s", expected, output)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseOnlyHost(t *testing.T) {
|
|
output, err := evalScript(`
|
|
local url = require("url")
|
|
|
|
parsed = url.parse("https://example.com")
|
|
|
|
print(parsed.scheme)
|
|
print(parsed.username)
|
|
print(parsed.password)
|
|
print(parsed.host)
|
|
print(parsed.path)
|
|
print(parsed.query)
|
|
print(parsed.fragment)
|
|
`)
|
|
|
|
if err != nil {
|
|
t.Errorf("Failed to evaluate script: %s", err)
|
|
} else {
|
|
if expected := `https
|
|
nil
|
|
nil
|
|
example.com
|
|
|
|
|
|
|
|
`; expected != output {
|
|
t.Errorf("Expected output does not match actual output\nExpected: %s\nActual: %s", expected, output)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBuild(t *testing.T) {
|
|
output, err := evalScript(`
|
|
local url = require("url")
|
|
|
|
built = url.build({
|
|
scheme="https",
|
|
username="bob",
|
|
password="secret",
|
|
host="example.com:8080",
|
|
path="/products",
|
|
query="page=2",
|
|
fragment="something"
|
|
})
|
|
|
|
print(built)
|
|
`)
|
|
|
|
if err != nil {
|
|
t.Errorf("Failed to evaluate script: %s", err)
|
|
} else {
|
|
if expected := `https://bob:secret@example.com:8080/products?page=2#something
|
|
`; expected != output {
|
|
t.Errorf("Expected output does not match actual output\nExpected: %s\nActual: %s", expected, output)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBuildEmpty(t *testing.T) {
|
|
output, err := evalScript(`
|
|
local url = require("url")
|
|
|
|
built = url.build({})
|
|
|
|
print(built)
|
|
`)
|
|
|
|
if err != nil {
|
|
t.Errorf("Failed to evaluate script: %s", err)
|
|
} else {
|
|
if expected := `
|
|
`; expected != output {
|
|
t.Errorf("Expected output does not match actual output\nExpected: %s\nActual: %s", expected, output)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBuildQueryString(t *testing.T) {
|
|
output, err := evalScript(`
|
|
local url = require("url")
|
|
|
|
function assert_query_string(options, expected, message)
|
|
actual = url.build_query_string(options)
|
|
|
|
if expected ~= actual then
|
|
print("Failed to build '" .. message .. "'")
|
|
print("Expected:")
|
|
print(expected)
|
|
print("Actual:")
|
|
print(actual)
|
|
end
|
|
end
|
|
|
|
assert_query_string(
|
|
{foo="bar", baz=42, quux="All your base are belong to us"},
|
|
"baz=42&foo=bar&quux=All+your+base+are+belong+to+us",
|
|
"simple"
|
|
)
|
|
|
|
assert_query_string(
|
|
{someName={1, 2, 3}, regularThing="blah"},
|
|
"regularThing=blah&someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3",
|
|
"with array"
|
|
)
|
|
|
|
assert_query_string(
|
|
{foo={"a", "b", "c"}},
|
|
"foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c",
|
|
"with array of strings"
|
|
)
|
|
|
|
assert_query_string(
|
|
{foo={"baz", 42, "All your base are belong to us"}},
|
|
"foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All+your+base+are+belong+to+us",
|
|
"more array"
|
|
)
|
|
|
|
assert_query_string(
|
|
{foo={bar="baz", beep=42, quux="All your base are belong to us"}},
|
|
"foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us",
|
|
"even more arrays"
|
|
)
|
|
|
|
assert_query_string(
|
|
{a={1,2}, b={c=3, d={4,5}, e={ x={6}, y=7, z={8,9} }, f=true, g=false, h=""}, i={10,11}, j=true, k=false, l={"",0}, m="cowboy hat?" },
|
|
"a%5B%5D=1&a%5B%5D=2&b%5Bc%5D=3&b%5Bd%5D%5B%5D=4&b%5Bd%5D%5B%5D=5&b%5Be%5D%5Bx%5D%5B%5D=6&b%5Be%5D%5By%5D=7&b%5Be%5D%5Bz%5D%5B%5D=8&b%5Be%5D%5Bz%5D%5B%5D=9&b%5Bf%5D=true&b%5Bg%5D=false&b%5Bh%5D=&i%5B%5D=10&i%5B%5D=11&j=true&k=false&l%5B%5D=&l%5B%5D=0&m=cowboy+hat%3F",
|
|
"huge structure"
|
|
)
|
|
|
|
assert_query_string(
|
|
{ a={0, { 1, 2 }, { 3, { 4, 5 }, { 6 } }, { b= { 7, { 8, 9 }, { { c=10, d=11 } }, { { 12 } }, { { { 13 } } }, { e= { f= { g={ 14, { 15 } } } } }, 16 } }, 17 } },
|
|
"a%5B%5D=0&a%5B1%5D%5B%5D=1&a%5B1%5D%5B%5D=2&a%5B2%5D%5B%5D=3&a%5B2%5D%5B1%5D%5B%5D=4&a%5B2%5D%5B1%5D%5B%5D=5&a%5B2%5D%5B2%5D%5B%5D=6&a%5B3%5D%5Bb%5D%5B%5D=7&a%5B3%5D%5Bb%5D%5B1%5D%5B%5D=8&a%5B3%5D%5Bb%5D%5B1%5D%5B%5D=9&a%5B3%5D%5Bb%5D%5B2%5D%5B0%5D%5Bc%5D=10&a%5B3%5D%5Bb%5D%5B2%5D%5B0%5D%5Bd%5D=11&a%5B3%5D%5Bb%5D%5B3%5D%5B0%5D%5B%5D=12&a%5B3%5D%5Bb%5D%5B4%5D%5B0%5D%5B0%5D%5B%5D=13&a%5B3%5D%5Bb%5D%5B5%5D%5Be%5D%5Bf%5D%5Bg%5D%5B%5D=14&a%5B3%5D%5Bb%5D%5B5%5D%5Be%5D%5Bf%5D%5Bg%5D%5B1%5D%5B%5D=15&a%5B3%5D%5Bb%5D%5B%5D=16&a%5B%5D=17",
|
|
"nested arrays"
|
|
)
|
|
|
|
assert_query_string(
|
|
{ a= {1,2,3}, ["b[]"]= {4,5,6}, ["c[d]"]= {7,8,9}, e= { f= {10}, g= {11,12}, h= 13 } },
|
|
"a%5B%5D=1&a%5B%5D=2&a%5B%5D=3&b%5B%5D=4&b%5B%5D=5&b%5B%5D=6&c%5Bd%5D%5B%5D=7&c%5Bd%5D%5B%5D=8&c%5Bd%5D%5B%5D=9&e%5Bf%5D%5B%5D=10&e%5Bg%5D%5B%5D=11&e%5Bg%5D%5B%5D=12&e%5Bh%5D=13",
|
|
"make sure params are not double-encoded"
|
|
)
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
t.Errorf("Failed to evaluate script: %s", err)
|
|
} else {
|
|
if expected := ``; expected != output {
|
|
t.Error(output)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResolve(t *testing.T) {
|
|
output, err := evalScript(`
|
|
local url = require("url")
|
|
|
|
print(url.resolve('/one/two/three', 'four'))
|
|
print(url.resolve('http://example.com/', '/one'))
|
|
print(url.resolve('http://example.com/one', '/two'))
|
|
print(url.resolve('https://example.com/one', '//example2.com'))
|
|
`)
|
|
|
|
if err != nil {
|
|
t.Errorf("Failed to evaluate script: %s", err)
|
|
} else {
|
|
if expected := `/one/two/four
|
|
http://example.com/one
|
|
http://example.com/two
|
|
https://example2.com
|
|
`; expected != output {
|
|
t.Errorf("Expected output does not match actual output\nExpected: %s\nActual: %s", expected, output)
|
|
}
|
|
}
|
|
}
|
|
|
|
func evalScript(script string) (string, error) {
|
|
L := lua.NewState()
|
|
defer L.Close()
|
|
|
|
L.PreloadModule("url", Loader)
|
|
|
|
var err error
|
|
|
|
out := captureStdout(func() {
|
|
err = L.DoString(script)
|
|
})
|
|
|
|
return out, err
|
|
}
|
|
|
|
func captureStdout(inner func()) string {
|
|
oldStdout := os.Stdout
|
|
r, w, _ := os.Pipe()
|
|
os.Stdout = w
|
|
|
|
outC := make(chan string)
|
|
go func() {
|
|
var buf bytes.Buffer
|
|
io.Copy(&buf, r)
|
|
outC <- buf.String()
|
|
}()
|
|
|
|
inner()
|
|
|
|
w.Close()
|
|
os.Stdout = oldStdout
|
|
out := strings.Replace(<-outC, "\r", "", -1)
|
|
|
|
return out
|
|
}
|