Fix forum logic for negative citations
This commit is contained in:
parent
0c98ae2505
commit
7cda474d20
|
@ -1,5 +1,5 @@
|
||||||
import { Actor } from './actor.js';
|
import { Actor } from './actor.js';
|
||||||
import { WDAG } from './wdag.js';
|
import { WDAG, Vertex } from './wdag.js';
|
||||||
import { Action } from './action.js';
|
import { Action } from './action.js';
|
||||||
import { CryptoUtil } from './crypto.js';
|
import { CryptoUtil } from './crypto.js';
|
||||||
import params from '../params.js';
|
import params from '../params.js';
|
||||||
|
@ -14,7 +14,7 @@ class Post extends Actor {
|
||||||
const index = forum.posts.countVertices();
|
const index = forum.posts.countVertices();
|
||||||
const name = `Post${index + 1}`;
|
const name = `Post${index + 1}`;
|
||||||
super(name, forum.scene);
|
super(name, forum.scene);
|
||||||
this.id = postContent.id ?? `post_${CryptoUtil.randomUUID().slice(0, 4)}`;
|
this.id = postContent.id ?? name;
|
||||||
this.authorPublicKey = authorPublicKey;
|
this.authorPublicKey = authorPublicKey;
|
||||||
this.value = 0;
|
this.value = 0;
|
||||||
this.initialValue = 0;
|
this.initialValue = 0;
|
||||||
|
@ -147,41 +147,48 @@ export class Forum extends ReputationHolder {
|
||||||
if (params.referenceChainLimit === null || depth <= params.referenceChainLimit) {
|
if (params.referenceChainLimit === null || depth <= params.referenceChainLimit) {
|
||||||
for (const citationEdge of postVertex.getEdges(CITATION, true)) {
|
for (const citationEdge of postVertex.getEdges(CITATION, true)) {
|
||||||
const { to: citedPostVertex, weight } = citationEdge;
|
const { to: citedPostVertex, weight } = citationEdge;
|
||||||
const citedPost = citedPostVertex.data;
|
|
||||||
let outboundAmount = weight * increment;
|
let outboundAmount = weight * increment;
|
||||||
const balance = this.posts.getEdge(BALANCE, postVertex, citedPostVertex)?.data || 0;
|
const balance = this.posts.getEdge(BALANCE, postVertex, citedPostVertex)?.weight || 0;
|
||||||
console.log('Citation', {
|
console.log('Citation', {
|
||||||
citationEdge, outboundAmount, balance, citedPostValue: citedPost.value,
|
citationEdge, outboundAmount, balance,
|
||||||
});
|
});
|
||||||
// We need to ensure that we propagate no more reputation than we leached
|
// We need to ensure that we propagate no more reputation than we leached
|
||||||
if (outboundAmount < 0) {
|
if (depth > 0 && weight < 0) {
|
||||||
outboundAmount = Math.max(outboundAmount, -citedPost.value);
|
outboundAmount = outboundAmount < 0
|
||||||
if (depth > 0) {
|
? Math.max(outboundAmount, -balance)
|
||||||
outboundAmount = Math.max(outboundAmount, -balance);
|
: Math.min(outboundAmount, -balance);
|
||||||
}
|
}
|
||||||
}
|
const refundFromOutbound = await this.propagateValue(citationEdge, {
|
||||||
increment -= outboundAmount * params.leachingValue;
|
|
||||||
this.posts.setEdge(BALANCE, postVertex, citedPostVertex, balance + outboundAmount);
|
|
||||||
await this.propagateValue(citationEdge, {
|
|
||||||
rewardsAccumulator,
|
rewardsAccumulator,
|
||||||
increment: outboundAmount,
|
increment: outboundAmount,
|
||||||
depth: depth + 1,
|
depth: depth + 1,
|
||||||
});
|
});
|
||||||
|
outboundAmount -= refundFromOutbound;
|
||||||
|
this.posts.setEdge(BALANCE, postVertex, citedPostVertex, balance + outboundAmount);
|
||||||
|
increment -= outboundAmount * params.leachingValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const newValue = post.value + increment;
|
const rawNewValue = post.value + increment;
|
||||||
|
const newValue = Math.max(0, rawNewValue);
|
||||||
|
const appliedIncrement = newValue - post.value;
|
||||||
|
const refundToInbound = increment - appliedIncrement;
|
||||||
|
|
||||||
console.log('propagateValue end', {
|
console.log('propagateValue end', {
|
||||||
depth,
|
depth,
|
||||||
increment,
|
increment,
|
||||||
|
rawNewValue,
|
||||||
newValue,
|
newValue,
|
||||||
|
appliedIncrement,
|
||||||
|
refundToInbound,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Award reputation to post author
|
// Award reputation to post author
|
||||||
rewardsAccumulator.set(post.tokenId, increment);
|
rewardsAccumulator.set(post.tokenId, appliedIncrement);
|
||||||
|
|
||||||
// Increment the value of the post
|
// Increment the value of the post
|
||||||
await this.setPostValue(post, newValue);
|
await this.setPostValue(post, newValue);
|
||||||
|
|
||||||
|
return refundToInbound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
class Vertex {
|
export class Vertex {
|
||||||
constructor(id, data) {
|
constructor(id, data) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
@ -15,7 +15,7 @@ class Vertex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Edge {
|
export class Edge {
|
||||||
constructor(label, from, to, weight) {
|
constructor(label, from, to, weight) {
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
|
@ -80,9 +80,7 @@ export class WDAG {
|
||||||
setEdge(label, from, to, edge) {
|
setEdge(label, from, to, edge) {
|
||||||
from = from instanceof Vertex ? from : this.getVertex(from);
|
from = from instanceof Vertex ? from : this.getVertex(from);
|
||||||
to = to instanceof Vertex ? to : this.getVertex(to);
|
to = to instanceof Vertex ? to : this.getVertex(to);
|
||||||
if (!(edge instanceof Edge)) {
|
edge = typeof edge === 'number' ? new Edge(label, from, to, edge) : edge;
|
||||||
edge = new Edge(edge);
|
|
||||||
}
|
|
||||||
let edges = this.edgeLabels.get(label);
|
let edges = this.edgeLabels.get(label);
|
||||||
if (!edges) {
|
if (!edges) {
|
||||||
edges = new Map();
|
edges = new Map();
|
||||||
|
|
|
@ -9,7 +9,13 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="./tests/validation-pool.test.html">Validation Pool</a></li>
|
<li><a href="./tests/validation-pool.test.html">Validation Pool</a></li>
|
||||||
<li><a href="./tests/availability.test.html">Availability + Business</a></li>
|
<li><a href="./tests/availability.test.html">Availability + Business</a></li>
|
||||||
<li><a href="./tests/forum.test.html">Forum</a></li>
|
<li>
|
||||||
|
Forum
|
||||||
|
<ul>
|
||||||
|
<li><a href="./tests/forum1.test.html">1</a></li>
|
||||||
|
<li><a href="./tests/forum2.test.html">2</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>Secondary</h3>
|
<h3>Secondary</h3>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<head>
|
<head>
|
||||||
<title>Forum test</title>
|
<title>Forum test 1</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css" />
|
<link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css" />
|
||||||
<link type="text/css" rel="stylesheet" href="../index.css" />
|
<link type="text/css" rel="stylesheet" href="../index.css" />
|
||||||
|
@ -10,9 +10,9 @@
|
||||||
<div id="scene"></div>
|
<div id="scene"></div>
|
||||||
</body>
|
</body>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/radash/10.7.0/radash.js" integrity="sha512-S207zKWG3iqXqe6msO7/Mr8X3DzzF4u8meFlokHjGtBPTGUhgzVo0lpcqEy0GoiMUdcoct+H+SqzoLsxXbynzg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/radash/10.7.0/radash.js" integrity="sha512-S207zKWG3iqXqe6msO7/Mr8X3DzzF4u8meFlokHjGtBPTGUhgzVo0lpcqEy0GoiMUdcoct+H+SqzoLsxXbynzg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
<script src="https://unpkg.com/chai/chai.js"></script>
|
|
||||||
<script src="https://unpkg.com/mocha/mocha.js"></script>
|
<script src="https://unpkg.com/mocha/mocha.js"></script>
|
||||||
<script type="module" src="./scripts/forum.test.js"></script>
|
<script src="https://unpkg.com/chai/chai.js"></script>
|
||||||
|
<script type="module" src="./scripts/forum1.test.js"></script>
|
||||||
<script defer class="mocha-init">
|
<script defer class="mocha-init">
|
||||||
mocha.setup({
|
mocha.setup({
|
||||||
ui: 'bdd',
|
ui: 'bdd',
|
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Forum test 2</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css" />
|
||||||
|
<link type="text/css" rel="stylesheet" href="../index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="mocha"></div>
|
||||||
|
<div id="scene"></div>
|
||||||
|
</body>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/radash/10.7.0/radash.js" integrity="sha512-S207zKWG3iqXqe6msO7/Mr8X3DzzF4u8meFlokHjGtBPTGUhgzVo0lpcqEy0GoiMUdcoct+H+SqzoLsxXbynzg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src="https://unpkg.com/mocha/mocha.js"></script>
|
||||||
|
<script src="https://unpkg.com/chai/chai.js"></script>
|
||||||
|
<script type="module" src="./scripts/forum2.test.js"></script>
|
||||||
|
<script defer class="mocha-init">
|
||||||
|
mocha.setup({
|
||||||
|
ui: 'bdd',
|
||||||
|
globals: ['scene', 'bench', 'forum', 'experts', 'posts', '__REACT_DEVTOOLS_*'],
|
||||||
|
});
|
||||||
|
mocha.checkLeaks();
|
||||||
|
chai.should();
|
||||||
|
</script>
|
||||||
|
<script defer class="mocha-exec">
|
||||||
|
// TODO: Weird race condition -- resolve this in a better way
|
||||||
|
setTimeout(() => mocha.run(), 1000);
|
||||||
|
</script>
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { Box } from '../../classes/box.js';
|
||||||
|
import { Scene } from '../../classes/scene.js';
|
||||||
|
import { Expert } from '../../classes/expert.js';
|
||||||
|
import { Bench } from '../../classes/bench.js';
|
||||||
|
import { delay } from '../../util.js';
|
||||||
|
import { Forum } from '../../classes/forum.js';
|
||||||
|
import { PostContent } from '../../classes/post-content.js';
|
||||||
|
import params from '../../params.js';
|
||||||
|
|
||||||
|
const DEFAULT_DELAY_MS = 1;
|
||||||
|
const POOL_DURATION_MS = 50;
|
||||||
|
|
||||||
|
export class ForumTest {
|
||||||
|
constructor() {
|
||||||
|
this.scene = null;
|
||||||
|
this.forum = null;
|
||||||
|
this.bench = null;
|
||||||
|
this.experts = null;
|
||||||
|
this.posts = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async newExpert() {
|
||||||
|
const index = this.experts.length;
|
||||||
|
const name = `Expert${index + 1}`;
|
||||||
|
const expert = await new Expert(name, this.scene).initialize();
|
||||||
|
this.experts.push(expert);
|
||||||
|
// expert.addValue('rep', () => bench.reputation.valueOwnedBy(expert.reputationPublicKey))
|
||||||
|
return expert;
|
||||||
|
}
|
||||||
|
|
||||||
|
async addPost(author, fee, citations = []) {
|
||||||
|
const postIndex = this.posts.length;
|
||||||
|
const title = `posts[${postIndex}]`;
|
||||||
|
await this.scene.startSection();
|
||||||
|
|
||||||
|
const postContent = new PostContent({}).setTitle(title);
|
||||||
|
for (const { postId, weight } of citations) {
|
||||||
|
postContent.addCitation(postId, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { pool, postId } = await author.submitPostWithFee(
|
||||||
|
this.bench,
|
||||||
|
this.forum,
|
||||||
|
postContent,
|
||||||
|
{
|
||||||
|
fee,
|
||||||
|
duration: POOL_DURATION_MS,
|
||||||
|
tokenLossRatio: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.posts.push(postId);
|
||||||
|
await delay(POOL_DURATION_MS);
|
||||||
|
await pool.evaluateWinningConditions();
|
||||||
|
await this.scene.endSection();
|
||||||
|
await delay(DEFAULT_DELAY_MS);
|
||||||
|
return postId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setup() {
|
||||||
|
const rootElement = document.getElementById('scene');
|
||||||
|
const rootBox = new Box('rootBox', rootElement).flex();
|
||||||
|
|
||||||
|
this.scene = (window.scene = new Scene('Forum test', rootBox));
|
||||||
|
this.scene.withSequenceDiagram();
|
||||||
|
this.scene.withFlowchart();
|
||||||
|
this.scene.withTable();
|
||||||
|
|
||||||
|
this.scene.addDisplayValue('c3. stakeForAuthor').set(params.stakeForAuthor);
|
||||||
|
this.scene.addDisplayValue('q2. revaluationLimit').set(params.revaluationLimit);
|
||||||
|
this.scene
|
||||||
|
.addDisplayValue('q3. referenceChainLimit')
|
||||||
|
.set(params.referenceChainLimit);
|
||||||
|
this.scene.addDisplayValue('q4. leachingValue').set(params.leachingValue);
|
||||||
|
this.scene.addDisplayValue(' ');
|
||||||
|
|
||||||
|
this.forum = (window.forum = new Forum('Forum', this.scene));
|
||||||
|
this.bench = (window.bench = new Bench(this.forum, 'Bench', this.scene));
|
||||||
|
this.experts = (window.experts = []);
|
||||||
|
this.posts = (window.posts = []);
|
||||||
|
|
||||||
|
await this.newExpert();
|
||||||
|
// await newExpert();
|
||||||
|
// await newExpert();
|
||||||
|
|
||||||
|
// bench.addValue('total rep', () => bench.reputation.getTotal());
|
||||||
|
this.forum.addValue('total value', () => this.forum.getTotalValue());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,135 +0,0 @@
|
||||||
import { Box } from '../../classes/box.js';
|
|
||||||
import { Scene } from '../../classes/scene.js';
|
|
||||||
import { Expert } from '../../classes/expert.js';
|
|
||||||
import { Bench } from '../../classes/bench.js';
|
|
||||||
import { delay } from '../../util.js';
|
|
||||||
import { Forum } from '../../classes/forum.js';
|
|
||||||
import { PostContent } from '../../classes/post-content.js';
|
|
||||||
import params from '../../params.js';
|
|
||||||
|
|
||||||
const DEFAULT_DELAY_MS = 1;
|
|
||||||
const POOL_DURATION_MS = 50;
|
|
||||||
|
|
||||||
let scene;
|
|
||||||
let forum;
|
|
||||||
let bench;
|
|
||||||
let experts;
|
|
||||||
let posts;
|
|
||||||
|
|
||||||
async function newExpert() {
|
|
||||||
const index = experts.length;
|
|
||||||
const name = `Expert${index + 1}`;
|
|
||||||
const expert = await new Expert(name, scene).initialize();
|
|
||||||
experts.push(expert);
|
|
||||||
return expert;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addPost(author, fee, citations = []) {
|
|
||||||
const postIndex = posts.length;
|
|
||||||
const title = `posts[${postIndex}]`;
|
|
||||||
await scene.startSection();
|
|
||||||
|
|
||||||
const postContent = new PostContent({}).setTitle(title);
|
|
||||||
for (const { postId, weight } of citations) {
|
|
||||||
postContent.addCitation(postId, weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { pool, postId } = await author.submitPostWithFee(
|
|
||||||
bench,
|
|
||||||
forum,
|
|
||||||
postContent,
|
|
||||||
{
|
|
||||||
fee,
|
|
||||||
duration: POOL_DURATION_MS,
|
|
||||||
tokenLossRatio: 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
posts.push(postId);
|
|
||||||
await delay(POOL_DURATION_MS);
|
|
||||||
await pool.evaluateWinningConditions();
|
|
||||||
await scene.endSection();
|
|
||||||
await delay(DEFAULT_DELAY_MS);
|
|
||||||
return postId;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setup() {
|
|
||||||
const rootElement = document.getElementById('scene');
|
|
||||||
const rootBox = new Box('rootBox', rootElement).flex();
|
|
||||||
|
|
||||||
scene = (window.scene = new Scene('Forum test', rootBox));
|
|
||||||
scene.withSequenceDiagram();
|
|
||||||
scene.withFlowchart();
|
|
||||||
scene.withTable();
|
|
||||||
|
|
||||||
scene.addDisplayValue('c3. stakeForAuthor').set(params.stakeForAuthor);
|
|
||||||
scene.addDisplayValue('q2. revaluationLimit').set(params.revaluationLimit);
|
|
||||||
scene
|
|
||||||
.addDisplayValue('q3. referenceChainLimit')
|
|
||||||
.set(params.referenceChainLimit);
|
|
||||||
scene.addDisplayValue('q4. leachingValue').set(params.leachingValue);
|
|
||||||
scene.addDisplayValue(' ');
|
|
||||||
|
|
||||||
forum = (window.forum = new Forum('Forum', scene));
|
|
||||||
bench = (window.bench = new Bench(forum, 'Bench', scene));
|
|
||||||
experts = (window.experts = []);
|
|
||||||
posts = (window.posts = []);
|
|
||||||
|
|
||||||
await newExpert();
|
|
||||||
// await newExpert();
|
|
||||||
// await newExpert();
|
|
||||||
|
|
||||||
// bench.addValue('total rep', () => bench.reputation.getTotal());
|
|
||||||
forum.addValue('total value', () => forum.getTotalValue());
|
|
||||||
|
|
||||||
// for (const expert of experts) {
|
|
||||||
// expert.addValue('rep', () => bench.reputation.valueOwnedBy(expert.reputationPublicKey));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Forum', () => {
|
|
||||||
before(async () => {
|
|
||||||
await setup();
|
|
||||||
});
|
|
||||||
context('Negative citation of a negative citation with max strength', async () => {
|
|
||||||
it('Post1', async () => {
|
|
||||||
await addPost(experts[0], 10);
|
|
||||||
forum.getPost(posts[0]).value.should.equal(10);
|
|
||||||
});
|
|
||||||
it('Post2 negatively cites Post1', async () => {
|
|
||||||
await addPost(experts[0], 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 () => {
|
|
||||||
await addPost(experts[0], 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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
context('Negative citation of a weaker negative citation', async () => {
|
|
||||||
it('Post4', async () => {
|
|
||||||
await addPost(experts[0], 10);
|
|
||||||
forum.getPost(posts[3]).value.should.equal(10);
|
|
||||||
});
|
|
||||||
it('Post5 negatively cites Post4', async () => {
|
|
||||||
await addPost(experts[0], 10, [{ postId: posts[3], weight: -0.5 }]);
|
|
||||||
forum.getPost(posts[3]).value.should.equal(5);
|
|
||||||
forum.getPost(posts[4]).value.should.equal(15);
|
|
||||||
});
|
|
||||||
it('Post6 negatively cites Post5, restoring Post4 post to its initial value', async () => {
|
|
||||||
await addPost(experts[0], 20, [{ postId: posts[4], weight: -1 }]);
|
|
||||||
forum.getPost(posts[3]).value.should.equal(10);
|
|
||||||
forum.getPost(posts[4]).value.should.equal(0);
|
|
||||||
forum.getPost(posts[5]).value.should.equal(30);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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 }]);
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
|
describe('Forum', () => {
|
||||||
|
const forumTest = new ForumTest();
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await forumTest.setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
context('Negative citation of a negative citation with max strength', async () => {
|
||||||
|
it('Post1', async () => {
|
||||||
|
const { forum, experts, posts } = forumTest;
|
||||||
|
await forumTest.addPost(experts[0], 10);
|
||||||
|
forum.getPost(posts[0]).value.should.equal(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Post2 negatively cites Post1', async () => {
|
||||||
|
const { forum, experts, posts } = forumTest;
|
||||||
|
await forumTest.addPost(experts[0], 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 }]);
|
||||||
|
forum.getPost(posts[0]).value.should.equal(10);
|
||||||
|
forum.getPost(posts[1]).value.should.equal(0);
|
||||||
|
forum.getPost(posts[2]).value.should.equal(20);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 }]);
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
|
describe('Forum', () => {
|
||||||
|
const forumTest = new ForumTest();
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await forumTest.setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
context('Negative citation of a weaker negative citation', async () => {
|
||||||
|
it('Post4', async () => {
|
||||||
|
const { forum, experts, posts } = forumTest;
|
||||||
|
await forumTest.addPost(experts[0], 10);
|
||||||
|
forum.getPost(posts[0]).value.should.equal(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Post5 negatively cites Post4', async () => {
|
||||||
|
const { forum, experts, posts } = forumTest;
|
||||||
|
await forumTest.addPost(experts[0], 10, [{ postId: posts[0], weight: -0.5 }]);
|
||||||
|
forum.getPost(posts[0]).value.should.equal(5);
|
||||||
|
forum.getPost(posts[1]).value.should.equal(15);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Post6 negatively cites Post5, restoring Post4 post to its initial value', async () => {
|
||||||
|
const { forum, experts, posts } = forumTest;
|
||||||
|
await forumTest.addPost(experts[0], 20, [{ 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(30);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 }]);
|
Loading…
Reference in New Issue