Skip to content
Permalink
Browse files

feat(rust): unit tests generation w/ random input/output

  • Loading branch information...
mersinvald committed Apr 1, 2019
1 parent d4ae44b commit e15baedccf1c679427a7d376e9b815f0fc606654
@@ -2,6 +2,7 @@
**/build
**/coverage
**/docs
**/.idea
coverage
docs
.DS_Store
@@ -3,6 +3,7 @@ import {
TGetMethodTypingsMap,
TGetFunctionSignature,
IContentDescriptorTyping,
IMethodTypingsMap,
} from "./generator-interface";
import _ from "lodash";
import { types } from "@open-rpc/meta-schema";
@@ -34,7 +35,8 @@ const getMethodTypingsMap: TGetMethodTypingsMap = async (openrpcSchema) => {
..._.map(methods, "result"),
] as types.ContentDescriptorObject[];

const deriveString = "#[derive(Serialize, Deserialize)]";
const deriveString = "#[derive(Debug, Clone, Serialize, Deserialize)]";
const cfgDeriveString = "#[cfg_attr(test, derive(Random))]";
const untaggedString = "#[serde(untagged)]";
const typeLinesNested = await Promise.all(
_.map(
@@ -52,6 +54,7 @@ const getMethodTypingsMap: TGetMethodTypingsMap = async (openrpcSchema) => {

if (interfaceMatch) {
const toAdd = [deriveString];
toAdd.push(cfgDeriveString);

if (interfaceMatch[1] === "enum") {
toAdd.push(untaggedString);
@@ -71,7 +74,7 @@ const getMethodTypingsMap: TGetMethodTypingsMap = async (openrpcSchema) => {

return memoLines;
}, [] as any)
.filter((line) => line !== untaggedString && line !== deriveString)
.filter((line) => line !== untaggedString && line !== deriveString && line !== cfgDeriveString)
.compact()
.value(),
),
@@ -130,10 +133,13 @@ const getMethodTypingsMap: TGetMethodTypingsMap = async (openrpcSchema) => {
.value();

typings[Object.keys(typings)[0]].typing += allTypings;

//console.log(JSON.stringify(typings, undefined, " "))
//throw new Error();
return typings;
};



const getFunctionSignature: TGetFunctionSignature = (method, typeDefs) => {
const mResult = method.result as types.ContentDescriptorObject;
const result = `RpcRequest<${typeDefs[generateMethodResultId(method, mResult)].typeName}>`;
@@ -20,12 +20,13 @@ describe(`Examples to generate Js clients`, () => {
return await rmdir(testDir);
});

afterAll(async () => {
await fsx.emptyDir(testDir);
return await rmdir(testDir);
});
// afterAll(async () => {
// await fsx.emptyDir(testDir);
// return await rmdir(testDir);
// });

forEach(examples, (example: types.OpenRPC, exampleName: string) => {
if(exampleName != "petstore") return;
it(`creates a new client for example: ${exampleName}`, async () => {
expect.assertions(1);

@@ -10,6 +10,8 @@ import { generateMethodParamId, generateMethodResultId } from "@open-rpc/schema-
import { types } from "@open-rpc/meta-schema";

import generators from "./generators";
import { IMethodTypingsMap } from "./generators/generator-interface";
import { map } from "lodash";

const cwd = process.cwd();

@@ -27,6 +29,12 @@ const compileTemplate = async (name: string, schema: types.OpenRPC, language: st
const template = language === "rust" ? rsTemplate : jsTemplate;
return template({
className: name,
getParamTypings: (method: types.MethodObject, typeDefs: IMethodTypingsMap): string[] => {
return map(
method.params as types.ContentDescriptorObject[],
(param) => `${typeDefs[generateMethodParamId(method, param)].typeName}`,
);
},
generateMethodParamId,
generateMethodResultId,
getFunctionSignature: generators[language].getFunctionSignature,
@@ -2,9 +2,14 @@
name = "template-client"
version = "1.0.0"
authors = ["Zachary Belford <belfordz66@gmail.com>"]
edition = "2018"

[dependencies]
jsonrpc-client-core = "0.5.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json = "1.0"

[dev-dependencies]
autorand = "0.1"
futures = "0.1.25"
failure = "0.1.5"
@@ -0,0 +1,3 @@
#!/bin/bash

cargo test --all
@@ -68,11 +68,13 @@ impl Transport for MockTransport {
mod tests {
use super::*;
use serde::{Serialize, Deserialize};
use autorand::Random;

pub type PetId = String;
pub type Pets = Vec<Pet>;

#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[cfg_attr(test, derive(Random))]
pub struct Pet {
#[serde(rename = "id")]
id: PetId,
@@ -89,6 +91,7 @@ mod tests {
});

#[test]
#[allow(non_snake_case)]
fn generated_test_sample() {
//- method quety template start
let method = "get_pet".into();
@@ -97,16 +100,14 @@ mod tests {
//- params query template start
let mut params= Vec::new();
//-- loop over params (name, type) pairs start
let petId_value = PetId::from("pet0"); // note: should be random, or queried from example, not manually set value
let petId_value = PetId::random(); // note: should be random, or queried from example, not manually set value
params.push(serde_json::to_value(&petId_value).unwrap());
//-- loop over params end
//- params query template end

//- result query template start
// note: should be random, or queried from example, not manually set value
let result = Pets::from(vec![
Pet { id: PetId::from("pet0"), name: String::from("Fluffy"), tag: None }
]);
let result = Pets::random();
//- result query template end

let transport = MockTransport {
@@ -3,12 +3,13 @@ import { template } from "lodash";
export default template(`
#[macro_use]
extern crate jsonrpc_client_core;
use serde::{Serialize, Deserialize};
extern crate serde;
extern crate serde_json;
#[cfg(test)]
use autorand::Random;
#[macro_use]
extern crate serde_derive;
#[cfg(test)]
mod test_harness;
<%= _.chain(typeDefs).values().uniqBy("typeName").map("typing").value().join("") %>
@@ -17,4 +18,55 @@ jsonrpc_client!(pub struct <%= className %> {
<%= getFunctionSignature(method, typeDefs) %>
<% }); %>
});
#[cfg(test)]
mod tests {
use super::*;
use test_harness::*;
use serde::{Serialize, Deserialize};
use autorand::Random;
<% methods.forEach((method) => { %>
#[test]
#[allow(non_snake_case)]
fn <%= method.name + "_test" %> () {
//- method quety template start
let method = <%= '"' + method.name + '"' %>.into();
//- method query template end
//- params query template start
let mut params = Vec::new();
//-- loop over params (name, type) pairs start
<% getParamTypings(method, typeDefs).forEach((paramType) => { %>
let <%= paramType + "_value" %> = <%= paramType + "::random()" %>;
let serialized = serde_json::to_value(&<%= paramType + "_value" %>).unwrap();
params.push(serialized);
<% }); %>
//-- loop over params end
//- params query template end
//- result query template start
<% const resultType = typeDefs[generateMethodResultId(method, method.result)].typeName; %>
let result = <%= resultType + "::random()" %>;
//- result query template end
let transport = MockTransport {
method,
params,
result: serde_json::to_value(&result).unwrap(),
};
let mut client = PetStore::new(transport);
let received_result = client.get_pet(
//- loop over params start
<% getParamTypings(method, typeDefs).forEach((paramType) => { %>
<%= paramType + "_value" %>,
<% }); %>
//- loop over params end
).wait().unwrap();
assert_eq!(result, received_result);
}
<% }); %>
}
`);

0 comments on commit e15baed

Please sign in to comment.
You can’t perform that action at this time.