mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
Fix flaky tests and make sure empty bodies are always None
This commit is contained in:
parent
9f6a1532a6
commit
05a47bd9dc
11 changed files with 32 additions and 77 deletions
|
@ -1,4 +1,4 @@
|
||||||
use http_body_util::BodyExt;
|
use http_body_util::{BodyExt, Full};
|
||||||
use hyper::{
|
use hyper::{
|
||||||
body::{Bytes, Incoming},
|
body::{Bytes, Incoming},
|
||||||
header::CONTENT_ENCODING,
|
header::CONTENT_ENCODING,
|
||||||
|
@ -33,3 +33,11 @@ pub async fn handle_incoming_body(
|
||||||
|
|
||||||
Ok((body, was_decompressed))
|
Ok((body, was_decompressed))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bytes_to_full(bytes: Bytes) -> Full<Bytes> {
|
||||||
|
if bytes.is_empty() {
|
||||||
|
Full::default()
|
||||||
|
} else {
|
||||||
|
Full::new(bytes)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
|
pub mod body;
|
||||||
pub mod futures;
|
pub mod futures;
|
||||||
pub mod headers;
|
pub mod headers;
|
||||||
pub mod hyper;
|
pub mod hyper;
|
||||||
pub mod incoming;
|
|
||||||
pub mod lua;
|
pub mod lua;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
|
|
@ -11,8 +11,8 @@ use hyper::{
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::shared::{
|
use crate::shared::{
|
||||||
|
body::{bytes_to_full, handle_incoming_body},
|
||||||
headers::{hash_map_to_table, header_map_to_table},
|
headers::{hash_map_to_table, header_map_to_table},
|
||||||
incoming::handle_incoming_body,
|
|
||||||
lua::{lua_table_to_header_map, lua_value_to_bytes, lua_value_to_method},
|
lua::{lua_table_to_header_map, lua_value_to_bytes, lua_value_to_method},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ impl Request {
|
||||||
.expect("request was valid")
|
.expect("request was valid")
|
||||||
.extend(self.inner.headers().clone());
|
.extend(self.inner.headers().clone());
|
||||||
|
|
||||||
let body = Full::new(self.inner.body().clone());
|
let body = bytes_to_full(self.inner.body().clone());
|
||||||
builder.body(body).expect("request was valid")
|
builder.body(body).expect("request was valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ impl Request {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn into_full(self) -> HyperRequest<Full<Bytes>> {
|
pub fn into_full(self) -> HyperRequest<Full<Bytes>> {
|
||||||
let (parts, body) = self.inner.into_parts();
|
let (parts, body) = self.inner.into_parts();
|
||||||
HyperRequest::from_parts(parts, Full::new(body))
|
HyperRequest::from_parts(parts, bytes_to_full(body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ use hyper::{
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::shared::{
|
use crate::shared::{
|
||||||
|
body::{bytes_to_full, handle_incoming_body},
|
||||||
headers::header_map_to_table,
|
headers::header_map_to_table,
|
||||||
incoming::handle_incoming_body,
|
|
||||||
lua::{lua_table_to_header_map, lua_value_to_bytes},
|
lua::{lua_table_to_header_map, lua_value_to_bytes},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ impl Response {
|
||||||
.expect("request was valid")
|
.expect("request was valid")
|
||||||
.extend(self.inner.headers().clone());
|
.extend(self.inner.headers().clone());
|
||||||
|
|
||||||
let body = Full::new(self.inner.body().clone());
|
let body = bytes_to_full(self.inner.body().clone());
|
||||||
builder.body(body).expect("request was valid")
|
builder.body(body).expect("request was valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ impl Response {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn into_full(self) -> HyperResponse<Full<Bytes>> {
|
pub fn into_full(self) -> HyperResponse<Full<Bytes>> {
|
||||||
let (parts, body) = self.inner.into_parts();
|
let (parts, body) = self.inner.into_parts();
|
||||||
HyperResponse::from_parts(parts, Full::new(body))
|
HyperResponse::from_parts(parts, bytes_to_full(body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
local net = require("@lune/net")
|
local net = require("@lune/net")
|
||||||
local task = require("@lune/task")
|
local task = require("@lune/task")
|
||||||
|
|
||||||
local PORT = 8083
|
local PORT = 8082
|
||||||
local URL = `http://127.0.0.1:{PORT}`
|
local URL = `http://127.0.0.1:{PORT}`
|
||||||
local RESPONSE = "Hello, lune!"
|
local RESPONSE = "Hello, lune!"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ local process = require("@lune/process")
|
||||||
local stdio = require("@lune/stdio")
|
local stdio = require("@lune/stdio")
|
||||||
local task = require("@lune/task")
|
local task = require("@lune/task")
|
||||||
|
|
||||||
local PORT = 8082
|
local PORT = 8083
|
||||||
local RESPONSE = "Hello, lune!"
|
local RESPONSE = "Hello, lune!"
|
||||||
|
|
||||||
-- Serve should not yield the entire main thread forever, only
|
-- Serve should not yield the entire main thread forever, only
|
||||||
|
|
|
@ -3,7 +3,7 @@ local process = require("@lune/process")
|
||||||
local stdio = require("@lune/stdio")
|
local stdio = require("@lune/stdio")
|
||||||
local task = require("@lune/task")
|
local task = require("@lune/task")
|
||||||
|
|
||||||
local PORT = 8083
|
local PORT = 8084
|
||||||
local URL = `http://127.0.0.1:{PORT}`
|
local URL = `http://127.0.0.1:{PORT}`
|
||||||
local RESPONSE = "Hello, lune!"
|
local RESPONSE = "Hello, lune!"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ local process = require("@lune/process")
|
||||||
local stdio = require("@lune/stdio")
|
local stdio = require("@lune/stdio")
|
||||||
local task = require("@lune/task")
|
local task = require("@lune/task")
|
||||||
|
|
||||||
local PORT = 8081
|
local PORT = 8085
|
||||||
local WS_URL = `ws://127.0.0.1:{PORT}`
|
local WS_URL = `ws://127.0.0.1:{PORT}`
|
||||||
local REQUEST = "Hello from client!"
|
local REQUEST = "Hello from client!"
|
||||||
local RESPONSE = "Hello, lune!"
|
local RESPONSE = "Hello, lune!"
|
||||||
|
|
|
@ -16,14 +16,11 @@ end)
|
||||||
|
|
||||||
-- Reference: https://create.roblox.com/docs/reference/engine/classes/HttpService#GetAsync
|
-- Reference: https://create.roblox.com/docs/reference/engine/classes/HttpService#GetAsync
|
||||||
|
|
||||||
local URL_ASTROS = "http://api.open-notify.org/astros.json"
|
|
||||||
|
|
||||||
local game = roblox.Instance.new("DataModel")
|
local game = roblox.Instance.new("DataModel")
|
||||||
local HttpService = game:GetService("HttpService") :: any
|
local HttpService = game:GetService("HttpService") :: any
|
||||||
|
|
||||||
local response = HttpService:GetAsync(URL_ASTROS)
|
local response = HttpService:GetAsync("https://httpbingo.org/json")
|
||||||
local data = HttpService:JSONDecode(response)
|
local data = HttpService:JSONDecode(response)
|
||||||
|
|
||||||
assert(type(data) == "table", "Returned JSON data should decode to a table")
|
assert(type(data) == "table", "Returned JSON data should decode to a table")
|
||||||
assert(data.message == "success", "Returned JSON data should have a 'message' with value 'success'")
|
assert(type(data.slideshow) == "table", "Returned JSON data should contain 'slideshow'")
|
||||||
assert(type(data.people) == "table", "Returned JSON data should have a 'people' table")
|
|
||||||
|
|
|
@ -1,53 +1,13 @@
|
||||||
local net = require("@lune/net")
|
|
||||||
local serde = require("@lune/serde")
|
local serde = require("@lune/serde")
|
||||||
|
local source = require("./source")
|
||||||
|
|
||||||
type Response = {
|
local decoded = serde.decode("json", source.pretty)
|
||||||
products: {
|
|
||||||
{
|
|
||||||
id: number,
|
|
||||||
title: string,
|
|
||||||
description: string,
|
|
||||||
price: number,
|
|
||||||
discountPercentage: number,
|
|
||||||
rating: number,
|
|
||||||
stock: number,
|
|
||||||
brand: string,
|
|
||||||
category: string,
|
|
||||||
thumbnail: string,
|
|
||||||
images: { string },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
total: number,
|
|
||||||
skip: number,
|
|
||||||
limit: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
local response = net.request("https://dummyjson.com/products")
|
assert(type(decoded) == "table", "Decoded payload was not a table")
|
||||||
|
assert(decoded.Hello == "World", "Decoded payload Hello was not World")
|
||||||
assert(response.ok, "Dummy JSON api returned an error")
|
assert(type(decoded.Inner) == "table", "Decoded payload Inner was not a table")
|
||||||
assert(#response.body > 0, "Dummy JSON api returned empty body")
|
assert(type(decoded.Inner.Array) == "table", "Decoded payload Inner.Array was not a table")
|
||||||
|
assert(type(decoded.Inner.Array[1]) == "number", "Decoded payload Inner.Array[1] was not a number")
|
||||||
local data: Response = serde.decode("json", response.body)
|
assert(type(decoded.Inner.Array[2]) == "number", "Decoded payload Inner.Array[2] was not a number")
|
||||||
|
assert(type(decoded.Inner.Array[3]) == "number", "Decoded payload Inner.Array[3] was not a number")
|
||||||
assert(type(data.limit) == "number", "Products limit was not a number")
|
assert(decoded.Foo == "Bar", "Decoded payload Foo was not Bar")
|
||||||
assert(type(data.products) == "table", "Products was not a table")
|
|
||||||
assert(#data.products > 0, "Products table was empty")
|
|
||||||
|
|
||||||
local productCount = 0
|
|
||||||
for _, product in data.products do
|
|
||||||
productCount += 1
|
|
||||||
assert(type(product.id) == "number", "Product id was not a number")
|
|
||||||
assert(type(product.title) == "string", "Product title was not a number")
|
|
||||||
assert(type(product.description) == "string", "Product description was not a number")
|
|
||||||
assert(type(product.images) == "table", "Product images was not a table")
|
|
||||||
assert(#product.images > 0, "Product images table was empty")
|
|
||||||
end
|
|
||||||
|
|
||||||
assert(
|
|
||||||
data.limit == productCount,
|
|
||||||
string.format(
|
|
||||||
"Products limit and number of products in array mismatch (expected %d, got %d)",
|
|
||||||
data.limit,
|
|
||||||
productCount
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
|
@ -2,16 +2,6 @@ local serde = require("@lune/serde")
|
||||||
local source = require("./source")
|
local source = require("./source")
|
||||||
|
|
||||||
local decoded = serde.decode("json", source.pretty)
|
local decoded = serde.decode("json", source.pretty)
|
||||||
|
|
||||||
assert(type(decoded) == "table", "Decoded payload was not a table")
|
|
||||||
assert(decoded.Hello == "World", "Decoded payload Hello was not World")
|
|
||||||
assert(type(decoded.Inner) == "table", "Decoded payload Inner was not a table")
|
|
||||||
assert(type(decoded.Inner.Array) == "table", "Decoded payload Inner.Array was not a table")
|
|
||||||
assert(type(decoded.Inner.Array[1]) == "number", "Decoded payload Inner.Array[1] was not a number")
|
|
||||||
assert(type(decoded.Inner.Array[2]) == "number", "Decoded payload Inner.Array[2] was not a number")
|
|
||||||
assert(type(decoded.Inner.Array[3]) == "number", "Decoded payload Inner.Array[3] was not a number")
|
|
||||||
assert(decoded.Foo == "Bar", "Decoded payload Foo was not Bar")
|
|
||||||
|
|
||||||
local encoded = serde.encode("json", decoded, false)
|
local encoded = serde.encode("json", decoded, false)
|
||||||
assert(encoded == source.encoded, "JSON round-trip did not produce the same result")
|
assert(encoded == source.encoded, "JSON round-trip did not produce the same result")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue