added nearly complete p2p implementation

This commit is contained in:
mrfry 2023-03-20 18:02:45 +01:00
parent 11dacdae64
commit 5c22f575dd
25 changed files with 14320 additions and 12563 deletions

View file

@ -1,11 +1,11 @@
import { Subject, Question } from '../types/basicTypes'
import fs from 'fs'
import { RecievedData } from '../utils/actions'
import {
addQuestion,
createQuestion,
getSubjNameWithoutYear,
} from '../utils/classes'
import { Subject, Question } from '../types/basicTypes'
import fs from 'fs'
import { RecievedData } from '../utils/actions'
} from '../utils/qdbUtils'
const question: Question = createQuestion('asd', 'asd', { type: 'simple' })

View file

@ -1,58 +1,23 @@
import { updateQuestionsInArray } from '../utils/actions'
import { createQuestion } from '../utils/classes'
import { cleanDb } from '../utils/classes'
import { QuestionDb, Subject, Question } from '../types/basicTypes'
const date = (x?: number) => new Date().getTime() + (x || 0)
import { questions } from './testData'
import { cleanDb } from '../utils/qdbUtils'
const q1 = createQuestion(
'A kötvény és a részvény közös tulajdonsága, hogy TOREMOVE',
'piaci áruk eltérhet a névértéktől.',
{
type: 'simple',
date: date(-1000),
}
)
const q2 = createQuestion(
'A kötvény és a részvény közös tulajdonsága, hogy TOREMOVE',
'afjléa gféda gfdjs légf',
{
type: 'simple',
date: date(-1000),
}
)
const q3 = createQuestion(
'A kötvény és a részvény közös tulajdonsága, hogy TOREMOVE',
'afjlsd gfds dgfs gf sdgf d',
{
type: 'simple',
date: date(-1000),
}
)
const q4 = createQuestion(
'A kötvény névértéke',
'A kötvényen feltüntetett meghatározott nagyságú összeg.',
{
type: 'simple',
date: date(-1000),
}
)
const q5 = createQuestion(
'Mi az osztalék? asd asd',
'A vállalati profit egy része..',
{
type: 'simple',
date: date(1000),
}
)
const q6 = createQuestion(
'valaim nagyon értelmes kérdés asd asd',
'A vállalati profit egy része..',
{
type: 'simple',
date: date(1000),
}
)
const [q1, q2, q3, q4] = questions.slice(0, 4).map((q) => ({
...q,
data: {
...q.data,
date: 100,
},
}))
const [q5, q6] = questions.slice(4, 6).map((q) => ({
...q,
data: {
...q.data,
date: 1000,
},
}))
function setupTest({
newQuestions,
@ -68,12 +33,12 @@ function setupTest({
...x,
data: {
...x.data,
date: date(),
date: 500,
},
}
})
const subjName = subjToClean || 'subject'
const overwriteFromDate = date(-100)
const overwriteBeforeDate = 400
const qdbIndex = 0
const qdbs: QuestionDb[] = [
{
@ -93,7 +58,7 @@ function setupTest({
{
questions: recievedQuestions,
subjToClean: subjName,
overwriteFromDate: overwriteFromDate,
overwriteBeforeDate: overwriteBeforeDate,
qdbIndex: qdbIndex,
},
qdbs
@ -108,7 +73,7 @@ function setupTest({
return {
questionIndexesToRemove: questionIndexesToRemove,
updatedQuestions: updatedQuestions,
overwriteFromDate: overwriteFromDate,
overwriteBeforeDate: overwriteBeforeDate,
subjIndex: subjIndex,
}
}
@ -116,21 +81,16 @@ function setupTest({
const s1: Subject = { Name: 'test subject', Questions: [q1, q2, q4, q5] }
test('Old and duplicate questions should be removed from the database', () => {
const { questionIndexesToRemove, updatedQuestions, overwriteFromDate } =
setupTest({ newQuestions: [q1, q4, q5], data: [s1] })
expect(questionIndexesToRemove.length).toBe(3)
expect(questionIndexesToRemove[0].length).toBe(2)
expect(updatedQuestions.length).toBe(3)
const toremoveCount = updatedQuestions.filter((question) => {
return question.Q.includes('TOREMOVE')
}).length
expect(toremoveCount).toBe(1)
const newQuestion = updatedQuestions.find((question) => {
return question.Q.includes('TOREMOVE')
const { questionIndexesToRemove, updatedQuestions } = setupTest({
newQuestions: [q1, q2, q3],
data: [s1],
})
expect(newQuestion.data.date > overwriteFromDate).toBeTruthy()
expect(questionIndexesToRemove[0].length).toBe(2)
expect(questionIndexesToRemove[1].length).toBe(2)
expect(questionIndexesToRemove[2].length).toBe(2)
expect(updatedQuestions.length).toBe(5)
})
const s2: Subject = {
@ -139,30 +99,37 @@ const s2: Subject = {
}
test('Old and duplicate questions should be removed from the database round 2', () => {
const { questionIndexesToRemove, updatedQuestions, overwriteFromDate } =
setupTest({ newQuestions: [q1, q4, q5], data: [s2] })
const { questionIndexesToRemove, updatedQuestions } = setupTest({
newQuestions: [q1, q4, q5],
data: [s2],
})
expect(questionIndexesToRemove.length).toBe(3)
expect(questionIndexesToRemove[0].length).toBe(3)
expect(questionIndexesToRemove[1].length).toBe(1)
expect(questionIndexesToRemove[2].length).toBe(0)
expect(updatedQuestions.length).toBe(4)
const toremoveCount = updatedQuestions.filter((question) => {
return question.Q.includes('TOREMOVE')
}).length
expect(toremoveCount).toBe(1)
const newQuestion = updatedQuestions.find((question) => {
return question.Q.includes('TOREMOVE')
})
test('Old and duplicate questions should be removed from the database round 3', () => {
const { questionIndexesToRemove, updatedQuestions } = setupTest({
newQuestions: [q5, q6],
data: [s2],
})
expect(newQuestion.data.date > overwriteFromDate).toBeTruthy()
expect(questionIndexesToRemove[0].length).toBe(0)
expect(questionIndexesToRemove[1].length).toBe(0)
expect(updatedQuestions.length).toBe(6)
})
const s3: Subject = {
Name: 'test subject',
Questions: [q5, q6].map((x) => ({
...x,
Questions: [q5, q6].map((q) => ({
...q,
data: {
...x.data,
date: date(+50000),
...q.data,
date: 50000,
},
})),
}

204
src/tests/p2p.test.ts Normal file
View file

@ -0,0 +1,204 @@
import { getNewDataSince, mergeSubjects } from '../modules/api/submodules/p2p'
import {
countQuestionsInSubjects,
getSubjectDifference,
} from '../utils/qdbUtils'
// import { QuestionDb, Subject } from '../types/basicTypes'
import { questions, subjects } from './testData'
// ------------------------------------------------------------------------------------
// getSubjectDifference
// ------------------------------------------------------------------------------------
test('Merging two similar question dbs should result in the same', () => {
const { newData, newSubjects } = getSubjectDifference(subjects, subjects)
const newQuestionCount = countQuestionsInSubjects(newData)
expect(newSubjects.length).toBe(0)
expect(newQuestionCount).toBe(0)
})
test('Merging qdb with another that has one extra question should get added', () => {
const { newData, newSubjects } = getSubjectDifference(subjects, [
subjects[0],
{
...subjects[1],
Questions: [...subjects[1].Questions, questions[10]],
},
])
const newQuestionCount = countQuestionsInSubjects(newData)
expect(newSubjects.length).toBe(0)
expect(newQuestionCount).toBe(1)
})
test('Qdb merging adding new subject', () => {
const { newData, newSubjects } = getSubjectDifference(
[subjects[0]],
[subjects[0], subjects[1]]
)
const newQuestionCount = countQuestionsInSubjects(newData)
expect(newSubjects.length).toBe(1)
expect(newQuestionCount).toBe(0)
})
test('Qdb merging adding new subject and new questions', () => {
const { newData, newSubjects } = getSubjectDifference(
[subjects[0]],
[
{
...subjects[0],
Questions: [...subjects[0].Questions, questions[10]],
},
subjects[1],
subjects[2],
]
)
const newQuestionCount = countQuestionsInSubjects(newData)
expect(newSubjects.length).toBe(2)
expect(newQuestionCount).toBe(1)
})
// ------------------------------------------------------------------------------------
// getNewDataSince
// ------------------------------------------------------------------------------------
test('get new data since works', () => {
const [q1, q2, q3] = questions
.slice(0, 3)
.map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
const [q4, q5, q6] = questions
.slice(3, 6)
.map((q) => ({ ...q, data: { ...q.data, date: 1000 } }))
const res = getNewDataSince(
[
{
Name: '1',
Questions: [q1, q2, q3, q4, q5, q6],
},
],
750
)
expect(res.length).toBe(1)
expect(res[0].Questions.length).toBe(3)
})
test('get new data since works, multiple subjects', () => {
const [q1, q2, q3] = questions
.slice(0, 3)
.map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
const [q4, q5, q6] = questions
.slice(3, 6)
.map((q) => ({ ...q, data: { ...q.data, date: 1000 } }))
const res = getNewDataSince(
[
{
Name: '1',
Questions: [q1, q2, q3, q4, q5, q6],
},
{
Name: '2',
Questions: [q1, q2, q3, q4],
},
],
750
)
expect(res.length).toBe(2)
expect(res[0].Questions.length).toBe(3)
expect(res[1].Questions.length).toBe(1)
})
test('get new data since works, multiple subjects round 2', () => {
const [q1, q2, q3] = questions
.slice(0, 3)
.map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
const [q4, q5, q6] = questions
.slice(3, 6)
.map((q) => ({ ...q, data: { ...q.data, date: 1000 } }))
const [q7, q8, q9] = questions
.slice(6, 9)
.map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
const res = getNewDataSince(
[
{
Name: '1',
Questions: [q1, q2, q3, q4, q5, q6],
},
{
Name: '2',
Questions: [q7, q8, q9],
},
],
750
)
expect(res.length).toBe(1)
expect(res[0].Questions.length).toBe(3)
})
// ------------------------------------------------------------------------------------
// mergeQdbs
// ------------------------------------------------------------------------------------
test('merge subjects works', () => {
const [s1] = subjects
const res = mergeSubjects([s1], [s1], [s1])
expect(res.length).toBe(2)
expect(res[0].Questions.length).toBe(8)
})
test('merge subjects works, three new subjects', () => {
const [s1] = subjects
const res = mergeSubjects([s1], [s1], [s1, s1, s1])
expect(res.length).toBe(4)
expect(res[0].Questions.length).toBe(8)
expect(res[1].Questions.length).toBe(4)
expect(res[2].Questions.length).toBe(4)
expect(res[3].Questions.length).toBe(4)
})
test('merge subjects works, no new subjects, two subjects to merge', () => {
const [s1] = subjects
const res = mergeSubjects([s1], [s1, s1, s1, s1], [])
expect(res.length).toBe(1)
expect(res[0].Questions.length).toBe(20)
})
test('merge subjects works, merging a subject with different name gets ignored', () => {
const [s1, s2, s3] = subjects
const res = mergeSubjects([s1, s2], [s3], [])
expect(res.length).toBe(2)
expect(res[0].Questions.length).toBe(4)
expect(res[1].Questions.length).toBe(4)
})
test('merge subjects works, 2 subjects to 2, 1 new', () => {
const [s1, s2, s3] = subjects
const res = mergeSubjects([s1, s2], [s1, s2], [s3])
expect(res.length).toBe(3)
expect(res[0].Questions.length).toBe(8)
expect(res[1].Questions.length).toBe(8)
expect(res[2].Questions.length).toBe(4)
})
test('merge subjects works, no new data', () => {
const [s1, s2] = subjects
const res = mergeSubjects([s1, s2], [], [])
expect(res.length).toBe(2)
expect(res[0].Questions.length).toBe(4)
expect(res[1].Questions.length).toBe(4)
})

View file

@ -1,9 +1,9 @@
import {
setNoPossibleAnswersPenalties,
SearchResultQuestion,
noPossibleAnswerMatchPenalty,
} from '../utils/classes'
import { setNoPossibleAnswersPenalties } from '../utils/classes'
import { Question } from '../types/basicTypes'
import {
noPossibleAnswerMatchPenalty,
SearchResultQuestion,
} from '../utils/qdbUtils'
const matchPercent = 100

View file

@ -0,0 +1,38 @@
import { getAvailableQdbIndexes } from '../utils/qdbUtils'
import { emptyQdb } from './testData'
test('getAvailableQdbIndexes works, normal order', () => {
const qdbs = [0, 1, 2, 3, 4].map((x) => {
return { ...emptyQdb, index: x }
})
const [index] = getAvailableQdbIndexes(qdbs)
expect(index).toBe(5)
})
test('getAvailableQdbIndexes works, one missing', () => {
const qdbs = [0, 1, 2, 3, 5].map((x) => {
return { ...emptyQdb, index: x }
})
const [index] = getAvailableQdbIndexes(qdbs)
expect(index).toBe(4)
})
test('getAvailableQdbIndexes works, empty qdb', () => {
const [index] = getAvailableQdbIndexes([])
expect(index).toBe(0)
})
test('getAvailableQdbIndexes works, multiple count', () => {
const qdbs = [0, 1, 2, 3, 5].map((x) => {
return { ...emptyQdb, index: x }
})
let indexes = getAvailableQdbIndexes(qdbs)
expect(indexes.length).toBe(1)
expect(indexes[0]).toBe(4)
indexes = getAvailableQdbIndexes(qdbs, 5)
expect(indexes).toStrictEqual([4, 6, 7, 8, 9])
})

263
src/tests/testData.ts Normal file
View file

@ -0,0 +1,263 @@
import { QuestionDb } from '../types/basicTypes'
import { createQuestion } from '../utils/qdbUtils'
const rawQuestions = [
// 0
{
Q: 'A kötvény és a részvény közös tulajdonsága, hogy TOREMOVE',
A: 'piaci áruk eltérhet a névértéktől.',
data: {
type: 'simple',
date: 1678692844547,
},
},
// 1
{
Q: 'A kötvény és a részvény közös tulajdonsága, hogy TOREMOVE',
A: 'afjléa gféda gfdjs légf',
data: {
type: 'simple',
date: 1678692844547,
},
},
// 2
{
Q: 'A kötvény és a részvény közös tulajdonsága, hogy TOREMOVE',
A: 'afjlsd gfds dgfs gf sdgf d',
data: {
type: 'simple',
date: 1678692844547,
},
},
// 3
{
Q: 'A kötvény névértéke',
A: 'A kötvényen feltüntetett meghatározott nagyságú összeg.',
data: {
type: 'simple',
date: 1678692844547,
},
},
// 4
{
Q: 'Mi az osztalék? asd asd',
A: 'A vállalati profit egy része..',
data: {
type: 'simple',
date: 1678692844547,
},
},
// 5
{
Q: 'valaim nagyon értelmes kérdés asd asd',
A: 'A vállalati profit egy része..',
data: {
type: 'simple',
date: 1678692844547,
},
},
// 6
{
Q: 'A kötvény és a részvény közös tulajdonsága, hogy',
A: 'piaci áruk eltérhet a névértéktől.',
data: {
type: 'simple',
source: 'script',
date: 1252626725558,
},
},
// 7
{
Q: 'A kötvény és a részvény közös tulajdonsága, hogy',
A: 'afjléa gféda gfdjs légf',
data: {
type: 'simple',
source: 'script',
date: 1252626725558,
},
},
// 8
{
Q: 'A kötvény névértéke',
A: 'A kötvényen feltüntetett meghatározott nagyságú összeg.',
data: {
type: 'simple',
source: 'script',
date: 1252626725558,
},
},
// 9
{
Q: 'A részvényesnek joga van',
A: 'Mind a háromra feljogosít.',
data: {
type: 'simple',
source: 'script',
date: 1652636725558,
},
},
// 10
{
Q: 'Mi az osztalék?',
A: 'A vállalati profit egy része..',
data: {
type: 'simple',
source: 'script',
date: 1652636725559,
},
},
// 11
{
Q: 'Az alábbi értékpapírok közül melyik kizárólagos kibocsátója a hitelintézet?',
A: 'letéti jegy.',
data: {
type: 'simple',
source: 'script',
date: 1652636725559,
},
},
// 12
{
Q: 'Mely állítás nem igaz a kötvényre?',
A: 'az osztalék-számítás módját fel kell tüntetni az értékpapíron.',
data: {
type: 'simple',
source: 'script',
date: 1652636725559,
},
},
// 13
{
Q: 'Mely állítás nem igaz a kötvényre?',
A: 'tagsági jogot megtestesítő értékpapír.',
data: {
type: 'simple',
source: 'script',
date: 1652636725559,
},
},
{
Q: 'Az osztalék közvetlenül nem függ',
A: 'a részvénytársaság múltbeli költséggazdálkodásától.',
data: {
type: 'simple',
source: 'script',
date: 1652636725560,
},
},
{
Q: 'Ha a részvénytársaság az egyik tulajdonosától visszavásárolja a saját részvényeit, akkor ezzel',
A: 'átrendezi a vállalat tulajdonosi szerkezetét.',
data: {
type: 'simple',
source: 'script',
date: 1652636725560,
},
},
{
Q: 'Válassza ki az értékpapírokra vonatkozó helyes megállapítást!',
A: 'Vagyoni jogot megtestesítő forgalomképes okirat.',
data: {
type: 'simple',
source: 'script',
date: 1652636725560,
},
},
{
Q: '10. Válassza ki, hogy mely értékpapírtípus járul hozzá egy vállalat alaptőkéjéhez?',
A: 'Részesedési jogot megtestesítő értékpapír.',
data: {
type: 'simple',
source: 'script',
date: 1652636725560,
},
},
{
Q: 'When does the ~/.bashrc script run automatically?',
A: 'When a new terminal window is opened..',
data: {
type: 'simple',
source: 'script',
date: 1678692844546,
},
},
{
Q: 'A robot is ...',
A: '... a complex mechatronic system enabled with electronics, sensors, actuators and software, executing tasks with a certain degree of autonomy. It may be preprogrammed, teleoperated or carrying out computations to make decisions. .',
data: {
type: 'simple',
source: 'script',
date: 1678692844546,
},
},
{
Q: 'A robot is ...',
A: '... some sort of device, which has sensors those sensors the world, does some sort of computation, decides on an action, and then does that action based on the sensory input, which makes some change out in the world, outside its body. .',
data: {
type: 'simple',
source: 'script',
date: 1678692844546,
},
},
{
Q: 'A robot is ...',
A: '... an actuated mechanism programmable in two or more axes with a degree of autonomy, moving within its environment, to perform intended tasks. .',
data: {
type: 'simple',
source: 'script',
date: 1678692844546,
},
},
{
Q: 'ROS is the abbreviation of ...',
A: 'Robot Operating System .',
data: {
type: 'simple',
source: 'script',
date: 1678692844546,
},
},
{
Q: 'A robot is ...',
A: '... a machine—especially one programmable by a computer— capable of carrying out a complex series of actions automatically. Robots can be guided by an external control device or the control may be embedded within. Robots may be constructed on the lines of human form, but most robots are machines designed to perform a task with no regard to their aesthetics. .',
data: {
type: 'simple',
source: 'script',
date: 1678692844547,
},
},
{
Q: 'Complete the definition of a robot: A robot is a complex mechatronic system enabled with electronics, üres , actuators and software, executing tasks with a certain degree of üres . It may be preprogrammed, üres or carrying out computations to make üres .',
A: 'Complete the definition of a robot: A robot is a complex mechatronic system enabled with electronics, [sensors], actuators and software, executing tasks with a certain degree of [autonomy]. It may be preprogrammed, [teleoperated] or carrying out computations to make [decisions].',
data: {
type: 'simple',
source: 'script',
date: 1678692844547,
},
},
]
export const questions = rawQuestions.map((q) => createQuestion(q))
export const subjects = [
{
Name: 'Pénzügyek alapjai',
Questions: questions.slice(0, 4),
},
{
Name: 'Programming robots in ROS',
Questions: questions.slice(4, 8),
},
{
Name: 'Programming something',
Questions: questions.slice(8, 12),
},
]
export const emptyQdb: QuestionDb = {
index: 0,
data: [],
path: '',
name: '',
shouldSearch: '',
shouldSave: {},
}