Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions src/userlib/js/bootstrap/candid/candid.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,27 @@ 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);
inputs.push(inputbox);
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");
Expand All @@ -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 = ''
Expand All @@ -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);
});
};

Expand Down
69 changes: 58 additions & 11 deletions src/userlib/js/bootstrap/candid/idl-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,38 @@ class Parse extends IDL.Visitor<string, any> {
}
}

class Random extends IDL.Visitor<string, any> {
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 && Math.random() < 0.5) {
return -num;
} else {
return num;
}
Comment on lines +105 to +110
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const num = Math.floor(Math.random() * 100);
if (signed && Math.random() < 0.5) {
return -num;
} else {
return num;
}
return 100 - Math.floor(Math.random() * 200);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want negative numbers for Nat.

}
}

export function renderInput(t: IDL.Type): InputBox {
return t.accept(new Render(), null);
}
Expand All @@ -87,6 +119,15 @@ 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(), '');
}

export interface ParseConfig {
random?: boolean;
}

class InputBox {
public input: HTMLInputElement;
public status: HTMLElement;
Expand Down Expand Up @@ -116,14 +157,20 @@ 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 (config.random && this.input.value === '') {
const v = generatePrimitive(this.idl);
this.value = v;
return v;
}
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()}`);
Expand Down Expand Up @@ -163,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) {
Expand Down Expand Up @@ -214,10 +261,10 @@ class RecordForm extends InputForm {
this.generateForm();
this.renderForm(dom);
}
public parse(): Record<string, any> | undefined {
public parse(config: ParseConfig): Record<string, any> | undefined {
const v: Record<string, any> = {};
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())) {
Expand Down Expand Up @@ -247,10 +294,10 @@ class VariantForm extends InputForm {
const variant = renderInput(type);
this.form = [variant];
}
public parse(): Record<string, any> | undefined {
public parse(config: ParseConfig): Record<string, any> | 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;
}
Expand All @@ -277,11 +324,11 @@ class OptionForm extends InputForm {
this.form = [];
}
}
public parse<T>(): [T] | [] | undefined {
public parse<T>(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;
}
Expand Down Expand Up @@ -321,9 +368,9 @@ class VecForm extends InputForm {
this.form.forEach(e => e.render(form));
dom.appendChild(form);
}
public parse<T>(): T[] | undefined {
public parse<T>(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;
Expand Down
4 changes: 2 additions & 2 deletions src/userlib/js/bootstrap/candid/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down