diff --git a/forum-network/src/classes/actors/expert.js b/forum-network/src/classes/actors/expert.js index 99f98bb..3a6f9e8 100644 --- a/forum-network/src/classes/actors/expert.js +++ b/forum-network/src/classes/actors/expert.js @@ -1,7 +1,9 @@ import { Action } from '../display/action.js'; import { PostMessage } from '../forum-network/message.js'; -import { CryptoUtil } from '../util/crypto.js'; +import { CryptoUtil } from '../supporting/crypto.js'; import { ReputationHolder } from '../reputation/reputation-holder.js'; +import { EdgeTypes } from '../../util/constants.js'; +import { displayNumber } from '../../util/helpers.js'; export class Expert extends ReputationHolder { constructor(dao, name, scene, options) { @@ -20,6 +22,25 @@ export class Expert extends ReputationHolder { this.tokens = []; } + getReputation() { + const authorVertex = this.dao.forum.graph.getVertex(this.reputationPublicKey); + if (!authorVertex) { + return 0; + } + const authorEdges = authorVertex.getEdges(EdgeTypes.AUTHOR, false); + const tokenValues = authorEdges.map(({ data: { tokenId } }) => this.dao.reputation.valueOf(tokenId)); + return tokenValues.reduce((value, total) => total += value, 0); + } + + getLabel() { + return `${this.name} + + + +
reputation${displayNumber(this.getReputation())}
` + .replaceAll(/\n\s*/g, ''); + } + async initialize() { this.reputationKey = await CryptoUtil.generateAsymmetricKey(); // this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey); diff --git a/forum-network/src/classes/dao/availability.js b/forum-network/src/classes/dao/availability.js index 47d936d..8cdb638 100644 --- a/forum-network/src/classes/dao/availability.js +++ b/forum-network/src/classes/dao/availability.js @@ -1,6 +1,6 @@ import { Action } from '../display/action.js'; import { Actor } from '../display/actor.js'; -import { CryptoUtil } from '../util/crypto.js'; +import { CryptoUtil } from '../supporting/crypto.js'; class Worker { constructor(reputationPublicKey, tokenId, stakeAmount, duration) { diff --git a/forum-network/src/classes/dao/business.js b/forum-network/src/classes/dao/business.js index 67a2705..8c266ee 100644 --- a/forum-network/src/classes/dao/business.js +++ b/forum-network/src/classes/dao/business.js @@ -1,7 +1,7 @@ -import { randomID } from '../../util.js'; +import { randomID } from '../../util/helpers.js'; import { Action } from '../display/action.js'; import { Actor } from '../display/actor.js'; -import { PostContent } from '../util/post-content.js'; +import { PostContent } from '../supporting/post-content.js'; class Request { static nextSeq = 0; diff --git a/forum-network/src/classes/dao/forum.js b/forum-network/src/classes/dao/forum.js index 01175ca..cbfac86 100644 --- a/forum-network/src/classes/dao/forum.js +++ b/forum-network/src/classes/dao/forum.js @@ -3,18 +3,10 @@ import { Action } from '../display/action.js'; import { Actor } from '../display/actor.js'; import params from '../../params.js'; import { ReputationHolder } from '../reputation/reputation-holder.js'; -import { displayNumber, EPSILON, INCINERATOR_ADDRESS } from '../../util.js'; - -const EdgeTypes = { - CITATION: 'citation', - BALANCE: 'balance', - AUTHOR: 'author', -}; - -const VertexTypes = { - POST: 'post', - AUTHOR: 'author', -}; +import { displayNumber } from '../../util/helpers.js'; +import { + EPSILON, INCINERATOR_ADDRESS, EdgeTypes, VertexTypes, +} from '../../util/constants.js'; class Post extends Actor { constructor(forum, senderId, postContent) { @@ -65,36 +57,7 @@ class Post extends Actor { async setValue(value) { this.value = value; await this.setDisplayValue('value', value); - this.forum.graph.setVertexDisplayLabel(this.id, this.getLabel()); - } -} - -class Author extends Actor { - constructor(forum, publicKey) { - super(publicKey, forum.scene); - this.forum = forum; - this.publicKey = publicKey; - this.name = publicKey; - } - - getReputation() { - const authorVertex = this.forum.graph.getVertex(this.publicKey); - if (!authorVertex) { - return 0; - } - const authorEdges = authorVertex.getEdges(EdgeTypes.AUTHOR, false); - const tokenValues = authorEdges.map(({ data: { tokenId } }) => this.forum.dao.reputation.valueOf(tokenId)); - console.log('getReputation', { authorEdges, tokenValues }); - return tokenValues.reduce((value, total) => total += value, 0); - } - - getLabel() { - return `${this.name} - - - -
reputation${displayNumber(this.getReputation())}
` - .replaceAll(/\n\s*/g, ''); + this.forum.graph.getVertex(this.id).setDisplayLabel(this.getLabel()); } } @@ -155,21 +118,29 @@ export class Forum extends ReputationHolder { const post = postVertex.data; post.setStatus('Validated'); post.initialValue = initialValue; - this.graph.setVertexDisplayLabel(post.id, post.getLabel()); + postVertex.setDisplayLabel(post.getLabel()); const addAuthorToGraph = (publicKey, weight, authorTokenId) => { - const author = new Author(this, publicKey); + // For graph display purposes, we want to use the existing Expert actors from the current scene. + const author = this.scene.findActor(({ reputationPublicKey }) => reputationPublicKey === publicKey); + if (author.options.hide) { + return; + } author.setDisplayValue('reputation', () => author.getReputation()); const authorVertex = this.graph.getVertex(publicKey) - ?? this.graph.addVertex(VertexTypes.AUTHOR, publicKey, author, author.getLabel()); - const authorEdge = this.graph.addEdge( + ?? this.graph.addVertex(VertexTypes.AUTHOR, publicKey, author, author.getLabel(), { + hide: author.options.hide, + }); + this.graph.addEdge( EdgeTypes.AUTHOR, postVertex, authorVertex, weight, { tokenId: authorTokenId }, + { + hide: author.options.hide, + }, ); - console.log('addAuthorToGraph', { authorVertex, authorEdge }); }; // In the case of multiple authors, mint additional (empty) tokens. @@ -198,8 +169,9 @@ export class Forum extends ReputationHolder { ); // Apply computed rewards to update values of tokens - for (const [authorTokenId, amount] of rewardsAccumulator) { - console.log('reward', { authorTokenId, amount }); + for (const [authorEdge, amount] of rewardsAccumulator) { + const { to: authorVertex, data: { tokenId: authorTokenId } } = authorEdge; + const { data: author } = authorVertex; // The primary author gets the validation pool minted token. // So we don't need to transfer any reputation to the primary author. // Their reward will be the remaining balance after all other transfers. @@ -210,6 +182,8 @@ export class Forum extends ReputationHolder { this.dao.reputation.transferValueFrom(tokenId, authorTokenId, amount); } } + await author.computeDisplayValues(); + authorVertex.setDisplayLabel(author.getLabel()); } // Transfer ownership of the minted tokens to the authors @@ -218,8 +192,6 @@ export class Forum extends ReputationHolder { const author = authorVertex.data; const { tokenId: authorTokenId } = authorEdge.data; this.dao.reputation.transfer(this.id, author.publicKey, authorTokenId); - authorVertex.setDisplayLabel(author.getLabel()); - await author.computeDisplayValues(); } } @@ -343,9 +315,9 @@ export class Forum extends ReputationHolder { // Apply reputation effects to post authors, not to the post directly for (const authorEdge of postVertex.getEdges(EdgeTypes.AUTHOR, true)) { - const { weight, data: { tokenId }, to: { data: author } } = authorEdge; + const { weight, to: { data: author } } = authorEdge; const authorIncrement = weight * appliedIncrement; - rewardsAccumulator.set(tokenId, authorIncrement); + rewardsAccumulator.set(authorEdge, authorIncrement); this.actions.propagate.log(post, author, `(${authorIncrement})`); } diff --git a/forum-network/src/classes/dao/validation-pool.js b/forum-network/src/classes/dao/validation-pool.js index 6348cfa..24dcc4d 100644 --- a/forum-network/src/classes/dao/validation-pool.js +++ b/forum-network/src/classes/dao/validation-pool.js @@ -3,7 +3,7 @@ import { Stake } from '../supporting/stake.js'; import { Voter } from '../supporting/voter.js'; import params from '../../params.js'; import { Action } from '../display/action.js'; -import { displayNumber } from '../../util.js'; +import { displayNumber } from '../../util/helpers.js'; const ValidationPoolStates = Object.freeze({ OPEN: 'OPEN', diff --git a/forum-network/src/classes/display/actor.js b/forum-network/src/classes/display/actor.js index f489d4d..0f1b011 100644 --- a/forum-network/src/classes/display/actor.js +++ b/forum-network/src/classes/display/actor.js @@ -1,7 +1,13 @@ -import { displayNumber } from '../../util.js'; +import { displayNumber } from '../../util/helpers.js'; export class Actor { - constructor(name, scene, { announce = false } = {}) { + /** + * @param {string} name + * @param {Scene} scene + * @param {boolean} options.announce + * @param {boolean} options.hide + */ + constructor(name, scene, options = {}) { if (!scene) throw new Error('An actor without a scene!'); this.name = name; this.scene = scene; @@ -11,7 +17,8 @@ export class Actor { this.values = new Map(); this.valueFunctions = new Map(); this.active = 0; - scene?.registerActor(this, announce); + this.options = options; + scene?.registerActor(this); } activate() { diff --git a/forum-network/src/classes/display/box.js b/forum-network/src/classes/display/box.js index 46f49f6..bee1f88 100644 --- a/forum-network/src/classes/display/box.js +++ b/forum-network/src/classes/display/box.js @@ -1,5 +1,5 @@ import { DisplayValue } from './display-value.js'; -import { randomID } from '../../util.js'; +import { randomID } from '../../util/helpers.js'; export class Box { constructor(name, parentEl, options = {}) { diff --git a/forum-network/src/classes/display/display-value.js b/forum-network/src/classes/display/display-value.js index e92de70..70a2279 100644 --- a/forum-network/src/classes/display/display-value.js +++ b/forum-network/src/classes/display/display-value.js @@ -1,4 +1,4 @@ -import { displayNumber } from '../../util.js'; +import { displayNumber } from '../../util/helpers.js'; export class DisplayValue { constructor(name, box) { diff --git a/forum-network/src/classes/display/mermaid.js b/forum-network/src/classes/display/mermaid.js index 9d42760..72f0171 100644 --- a/forum-network/src/classes/display/mermaid.js +++ b/forum-network/src/classes/display/mermaid.js @@ -1,5 +1,5 @@ import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.min.mjs'; -import { debounce } from '../../util.js'; +import { debounce } from '../../util/helpers.js'; export class MermaidDiagram { constructor(box, logBox) { diff --git a/forum-network/src/classes/display/scene.js b/forum-network/src/classes/display/scene.js index 344109c..8f62ad1 100644 --- a/forum-network/src/classes/display/scene.js +++ b/forum-network/src/classes/display/scene.js @@ -1,5 +1,5 @@ import { Action } from './action.js'; -import { CryptoUtil } from '../util/crypto.js'; +import { CryptoUtil } from '../supporting/crypto.js'; import { MermaidDiagram } from './mermaid.js'; import { SequenceDiagram } from './sequence.js'; import { Table } from './table.js'; @@ -86,9 +86,9 @@ export class Scene { return this; } - registerActor(actor, announce) { + registerActor(actor) { this.actors.add(actor); - if (announce) { + if (actor.options.announce) { this.sequence?.log(`participant ${actor.name}`); } } @@ -116,10 +116,12 @@ export class Scene { row.set('elapsedMs', new Date() - this.dateStart); row.set('label', label); for (const actor of this.actors) { - for (const [aKey, { name, value }] of actor.getValuesMap()) { - const key = `${actor.name}:${aKey}`; - columns.push({ key, title: name }); - row.set(key, value); + if (!actor.options.hide) { + for (const [aKey, { name, value }] of actor.getValuesMap()) { + const key = `${actor.name}:${aKey}`; + columns.push({ key, title: name }); + row.set(key, value); + } } } columns.push({ key: 'label', title: '' }); diff --git a/forum-network/src/classes/display/sequence.js b/forum-network/src/classes/display/sequence.js index 39fbe2f..2a3b530 100644 --- a/forum-network/src/classes/display/sequence.js +++ b/forum-network/src/classes/display/sequence.js @@ -1,4 +1,4 @@ -import { hexToRGB } from '../../util.js'; +import { hexToRGB } from '../../util/helpers.js'; import { MermaidDiagram } from './mermaid.js'; export class SequenceDiagram extends MermaidDiagram { diff --git a/forum-network/src/classes/display/table.js b/forum-network/src/classes/display/table.js index ee579d4..670acde 100644 --- a/forum-network/src/classes/display/table.js +++ b/forum-network/src/classes/display/table.js @@ -1,4 +1,4 @@ -import { displayNumber } from '../../util.js'; +import { displayNumber } from '../../util/helpers.js'; export class Table { constructor(box) { diff --git a/forum-network/src/classes/forum-network/forum-node.js b/forum-network/src/classes/forum-network/forum-node.js index b262357..ff76ed7 100644 --- a/forum-network/src/classes/forum-network/forum-node.js +++ b/forum-network/src/classes/forum-network/forum-node.js @@ -3,7 +3,7 @@ import { Message, PostMessage, PeerMessage, messageFromJSON, } from './message.js'; import { NetworkNode } from './network-node.js'; -import { randomID } from '../../util.js'; +import { randomID } from '../../util/helpers.js'; export class ForumNode extends NetworkNode { constructor(name, scene) { diff --git a/forum-network/src/classes/forum-network/message.js b/forum-network/src/classes/forum-network/message.js index 2e0ab81..c0cb1be 100644 --- a/forum-network/src/classes/forum-network/message.js +++ b/forum-network/src/classes/forum-network/message.js @@ -1,5 +1,5 @@ -import { CryptoUtil } from '../util/crypto.js'; -import { PostContent } from '../util/post-content.js'; +import { CryptoUtil } from '../supporting/crypto.js'; +import { PostContent } from '../supporting/post-content.js'; export class Message { constructor(content) { diff --git a/forum-network/src/classes/ideas/storage.js b/forum-network/src/classes/ideas/storage.js index e317264..a2d6b1a 100644 --- a/forum-network/src/classes/ideas/storage.js +++ b/forum-network/src/classes/ideas/storage.js @@ -1,4 +1,4 @@ -import { randomID } from '../util/util.js'; +import { randomID } from '../util/util/helpers.js'; class Pledge { constructor({ stake, duration }) { diff --git a/forum-network/src/classes/reputation/reputation-holder.js b/forum-network/src/classes/reputation/reputation-holder.js index 29696ae..5d89e61 100644 --- a/forum-network/src/classes/reputation/reputation-holder.js +++ b/forum-network/src/classes/reputation/reputation-holder.js @@ -1,4 +1,4 @@ -import { randomID } from '../../util.js'; +import { randomID } from '../../util/helpers.js'; import { Actor } from '../display/actor.js'; export class ReputationHolder extends Actor { diff --git a/forum-network/src/classes/reputation/reputation-token.js b/forum-network/src/classes/reputation/reputation-token.js index 65847d6..73ea289 100644 --- a/forum-network/src/classes/reputation/reputation-token.js +++ b/forum-network/src/classes/reputation/reputation-token.js @@ -1,6 +1,6 @@ import { ERC721 } from '../supporting/erc721.js'; - -import { EPSILON, randomID } from '../../util.js'; +import { randomID } from '../../util/helpers.js'; +import { EPSILON } from '../../util/constants.js'; class Lock { constructor(tokenId, amount, duration) { diff --git a/forum-network/src/classes/util/crypto.js b/forum-network/src/classes/supporting/crypto.js similarity index 100% rename from forum-network/src/classes/util/crypto.js rename to forum-network/src/classes/supporting/crypto.js diff --git a/forum-network/src/classes/util/post-content.js b/forum-network/src/classes/supporting/post-content.js similarity index 100% rename from forum-network/src/classes/util/post-content.js rename to forum-network/src/classes/supporting/post-content.js diff --git a/forum-network/src/classes/supporting/wdag.js b/forum-network/src/classes/supporting/wdag.js index ac35558..e3a71bf 100644 --- a/forum-network/src/classes/supporting/wdag.js +++ b/forum-network/src/classes/supporting/wdag.js @@ -1,9 +1,12 @@ +const getEdgeKey = ({ from, to }) => btoa([from.id, to.id]).replaceAll(/[^A-Za-z0-9]+/g, ''); + export class Vertex { - constructor(graph, type, id, data) { + constructor(graph, type, id, data, options = {}) { this.graph = graph; this.type = type; this.id = id; this.data = data; + this.options = options; this.edges = { from: [], to: [], @@ -17,17 +20,50 @@ export class Vertex { } setDisplayLabel(label) { - this.graph.setVertexDisplayLabel(this.id, label); + if (this.options.hide) { + return; + } + this.graph.flowchart?.log(`${this.id}[${label}]`); } } export class Edge { - constructor(type, from, to, weight, data) { + constructor(graph, type, from, to, weight, data, options = {}) { + this.graph = graph; this.from = from; this.to = to; this.type = type; this.weight = weight; this.data = data; + this.options = options; + } + + getHtml() { + let html = ''; + for (const { type, weight } of this.graph.getEdges(null, this.from, this.to)) { + html += ``; + } + html += '
${type}${weight}
'; + return html; + } + + getFlowchartNode() { + return `${getEdgeKey(this)}(${this.getHtml()})`; + } + + displayEdgeNode() { + if (this.options.hide) { + return; + } + this.graph.flowchart?.log(this.getFlowchartNode()); + } + + displayEdge() { + if (this.options.hide) { + return; + } + this.graph.flowchart?.log(`${this.from.id} --- ${this.getFlowchartNode()} --> ${this.to.id}`); + this.graph.flowchart?.log(`class ${getEdgeKey(this)} edge`); } } @@ -46,11 +82,7 @@ export class WDAG { return this; } - setVertexDisplayLabel(id, label) { - this.flowchart?.log(`${id}[${label}]`); - } - - addVertex(type, id, data, label) { + addVertex(type, id, data, label, options) { // Support simple case of auto-incremented numeric ids if (typeof id === 'object') { data = id; @@ -59,9 +91,9 @@ export class WDAG { if (this.vertices.has(id)) { throw new Error(`Vertex already exists with id: ${id}`); } - const vertex = new Vertex(this, type, id, data); + const vertex = new Vertex(this, type, id, data, options); this.vertices.set(id, vertex); - this.setVertexDisplayLabel(id, label ?? id); + vertex.setDisplayLabel(id, label ?? id); return vertex; } @@ -77,10 +109,6 @@ export class WDAG { return Array.from(this.vertices.values()).map(({ data }) => data); } - static getEdgeKey({ from, to }) { - return btoa([from.id, to.id]).replaceAll(/[^A-Za-z0-9]+/g, ''); - } - getEdge(type, from, to) { from = from instanceof Vertex ? from : this.getVertex(from); to = to instanceof Vertex ? to : this.getVertex(to); @@ -88,7 +116,7 @@ export class WDAG { return undefined; } const edges = this.edgeTypes.get(type); - const edgeKey = WDAG.getEdgeKey({ from, to }); + const edgeKey = getEdgeKey({ from, to }); return edges?.get(edgeKey); } @@ -96,46 +124,31 @@ export class WDAG { return this.getEdge(type, from, to)?.weight; } - getEdgeHtml({ from, to }) { - let html = ''; - for (const { type, weight } of this.getEdges(null, from, to)) { - html += ``; - } - html += '
${type}${weight}
'; - return html; - } - - getEdgeFlowchartNode(edge) { - const edgeKey = WDAG.getEdgeKey(edge); - return `${edgeKey}(${this.getEdgeHtml(edge)})`; - } - - setEdgeWeight(type, from, to, weight, data) { + setEdgeWeight(type, from, to, weight, data, options) { from = from instanceof Vertex ? from : this.getVertex(from); to = to instanceof Vertex ? to : this.getVertex(to); - const edge = new Edge(type, from, to, weight, data); + const edge = new Edge(this, type, from, to, weight, data, options); let edges = this.edgeTypes.get(type); if (!edges) { edges = new Map(); this.edgeTypes.set(type, edges); } - const edgeKey = WDAG.getEdgeKey(edge); + const edgeKey = getEdgeKey(edge); edges.set(edgeKey, edge); - this.flowchart?.log(this.getEdgeFlowchartNode(edge)); + edge.displayEdgeNode(); return edge; } - addEdge(type, from, to, weight, data) { + addEdge(type, from, to, weight, data, options) { from = from instanceof Vertex ? from : this.getVertex(from); to = to instanceof Vertex ? to : this.getVertex(to); if (this.getEdge(type, from, to)) { throw new Error(`Edge ${type} from ${from.id} to ${to.id} already exists`); } - const edge = this.setEdgeWeight(type, from, to, weight, data); + const edge = this.setEdgeWeight(type, from, to, weight, data, options); from.edges.from.push(edge); to.edges.to.push(edge); - this.flowchart?.log(`${from.id} --- ${this.getEdgeFlowchartNode(edge)} --> ${to.id}`); - this.flowchart?.log(`class ${WDAG.getEdgeKey(edge)} edge`); + edge.displayEdge(); return edge; } diff --git a/forum-network/src/classes/util/prioritized-queue.js b/forum-network/src/classes/util/prioritized-queue.js deleted file mode 100644 index 79b5851..0000000 --- a/forum-network/src/classes/util/prioritized-queue.js +++ /dev/null @@ -1,24 +0,0 @@ -export class PrioritizedQueue { - constructor() { - this.buffer = []; - } - - // Add an item to the buffer, ahead of the next lowest priority item - add(message, priority) { - const idx = this.buffer.findIndex((item) => item.priority < priority); - if (idx < 0) { - this.buffer.push({ message, priority }); - } else { - this.buffer.splice(idx, 0, { message, priority }); - } - } - - // Return the highest priority item in the buffer - pop() { - if (!this.buffer.length) { - return null; - } - const item = this.buffer.shift(); - return item.message; - } -} diff --git a/forum-network/src/tests/flowchart.test.html b/forum-network/src/tests/flowchart.test.html index 97f9021..ff07fe1 100644 --- a/forum-network/src/tests/flowchart.test.html +++ b/forum-network/src/tests/flowchart.test.html @@ -14,7 +14,7 @@ import { Scene } from '../classes/display/scene.js'; import { Actor } from '../classes/display/actor.js'; import { Action } from '../classes/display/action.js'; - import { delay } from '../util.js'; + import { delay } from '../util/helpers.js'; const DEFAULT_DELAY_INTERVAL = 500; diff --git a/forum-network/src/tests/reputation.test.html b/forum-network/src/tests/reputation.test.html index 6c2bad7..d91e105 100644 --- a/forum-network/src/tests/reputation.test.html +++ b/forum-network/src/tests/reputation.test.html @@ -15,7 +15,7 @@ // import { ValidationPool } from '../classes/validation-pool.js'; // import { TokenHolder } from '../classes/token-holder.js'; // import { ReputationToken } from '../classes/reputation-token.js'; - import { delay } from '../util.js'; + import { delay } from '../util/helpers.js'; const DEFAULT_DELAY_INTERVAL = 500; diff --git a/forum-network/src/tests/scripts/availability.test.js b/forum-network/src/tests/scripts/availability.test.js index b4e1d37..418335c 100644 --- a/forum-network/src/tests/scripts/availability.test.js +++ b/forum-network/src/tests/scripts/availability.test.js @@ -3,9 +3,9 @@ import { Scene } from '../../classes/display/scene.js'; import { Expert } from '../../classes/actors/expert.js'; import { DAO } from '../../classes/dao/dao.js'; import { Public } from '../../classes/actors/public.js'; -import { PostContent } from '../../classes/util/post-content.js'; +import { PostContent } from '../../classes/supporting/post-content.js'; import { delayOrWait } from '../../classes/display/controls.js'; -import { mochaRun } from '../../util.js'; +import { mochaRun } from '../../util/helpers.js'; const DELAY_INTERVAL = 100; const POOL_DURATION = 200; diff --git a/forum-network/src/tests/scripts/business.test.js b/forum-network/src/tests/scripts/business.test.js index dd3a524..97bb8b2 100644 --- a/forum-network/src/tests/scripts/business.test.js +++ b/forum-network/src/tests/scripts/business.test.js @@ -1,7 +1,7 @@ import { Business } from '../../classes/dao/business.js'; import { Scene } from '../../classes/display/scene.js'; import { Box } from '../../classes/display/box.js'; -import { mochaRun } from '../../util.js'; +import { mochaRun } from '../../util/helpers.js'; describe('Business', function tests() { this.timeout(0); diff --git a/forum-network/src/tests/scripts/debounce.test.js b/forum-network/src/tests/scripts/debounce.test.js index b0de18e..2945e18 100644 --- a/forum-network/src/tests/scripts/debounce.test.js +++ b/forum-network/src/tests/scripts/debounce.test.js @@ -2,7 +2,7 @@ import { Box } from '../../classes/display/box.js'; import { Scene } from '../../classes/display/scene.js'; import { Action } from '../../classes/display/action.js'; import { Actor } from '../../classes/display/actor.js'; -import { debounce, delay, mochaRun } from '../../util.js'; +import { debounce, delay, mochaRun } from '../../util/helpers.js'; describe('Debounce', () => { let scene; diff --git a/forum-network/src/tests/scripts/forum-network.test.js b/forum-network/src/tests/scripts/forum-network.test.js index 5cbe692..c40a394 100644 --- a/forum-network/src/tests/scripts/forum-network.test.js +++ b/forum-network/src/tests/scripts/forum-network.test.js @@ -1,10 +1,10 @@ import { Box } from '../../classes/display/box.js'; import { Scene } from '../../classes/display/scene.js'; -import { PostContent } from '../../classes/util/post-content.js'; +import { PostContent } from '../../classes/supporting/post-content.js'; import { Expert } from '../../classes/actors/expert.js'; import { ForumNode } from '../../classes/forum-network/forum-node.js'; import { Network } from '../../classes/forum-network/network.js'; -import { mochaRun, randomID } from '../../util.js'; +import { mochaRun, randomID } from '../../util/helpers.js'; import { delayOrWait } from '../../classes/display/controls.js'; describe('Forum Network', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum.test-util.js b/forum-network/src/tests/scripts/forum/forum.test-util.js index aabcd46..2409d0c 100644 --- a/forum-network/src/tests/scripts/forum/forum.test-util.js +++ b/forum-network/src/tests/scripts/forum/forum.test-util.js @@ -1,7 +1,7 @@ import { Box } from '../../../classes/display/box.js'; import { Scene } from '../../../classes/display/scene.js'; import { Expert } from '../../../classes/actors/expert.js'; -import { PostContent } from '../../../classes/util/post-content.js'; +import { PostContent } from '../../../classes/supporting/post-content.js'; import params from '../../../params.js'; import { DAO } from '../../../classes/dao/dao.js'; import { delayOrWait } from '../../../classes/display/controls.js'; @@ -55,12 +55,16 @@ export class ForumTest { return postId; } - async newExpert(options) { + async newExpert() { + // Hide by default, for simplicity of rendering first 9 forum tests + const options = { + hide: !this.options.displayAuthors, + announce: this.options.displayAuthors, + }; const index = this.experts.length; const name = `Expert${index + 1}`; const expert = await new Expert(this.dao, name, this.scene, options).initialize(); this.experts.push(expert); - // await expert.addComputedValue('rep', () => this.dao.reputation.valueOwnedBy(expert.reputationPublicKey)); return expert; } @@ -81,12 +85,13 @@ export class ForumTest { scene.addDisplayValue('q4. leachingValue').set(params.leachingValue); scene.addDisplayValue(' '); - this.dao = new DAO('DAO', scene, { announce: true }); + // If we're going to announce experts, announce the DAO so it appears first. + this.dao = new DAO('DAO', scene, { announce: this.options.displayAuthors }); this.forum = this.dao.forum; this.experts = []; this.posts = []; - await this.newExpert({ announce: true }); + await this.newExpert(); await this.dao.addComputedValue('total value', () => this.dao.reputation.getTotal()); } diff --git a/forum-network/src/tests/scripts/forum/forum1.test.js b/forum-network/src/tests/scripts/forum/forum1.test.js index 2800972..b2e8895 100644 --- a/forum-network/src/tests/scripts/forum/forum1.test.js +++ b/forum-network/src/tests/scripts/forum/forum1.test.js @@ -1,13 +1,15 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { this.timeout(0); - const forumTest = new ForumTest(); + const forumTest = new ForumTest({ displayAuthors: false }); before(async () => { await forumTest.setup(); + await forumTest.newExpert(); + await forumTest.newExpert(); }); context('Negative citation of a negative citation', async () => { @@ -19,14 +21,14 @@ describe('Forum', function tests() { it('Post2 negatively cites Post1', async () => { const { forum, experts, posts } = forumTest; - await forumTest.addPost(experts[0], 10, [{ postId: posts[0], weight: -1 }]); + await forumTest.addPost(experts[1], 10, [{ postId: posts[0], weight: -1 }]); forum.getPost(posts[0]).value.should.equal(0); forum.getPost(posts[1]).value.should.equal(20); }); it('Post3 negatively cites Post2, restoring Post1 post to its initial value', async () => { const { forum, experts, posts } = forumTest; - await forumTest.addPost(experts[0], 10, [{ postId: posts[1], weight: -1 }]); + await forumTest.addPost(experts[2], 10, [{ postId: posts[1], weight: -1 }]); forum.getPost(posts[0]).value.should.equal(10); forum.getPost(posts[1]).value.should.equal(0); forum.getPost(posts[2]).value.should.equal(20); @@ -34,11 +36,4 @@ describe('Forum', function tests() { }); }); -// await addPost(experts[0], 10); -// await addPost(experts[0], 10, [{ postId: posts[3], weight: -1 }]); -// await addPost(experts[0], 10, [{ postId: posts[4], weight: -1 }]); - -// await addPost(expert3, 'Post 4', 100, [{ postId: postId2, weight: -1 }]); -// await addPost(expert1, 'Post 5', 100, [{ postId: postId3, weight: -1 }]); - mochaRun(); diff --git a/forum-network/src/tests/scripts/forum/forum10.test.js b/forum-network/src/tests/scripts/forum/forum10.test.js index fa3fb02..fc21536 100644 --- a/forum-network/src/tests/scripts/forum/forum10.test.js +++ b/forum-network/src/tests/scripts/forum/forum10.test.js @@ -1,13 +1,15 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { this.timeout(0); - const forumTest = new ForumTest(); + const forumTest = new ForumTest({ displayAuthors: true }); before(async () => { await forumTest.setup(); + await forumTest.newExpert(); + await forumTest.newExpert(); }); context('Post with multiple authors', async () => { @@ -19,9 +21,6 @@ describe('Forum', function tests() { forum = forumTest.forum; experts = forumTest.experts; posts = forumTest.posts; - - await forumTest.newExpert({ announce: true }); - await forumTest.newExpert({ announce: true }); }); it('Post1', async () => { diff --git a/forum-network/src/tests/scripts/forum/forum11.test.js b/forum-network/src/tests/scripts/forum/forum11.test.js index 2d6e983..18553e6 100644 --- a/forum-network/src/tests/scripts/forum/forum11.test.js +++ b/forum-network/src/tests/scripts/forum/forum11.test.js @@ -1,13 +1,15 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { this.timeout(0); - const forumTest = new ForumTest(); + const forumTest = new ForumTest({ displayAuthors: true }); before(async () => { await forumTest.setup(); + await forumTest.newExpert(); + await forumTest.newExpert(); }); context('Multiple posts with overlapping authors', async () => { @@ -19,9 +21,6 @@ describe('Forum', function tests() { forum = forumTest.forum; experts = forumTest.experts; posts = forumTest.posts; - - await forumTest.newExpert({ announce: true }); - await forumTest.newExpert({ announce: true }); }); it('Post1 with two authors', async () => { diff --git a/forum-network/src/tests/scripts/forum/forum2.test.js b/forum-network/src/tests/scripts/forum/forum2.test.js index 6c76676..71b1e76 100644 --- a/forum-network/src/tests/scripts/forum/forum2.test.js +++ b/forum-network/src/tests/scripts/forum/forum2.test.js @@ -1,4 +1,4 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum3.test.js b/forum-network/src/tests/scripts/forum/forum3.test.js index f8d65ce..1fd49e1 100644 --- a/forum-network/src/tests/scripts/forum/forum3.test.js +++ b/forum-network/src/tests/scripts/forum/forum3.test.js @@ -1,4 +1,4 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum4.test.js b/forum-network/src/tests/scripts/forum/forum4.test.js index 2349110..1a35b13 100644 --- a/forum-network/src/tests/scripts/forum/forum4.test.js +++ b/forum-network/src/tests/scripts/forum/forum4.test.js @@ -1,4 +1,4 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum5.test.js b/forum-network/src/tests/scripts/forum/forum5.test.js index 52e819b..b6c0a34 100644 --- a/forum-network/src/tests/scripts/forum/forum5.test.js +++ b/forum-network/src/tests/scripts/forum/forum5.test.js @@ -1,4 +1,4 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum6.test.js b/forum-network/src/tests/scripts/forum/forum6.test.js index 8cb920e..69ddd39 100644 --- a/forum-network/src/tests/scripts/forum/forum6.test.js +++ b/forum-network/src/tests/scripts/forum/forum6.test.js @@ -1,4 +1,5 @@ -import { EPSILON, mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; +import { EPSILON } from '../../../util/constants.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum7.test.js b/forum-network/src/tests/scripts/forum/forum7.test.js index 670e634..83cbf59 100644 --- a/forum-network/src/tests/scripts/forum/forum7.test.js +++ b/forum-network/src/tests/scripts/forum/forum7.test.js @@ -1,4 +1,4 @@ -import { mochaRun } from '../../../util.js'; +import { mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum8.test.js b/forum-network/src/tests/scripts/forum/forum8.test.js index 513cc91..a27f0e2 100644 --- a/forum-network/src/tests/scripts/forum/forum8.test.js +++ b/forum-network/src/tests/scripts/forum/forum8.test.js @@ -1,4 +1,4 @@ -import { INCINERATOR_ADDRESS, mochaRun } from '../../../util.js'; +import { INCINERATOR_ADDRESS, mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/forum/forum9.test.js b/forum-network/src/tests/scripts/forum/forum9.test.js index 5bc484a..321d182 100644 --- a/forum-network/src/tests/scripts/forum/forum9.test.js +++ b/forum-network/src/tests/scripts/forum/forum9.test.js @@ -1,4 +1,4 @@ -import { INCINERATOR_ADDRESS, mochaRun } from '../../../util.js'; +import { INCINERATOR_ADDRESS, mochaRun } from '../../../util/helpers.js'; import { ForumTest } from './forum.test-util.js'; describe('Forum', function tests() { diff --git a/forum-network/src/tests/scripts/validation-pool.test.js b/forum-network/src/tests/scripts/validation-pool.test.js index 3d1e8c4..337ff74 100644 --- a/forum-network/src/tests/scripts/validation-pool.test.js +++ b/forum-network/src/tests/scripts/validation-pool.test.js @@ -1,10 +1,10 @@ import { Box } from '../../classes/display/box.js'; import { Scene } from '../../classes/display/scene.js'; import { Expert } from '../../classes/actors/expert.js'; -import { PostContent } from '../../classes/util/post-content.js'; +import { PostContent } from '../../classes/supporting/post-content.js'; import { DAO } from '../../classes/dao/dao.js'; import { delayOrWait } from '../../classes/display/controls.js'; -import { mochaRun } from '../../util.js'; +import { mochaRun } from '../../util/helpers.js'; const POOL_DURATION_MS = 100; const DEFAULT_DELAY_MS = 100; diff --git a/forum-network/src/tests/scripts/vm.test.js b/forum-network/src/tests/scripts/vm.test.js index ffd1967..fd2b1df 100644 --- a/forum-network/src/tests/scripts/vm.test.js +++ b/forum-network/src/tests/scripts/vm.test.js @@ -2,7 +2,7 @@ import { Actor } from '../../classes/display/actor.js'; import { Box } from '../../classes/display/box.js'; import { Scene } from '../../classes/display/scene.js'; import { VM } from '../../classes/supporting/vm.js'; -import { mochaRun } from '../../util.js'; +import { mochaRun } from '../../util/helpers.js'; const contractIds = ['contract-id-1', 'contract-id-2']; diff --git a/forum-network/src/tests/scripts/wdag.test.js b/forum-network/src/tests/scripts/wdag.test.js index 439dd17..dfc15a3 100644 --- a/forum-network/src/tests/scripts/wdag.test.js +++ b/forum-network/src/tests/scripts/wdag.test.js @@ -1,7 +1,7 @@ import { Box } from '../../classes/display/box.js'; import { Scene } from '../../classes/display/scene.js'; import { WDAG } from '../../classes/supporting/wdag.js'; -import { mochaRun } from '../../util.js'; +import { mochaRun } from '../../util/helpers.js'; const rootElement = document.getElementById('scene'); const rootBox = new Box('rootBox', rootElement).flex(); diff --git a/forum-network/src/util/constants.js b/forum-network/src/util/constants.js new file mode 100644 index 0000000..65b28c9 --- /dev/null +++ b/forum-network/src/util/constants.js @@ -0,0 +1,14 @@ +export const EPSILON = 2.23e-16; + +export const INCINERATOR_ADDRESS = 0; + +export const EdgeTypes = { + CITATION: 'citation', + BALANCE: 'balance', + AUTHOR: 'author', +}; + +export const VertexTypes = { + POST: 'post', + AUTHOR: 'author', +}; diff --git a/forum-network/src/util.js b/forum-network/src/util/helpers.js similarity index 81% rename from forum-network/src/util.js rename to forum-network/src/util/helpers.js index 427bfb1..53ad6ee 100644 --- a/forum-network/src/util.js +++ b/forum-network/src/util/helpers.js @@ -1,11 +1,5 @@ -import { CryptoUtil } from './classes/util/crypto.js'; - const timers = new Map(); -export const EPSILON = 2.23e-16; - -export const INCINERATOR_ADDRESS = 0; - export const debounce = async (fn, delayMs) => { const timer = timers.get(fn); if (timer) { @@ -39,7 +33,7 @@ export const displayNumber = (value, decimals = 2) => (value.toString().length > ? value.toFixed(decimals) : value); -export const randomID = () => CryptoUtil.randomUUID().replaceAll('-', '').slice(0, 8); +export const randomID = () => window.crypto.randomUUID().replaceAll('-', '').slice(0, 8); export const mochaRun = () => { if (mocha._state !== 'running') {