From c014ad7c19e43bee75a6b3b563cb9cba2df55719 Mon Sep 17 00:00:00 2001 From: chenyan-dfinity Date: Fri, 13 Mar 2020 16:04:46 -0700 Subject: [PATCH 1/5] feat(candid): add random value generator --- src/userlib/js/bootstrap/candid/idl-ui.ts | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/userlib/js/bootstrap/candid/idl-ui.ts b/src/userlib/js/bootstrap/candid/idl-ui.ts index 6365a72491..e6fd39f238 100644 --- a/src/userlib/js/bootstrap/candid/idl-ui.ts +++ b/src/userlib/js/bootstrap/candid/idl-ui.ts @@ -79,6 +79,42 @@ class Parse extends IDL.Visitor { } } +class Random extends IDL.Visitor { + public visitNull(t: IDL.NullClass, v: string): null { + return null; + } + public visitBool(t: IDL.BoolClass, v: string): boolean { + return Math.random() < 0.5; + } + public visitText(t: IDL.TextClass, v: string): string { + return Math.random().toString(36).substring(6); + } + public visitInt(t: IDL.IntClass, v: string): BigNumber { + return new BigNumber(this.generateNumber(true)); + } + public visitNat(t: IDL.NatClass, v: string): BigNumber { + return new BigNumber(this.generateNumber(false)); + } + public visitFixedInt(t: IDL.FixedIntClass, v: string): BigNumber { + return new BigNumber(this.generateNumber(true)); + } + public visitFixedNat(t: IDL.FixedNatClass, v: string): BigNumber { + return new BigNumber(this.generateNumber(false)); + } + private generateNumber(signed: boolean): number { + const num = Math.floor(Math.random() * 100); + if (signed) { + if (Math.random() < 0.5) { + return +num; + } else { + return -num; + } + } else { + return num; + } + } +} + export function renderInput(t: IDL.Type): InputBox { return t.accept(new Render(), null); } @@ -87,6 +123,11 @@ function parsePrimitive(t: IDL.Type, d: string) { return t.accept(new Parse(), d); } +function generatePrimitive(t: IDL.Type) { + // TODO: in the future we may want to take a string to specify how random values are generated + return t.accept(new Random(), ''); +} + class InputBox { public input: HTMLInputElement; public status: HTMLElement; @@ -124,6 +165,11 @@ class InputBox { } try { + if (this.input.value === '') { + const value = generatePrimitive(this.idl); + this.value = value; + return value; + } const value = parsePrimitive(this.idl, this.input.value); if (!this.idl.covariant(value)) { throw new Error(`${this.input.value} is not of type ${this.idl.display()}`); From c4317d1151a48fda3bc31e3c674f64f2b81fbd7b Mon Sep 17 00:00:00 2001 From: chenyan-dfinity Date: Fri, 13 Mar 2020 17:07:26 -0700 Subject: [PATCH 2/5] fix --- src/userlib/js/bootstrap/candid/idl-ui.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/userlib/js/bootstrap/candid/idl-ui.ts b/src/userlib/js/bootstrap/candid/idl-ui.ts index e6fd39f238..b33d4d9ca5 100644 --- a/src/userlib/js/bootstrap/candid/idl-ui.ts +++ b/src/userlib/js/bootstrap/candid/idl-ui.ts @@ -166,9 +166,9 @@ class InputBox { try { if (this.input.value === '') { - const value = generatePrimitive(this.idl); - this.value = value; - return value; + const v = generatePrimitive(this.idl); + this.value = v; + return v; } const value = parsePrimitive(this.idl, this.input.value); if (!this.idl.covariant(value)) { From 53c4868ade4931b5268dc8aa179e641319c28269 Mon Sep 17 00:00:00 2001 From: chenyan-dfinity Date: Fri, 13 Mar 2020 17:16:24 -0700 Subject: [PATCH 3/5] fix --- src/userlib/js/bootstrap/candid/idl-ui.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/userlib/js/bootstrap/candid/idl-ui.ts b/src/userlib/js/bootstrap/candid/idl-ui.ts index b33d4d9ca5..a7130785d6 100644 --- a/src/userlib/js/bootstrap/candid/idl-ui.ts +++ b/src/userlib/js/bootstrap/candid/idl-ui.ts @@ -103,15 +103,11 @@ class Random extends IDL.Visitor { } private generateNumber(signed: boolean): number { const num = Math.floor(Math.random() * 100); - if (signed) { - if (Math.random() < 0.5) { - return +num; - } else { + if (signed && Math.random() < 0.5) { return -num; + } else { + return num; } - } else { - return num; - } } } From c095fca1d312f5821844f1e6ad613d4596e022f2 Mon Sep 17 00:00:00 2001 From: chenyan-dfinity Date: Sat, 14 Mar 2020 18:06:35 -0700 Subject: [PATCH 4/5] add lucky button --- src/userlib/js/bootstrap/candid/candid.js | 48 ++++++++++++++-------- src/userlib/js/bootstrap/candid/idl-ui.ts | 31 ++++++++------ src/userlib/js/bootstrap/candid/index.html | 4 +- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/userlib/js/bootstrap/candid/candid.js b/src/userlib/js/bootstrap/candid/candid.js index 86b65bc47f..6e722b7528 100644 --- a/src/userlib/js/bootstrap/candid/candid.js +++ b/src/userlib/js/bootstrap/candid/candid.js @@ -18,14 +18,6 @@ function renderMethod(name, idl_func, f) { sig.innerHTML = `${name}: ${idl_func.display()}`; item.appendChild(sig); - const button = document.createElement("button"); - button.className = 'btn'; - if (idl_func.annotations.includes('query')) { - button.innerText = 'Query'; - } else { - button.innerText = 'Call'; - } - const inputs = []; idl_func.argTypes.forEach((arg, i) => { const inputbox = UI.renderInput(arg); @@ -33,8 +25,20 @@ function renderMethod(name, idl_func, f) { inputbox.render(item); }); + const button = document.createElement("button"); + button.className = 'btn'; + if (idl_func.annotations.includes('query')) { + button.innerText = 'Query'; + } else { + button.innerText = 'Call'; + } item.appendChild(button); + const random = document.createElement("button"); + random.className = 'btn'; + random.innerText = 'Lucky'; + item.appendChild(random); + const result = document.createElement("div"); result.className = 'result'; const left = document.createElement("span"); @@ -48,13 +52,7 @@ function renderMethod(name, idl_func, f) { const list = document.getElementById("methods"); list.append(item); - button.addEventListener("click", function() { - const args = inputs.map(arg => arg.parse()); - const isReject = inputs.some(arg => arg.isRejected()); - if (isReject) { - return; - } - + function call(args) { left.className = 'left'; left.innerText = 'Waiting...'; right.innerText = '' @@ -79,7 +77,25 @@ function renderMethod(name, idl_func, f) { })().catch(err => { left.className += ' error'; left.innerText = err.message; - }); + }); + } + + random.addEventListener("click", function() { + const args = inputs.map(arg => arg.parse({ random: true })); + const isReject = inputs.some(arg => arg.isRejected()); + if (isReject) { + return; + } + call(args); + }); + + button.addEventListener("click", function() { + const args = inputs.map(arg => arg.parse()); + const isReject = inputs.some(arg => arg.isRejected()); + if (isReject) { + return; + } + call(args); }); }; diff --git a/src/userlib/js/bootstrap/candid/idl-ui.ts b/src/userlib/js/bootstrap/candid/idl-ui.ts index a7130785d6..e0ffeafd36 100644 --- a/src/userlib/js/bootstrap/candid/idl-ui.ts +++ b/src/userlib/js/bootstrap/candid/idl-ui.ts @@ -124,6 +124,10 @@ function generatePrimitive(t: IDL.Type) { return t.accept(new Random(), ''); } +export interface ParseConfig { + random?: boolean; +} + class InputBox { public input: HTMLInputElement; public status: HTMLElement; @@ -144,7 +148,7 @@ class InputBox { if (input.value === '') { return; } - this.parse(); + this.parse({}); }); input.addEventListener('focus', () => { input.className = 'argument'; @@ -153,15 +157,16 @@ class InputBox { public isRejected(): boolean { return this.value === undefined; } - public parse(): any { + + public parse(config: ParseConfig = {}): any { if (this.form) { - const value = this.form.parse(); + const value = this.form.parse(config); this.value = value; return value; } try { - if (this.input.value === '') { + if (config.random && this.input.value === '') { const v = generatePrimitive(this.idl); this.value = v; return v; @@ -205,7 +210,7 @@ abstract class InputForm { public open: HTMLElement = document.createElement('button'); public event: string = 'change'; - public abstract parse(): any; + public abstract parse(config: ParseConfig): any; public abstract generateForm(): any; public renderForm(dom: HTMLElement): void { if (this.form.length === 0) { @@ -256,10 +261,10 @@ class RecordForm extends InputForm { this.generateForm(); this.renderForm(dom); } - public parse(): Record | undefined { + public parse(config: ParseConfig): Record | undefined { const v: Record = {}; this.fields.forEach(([key, _], i) => { - const value = this.form[i].parse(); + const value = this.form[i].parse(config); v[key] = value; }); if (this.form.some(input => input.isRejected())) { @@ -289,10 +294,10 @@ class VariantForm extends InputForm { const variant = renderInput(type); this.form = [variant]; } - public parse(): Record | undefined { + public parse(config: ParseConfig): Record | undefined { const select = this.open as HTMLSelectElement; const selected = select.options[select.selectedIndex].text; - const value = this.form[0].parse(); + const value = this.form[0].parse(config); if (value === undefined) { return undefined; } @@ -319,11 +324,11 @@ class OptionForm extends InputForm { this.form = []; } } - public parse(): [T] | [] | undefined { + public parse(config: ParseConfig): [T] | [] | undefined { if (this.form.length === 0) { return []; } else { - const value = this.form[0].parse(); + const value = this.form[0].parse(config); if (value === undefined) { return undefined; } @@ -363,9 +368,9 @@ class VecForm extends InputForm { this.form.forEach(e => e.render(form)); dom.appendChild(form); } - public parse(): T[] | undefined { + public parse(config: ParseConfig): T[] | undefined { const value = this.form.map(input => { - return input.parse(); + return input.parse(config); }); if (this.form.some(input => input.isRejected())) { return undefined; diff --git a/src/userlib/js/bootstrap/candid/index.html b/src/userlib/js/bootstrap/candid/index.html index d64e773ac6..0322ef5575 100644 --- a/src/userlib/js/bootstrap/candid/index.html +++ b/src/userlib/js/bootstrap/candid/index.html @@ -52,8 +52,8 @@ border-radius: .25rem; color: #FFF; font-family: sans-serif; - font-size: 18px; - font-weight: 700; + font-size: 16px; + font-weight: 700; margin: 5px; } .popup-form { From 9a837c89f2665d75f3d8de86f06e6b841f392a9a Mon Sep 17 00:00:00 2001 From: chenyan-dfinity Date: Sat, 14 Mar 2020 18:10:59 -0700 Subject: [PATCH 5/5] fix --- src/userlib/js/bootstrap/candid/idl-ui.ts | 2 +- src/userlib/js/bootstrap/candid/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/userlib/js/bootstrap/candid/idl-ui.ts b/src/userlib/js/bootstrap/candid/idl-ui.ts index e0ffeafd36..e09feb4b0f 100644 --- a/src/userlib/js/bootstrap/candid/idl-ui.ts +++ b/src/userlib/js/bootstrap/candid/idl-ui.ts @@ -148,7 +148,7 @@ class InputBox { if (input.value === '') { return; } - this.parse({}); + this.parse(); }); input.addEventListener('focus', () => { input.className = 'argument'; diff --git a/src/userlib/js/bootstrap/candid/index.html b/src/userlib/js/bootstrap/candid/index.html index 0322ef5575..a7a30d2c67 100644 --- a/src/userlib/js/bootstrap/candid/index.html +++ b/src/userlib/js/bootstrap/candid/index.html @@ -53,7 +53,7 @@ color: #FFF; font-family: sans-serif; font-size: 16px; - font-weight: 700; + font-weight: 700; margin: 5px; } .popup-form {