Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

decouple sampler and add skips to expect #7

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
12 changes: 6 additions & 6 deletions example/nip01.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ try {


for( const result of results) {
console.log(result.relay, result.suites.Nip01.pass);
//console.log(result.relay, result.suites.Nip01.pass);
}

let totalChecked = 0;
let totalPassed = 0;
let totalFailed = 0;

for (const result of results) {
console.log(result.relay, result.suites.Nip01.pass);
//console.log(result.relay, result.suites.Nip01.pass);

totalChecked++;
if (result.suites.Nip01.pass) {
Expand All @@ -50,7 +50,7 @@ for (const result of results) {

const percentagePassed = ((totalPassed / totalChecked) * 100).toFixed(2);

console.log('Total checked:', totalChecked);
console.log('Total passed:', totalPassed);
console.log('Total failed:', totalFailed);
console.log('Percentage passed:', percentagePassed + '%');
//console.log('Total checked:', totalChecked);
//console.log('Total passed:', totalPassed);
//console.log('Total failed:', totalFailed);
//console.log('Percentage passed:', percentagePassed + '%');
19 changes: 9 additions & 10 deletions example/nip50.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Auditor } from '../dist/server/index.js';
import util from 'util';
import https from 'https';
import { shuffleArray } from '../dist/server/utils/array.js';

const url = 'https://api.nostr.watch/v1/nip/50';

Expand All @@ -12,12 +11,12 @@ try {
throw new Error(`HTTP error! Status: ${response.status}`);
}

const relays = await response.json();
const relays = shuffleArray(await response.json());

if (Array.isArray(relays)) {
for (const relay of relays) {
const auditor = new Auditor();
auditor.removeSuite('Nip01');
// auditor.removeSuite('Nip01');
auditor.addSuite('Nip50')
const result = await auditor.test(relay);
results.push(result);
Expand All @@ -31,15 +30,15 @@ try {


for( const result of results) {
console.log(result.relay, result.suites.Nip50.pass);
//console.log(result.relay, result.suites.Nip50.pass);
}

let totalChecked = 0;
let totalPassed = 0;
let totalFailed = 0;

for (const result of results) {
console.log(result.relay, result.suites.Nip50.pass);
//console.log(result.relay, result.suites.Nip50.pass);

totalChecked++;
if (result.suites.Nip50.pass) {
Expand All @@ -51,7 +50,7 @@ for (const result of results) {

const percentagePassed = ((totalPassed / totalChecked) * 100).toFixed(2);

console.log('Total checked:', totalChecked);
console.log('Total passed:', totalPassed);
console.log('Total failed:', totalFailed);
console.log('Percentage passed:', percentagePassed + '%');
//console.log('Total checked:', totalChecked);
//console.log('Total passed:', totalPassed);
//console.log('Total failed:', totalFailed);
//console.log('Percentage passed:', percentagePassed + '%');
169 changes: 143 additions & 26 deletions src/base/Expect.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,102 @@
import assert from 'power-assert';
import Logger from './Logger.js';
import chalk from 'chalk';
import { toCode } from '#src/utils/string.js';

export interface IAssertWrapOptions {
type: string;
verbose?: boolean;
}

export type IExpectResults = IExpectResult[];

export type IExpectError = Record<string, string | boolean>

export type IExpectErrors = IExpectError[]

export interface IExpectResult {
type: string;
code: string;
message: string;
pass: boolean;
error?: Record<string, string | boolean>;
skipped: boolean;
error?: IExpectError;
}

export const defaultExpectResult = {
type: "unset",
code: "UNSET",
message: "unset",
pass: false,
skipped: false
}

export class AssertWrap {
private _result: IExpectResult[] = [];
private _passed: string[] = [];
private _failed: string[] = [];
private _type: string;
private _result: IExpectResults = [];
private _verbose: boolean = false;
private _skip: boolean = false;
private logger = new Logger('@nostrwatch/auditor:AssertWrap', {
showTimer: false,
showNamespace: false
});

constructor(options: IAssertWrapOptions = {}) {
if(options?.verbose !== undefined) this._verbose = options.verbose;
constructor({type, verbose}: IAssertWrapOptions) {
this._type = type
if(verbose !== undefined) this._verbose = verbose;
if(this._verbose) {
this.logger.registerLogger('pass', 'info', chalk.green.bold)
this.logger.registerLogger('fail', 'info', chalk.redBright.bold)
this.logger.registerLogger('skip', 'info', chalk.gray.bold)
}
}

get result(): IExpectResult[] {
get type() {
return this._type;
}

set skip(skip: boolean) {
this._skip = skip;
}

get skip() {
return this._skip;
}

private set result(result: IExpectResult) {
this._result.push(result);
}

get result(): IExpectResults {
return this._result;
}

private set result(result: IExpectResult) {
this._result.push(result);
get passed(): IExpectResults {
return this.result.filter( result => result.pass )
}

get skipped(): IExpectResults {
return this.result.filter( result => result.skipped )
}

get passed() {
return this._passed;
get failed(): IExpectResults {
return this.result.filter( result => !result.pass && !result.skipped )
}

get failed() {
return this._failed;
get errors(): IExpectErrors {
return this.failed.map( result => result.error )
}

get didPass() {
return this._failed.length === 0;
get passing() {
return this.failed.length === 0;
}

get passRate() {
return Math.round((this._passed.length / (this._passed.length + this._failed.length)) * 100);
return Math.round((this.passed.length / (this.result.length)) * 100);
}

get defaultResult(){
return {...defaultExpectResult, type: this.type};
}

private extractErrorDetails(error: any) {
Expand All @@ -62,18 +107,29 @@ export class AssertWrap {
private createProxy(assertionFn: (...args: any[]) => void) {
return new Proxy((...args: any[]) => assertionFn(...args), {
apply: (target, thisArg, argumentsList) => {
let result: IExpectResult = this.defaultResult;
const message = argumentsList[argumentsList.length - 1];
const code = toCode(message);
let pass = false
let error;

if(this.skip) {
result = { ...result, code, message, skipped: true };
this.result = result;
if(this._verbose) this.logger.custom('skip', `${message}`, 3);
return;
}

try {
Reflect.apply(target, thisArg, argumentsList);
const result: IExpectResult = { message, pass: true };
this.result = result;
if(this._verbose) this.logger.custom(`pass`, `${message}`, 3);
pass = true;

} catch (error) {
error = this.extractErrorDetails(error);
const result: IExpectResult = { message, pass: false, error };
this.result = result
if(this._verbose) this.logger.custom(`fail`, `${message}`, 3);
}
result = { ...result, code, message, pass, error };
if(this._verbose) this.logger.custom(pass? `pass`: `fail`, `${message}`, 3);
this.result = result;
},
});
}
Expand All @@ -93,8 +149,69 @@ export class AssertWrap {
}

export class Expect {
conditions: AssertWrap = new AssertWrap({ verbose: true })
message: AssertWrap = new AssertWrap({ verbose: true })
json: AssertWrap = new AssertWrap({ verbose: true })
behavior: AssertWrap = new AssertWrap({ verbose: true })

readonly keys: Array<keyof Expect> = ['message', 'json', 'behavior']

conditions: AssertWrap = new AssertWrap({ type: 'conditions', verbose: true})
message: AssertWrap = new AssertWrap({ type: 'message' })
json: AssertWrap = new AssertWrap({ type: 'json' })
behavior: AssertWrap = new AssertWrap({ type: 'conditions', verbose: true })
z
get passed(): IExpectResults {
return this.returnKeyAggregate('passed').filter(this.ignoreConditions) as IExpectResults
}

get failed(): IExpectResults {
return this.returnKeyAggregate('failed').filter(this.ignoreConditions) as IExpectResults
}

get skipped(): IExpectResults {
return this.returnKeyAggregate('skipped') as IExpectResults
}

get results(): IExpectResults {
return this.returnKeyAggregate('result').filter(this.ignoreConditions) as IExpectResults
}

get passrate(): number {
return Math.round( this.passed.length / this.results.length );
}

get passing(): boolean {
return this.failed.length === 0;
}

get errors(): IExpectErrors {
return this.returnKeyAggregate('errors') as IExpectErrors;
}

evaluateConditions(skip: boolean = false): boolean {
if(this.conditions.passing) return true;
if(skip) this.skip(['behavior'])
}

private skip(keys: (keyof Expect)[] ): void {
for(const key of keys){
this[key].skip = true;
}
}

private returnKeyAggregate(key: keyof AssertWrap): IExpectResults | IExpectErrors {
// console.log(`returnKeyAggregate: ${key}`)
let res = []
for(const expectKey of this.keys){
const arr = (this[expectKey as keyof Expect] as AssertWrap)[key]
if(!(arr instanceof Array)) {
//console.log(`returnKeyAggregate: this[${expectKey}][${key}] is not an array`)
continue;
}
res = [...res, ...arr]
}
return res;
}

private ignoreConditions(result: IExpectResult): boolean {
return result.type !== 'conditions';
}

}
23 changes: 23 additions & 0 deletions src/base/Ingestor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,37 @@ import { EventEmitter } from 'tseep';
export abstract class Ingestor {
protected signal?: EventEmitter;
protected sampleSize: number = 10;
private _completed: boolean = false;
private _parent?: string;

constructor(sampleSize?: number) {
if(sampleSize){
this.sampleSize = sampleSize;
}
}

get parent(): string {
return this._parent;
}

set belongsTo(parent: string) {
this._parent = parent;
}

abstract feed(note: Note): void;
abstract poop(): any;

registerSignal(signal: any): void {
this.signal = signal;
}

protected complete(): void {
this._completed = true;
}

async completed(): Promise<void> {
while(!this._completed) {
await new Promise(resolve => setTimeout(resolve, 250));
}
}
}
Loading