Parse and test logs

This commit is contained in:
Simon Warta 2020-02-04 16:43:38 +01:00
parent 8f0509e11e
commit 7741e5711a
4 changed files with 209 additions and 0 deletions

View File

@ -0,0 +1,124 @@
/* eslint-disable @typescript-eslint/camelcase */
import { parseAttribute, parseEvent, parseLog, parseLogs } from "./logs";
describe("logs", () => {
describe("parseAttribute", () => {
it("works", () => {
const attr = parseAttribute({ key: "a", value: "b" });
expect(attr).toEqual({ key: "a", value: "b" });
});
});
describe("parseEvent", () => {
it("works", () => {
const original = {
type: "message",
attributes: [
{
key: "action",
value: "store-code",
},
{
key: "module",
value: "wasm",
},
{
key: "action",
value: "store-code",
},
{
key: "sender",
value: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6",
},
{
key: "code_id",
value: "1",
},
],
} as const;
const event = parseEvent(original);
expect(event).toEqual(original);
});
});
describe("parseLog", () => {
it("works", () => {
const original = {
msg_index: 0,
log: "",
events: [
{
type: "message",
attributes: [
{
key: "action",
value: "store-code",
},
{
key: "module",
value: "wasm",
},
{
key: "action",
value: "store-code",
},
{
key: "sender",
value: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6",
},
{
key: "code_id",
value: "1",
},
],
},
],
} as const;
const log = parseLog(original);
expect(log).toEqual(original);
});
});
describe("parseLogs", () => {
it("works", () => {
const original = [
{
msg_index: 0,
log: "",
events: [
{
type: "message",
attributes: [
{
key: "action",
value: "store-code",
},
{
key: "module",
value: "wasm",
},
{
key: "action",
value: "store-code",
},
{
key: "sender",
value: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6",
},
{
key: "code_id",
value: "1",
},
],
},
],
},
] as const;
const logs = parseLogs(original);
expect(logs).toEqual(original);
});
});
});

59
packages/sdk/src/logs.ts Normal file
View File

@ -0,0 +1,59 @@
/* eslint-disable @typescript-eslint/camelcase */
import { isNonNullObject } from "@iov/encoding";
export interface Attribute {
readonly key: string;
readonly value: string;
}
export interface Event {
readonly type: "message";
readonly attributes: readonly Attribute[];
}
export interface Log {
readonly msg_index: number;
readonly log: string;
readonly events: readonly Event[];
}
export function parseAttribute(input: unknown): Attribute {
if (!isNonNullObject(input)) throw new Error("Attribute must be a non-null object");
const { key, value } = input as any;
if (typeof key !== "string" || typeof value !== "string") {
throw new Error("Attribute is not a key/value pair");
}
return {
key: key,
value: value,
};
}
export function parseEvent(input: unknown): Event {
if (!isNonNullObject(input)) throw new Error("Event must be a non-null object");
const { type, attributes } = input as any;
if (type !== "message") throw new Error("Event must be of type message");
if (!Array.isArray(attributes)) throw new Error("Event's attributes must be an array");
return {
type: type,
attributes: attributes.map(parseAttribute),
};
}
export function parseLog(input: unknown): Log {
if (!isNonNullObject(input)) throw new Error("Log must be a non-null object");
const { msg_index, log, events } = input as any;
if (typeof msg_index !== "number") throw new Error("Log's msg_index must be a number");
if (typeof log !== "string") throw new Error("Log's log must be a string");
if (!Array.isArray(events)) throw new Error("Log's events must be an array");
return {
msg_index: msg_index,
log: log,
events: events.map(parseEvent),
};
}
export function parseLogs(input: unknown): readonly Log[] {
if (!Array.isArray(input)) throw new Error("Logs must be an array");
return input.map(parseLog);
}

View File

@ -4,6 +4,7 @@ import { Encoding } from "@iov/encoding";
import { HdPaths, Secp256k1HdWallet } from "@iov/keycontrol";
import { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding";
import { Log, parseLogs } from "./logs";
import { RestClient } from "./restclient";
import contract from "./testdata/contract.json";
import data from "./testdata/cosmoshub.json";
@ -25,6 +26,11 @@ function pendingWithoutCosmos(): void {
}
}
function parseSuccess(rawLog?: string): readonly Log[] {
if (!rawLog) throw new Error("Log missing");
return parseLogs(JSON.parse(rawLog));
}
describe("RestClient", () => {
it("can be constructed", () => {
const client = new RestClient(httpUrl);
@ -153,6 +159,9 @@ describe("RestClient", () => {
const result = await client.postTx(postableBytes);
// console.log("Raw log:", result.raw_log);
expect(result.code).toBeFalsy();
const [firstLog] = parseSuccess(result.raw_log);
const codeIdAttr = firstLog.events[0].attributes.find(attr => attr.key === "code_id");
expect(codeIdAttr).toEqual({ key: "code_id", value: "1" });
});
});
});

17
packages/sdk/types/logs.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
export interface Attribute {
readonly key: string;
readonly value: string;
}
export interface Event {
readonly type: "message";
readonly attributes: readonly Attribute[];
}
export interface Log {
readonly msg_index: number;
readonly log: string;
readonly events: readonly Event[];
}
export declare function parseAttribute(input: unknown): Attribute;
export declare function parseEvent(input: unknown): Event;
export declare function parseLog(input: unknown): Log;
export declare function parseLogs(input: unknown): readonly Log[];