first test!
This commit is contained in:
parent
8d12e9df9c
commit
b94966aeb5
2 changed files with 181 additions and 8 deletions
|
|
@ -1,12 +1,12 @@
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, toValue } from 'vue'
|
||||||
|
|
||||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
import { useStatusesStore } from 'src/stores/statuses.js'
|
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||||
|
|
||||||
export function useTreeConversationTopology(conversation, replies, current) {
|
export function useTreeConversationTopology(conversation, replies, current) {
|
||||||
const getStatusObject = (id) => useStatusesStore().allStatuses.get(id)
|
const getStatusObject = (id) => useStatusesStore().allStatuses.get(id)
|
||||||
const getReplies = (id) => replies.value.get(id) ?? new Set()
|
const getReplies = (id) => toValue(replies).get(id) ?? new Set()
|
||||||
|
|
||||||
const { mergedConfig } = storeToRefs(useMergedConfigStore())
|
const { mergedConfig } = storeToRefs(useMergedConfigStore())
|
||||||
|
|
||||||
|
|
@ -21,12 +21,12 @@ export function useTreeConversationTopology(conversation, replies, current) {
|
||||||
const ancestors = computed(() => {
|
const ancestors = computed(() => {
|
||||||
// First we fill map with empty sets and add given id's parent
|
// First we fill map with empty sets and add given id's parent
|
||||||
// as set's only element (if any)
|
// as set's only element (if any)
|
||||||
const parentMap = conversation.value.reduce(
|
const parentMap = toValue(conversation).reduce(
|
||||||
(result, { id, in_reply_to_status_id: irid }) => {
|
(result, { id, in_reply_to_status_id: irid }) => {
|
||||||
if (!result.has(id)) {
|
if (!result.has(id)) {
|
||||||
result.set(id, new Set())
|
result.set(id, new Set())
|
||||||
}
|
}
|
||||||
if (irid && conversation.value.length !== 1) {
|
if (irid && toValue(conversation).length !== 1) {
|
||||||
// Setting parent for current item
|
// Setting parent for current item
|
||||||
result.get(id).add(irid)
|
result.get(id).add(irid)
|
||||||
}
|
}
|
||||||
|
|
@ -48,26 +48,32 @@ export function useTreeConversationTopology(conversation, replies, current) {
|
||||||
})
|
})
|
||||||
return parentMap
|
return parentMap
|
||||||
})
|
})
|
||||||
const topLevel = computed(() =>
|
const topLevelIds = computed(() =>
|
||||||
[...ancestors.value.entries()]
|
[...ancestors.value.entries()]
|
||||||
.filter(([id, ancestors]) => ancestors.size === 0)
|
.filter(([id, ancestors]) => ancestors.size === 0)
|
||||||
.map(([id]) => getStatusObject(id)),
|
.map(([id]) => id),
|
||||||
|
)
|
||||||
|
const topLevel = computed(() =>
|
||||||
|
topLevelIds.value.map((id) => getStatusObject(id)),
|
||||||
)
|
)
|
||||||
const getAncestorIds = (id) => ancestors.value.get(id) ?? new Set()
|
const getAncestorIds = (id) => ancestors.value.get(id) ?? new Set()
|
||||||
const getAncestors = (id) =>
|
const getAncestors = (id) =>
|
||||||
[...getAncestorIds(id)].map(getStatusObject).filter(Boolean)
|
[...getAncestorIds(id)].map(getStatusObject).filter(Boolean)
|
||||||
const currentAncestors = computed(() => getAncestors(current.value).reverse())
|
const currentAncestors = computed(() =>
|
||||||
|
getAncestors(toValue(current)).reverse(),
|
||||||
|
)
|
||||||
const currentDepth = computed(() => currentAncestors.value.length)
|
const currentDepth = computed(() => currentAncestors.value.length)
|
||||||
|
|
||||||
// Thread Display, for collapsing/expanding tree branches
|
// Thread Display, for collapsing/expanding tree branches
|
||||||
// Map of id => 'showing' | 'hidden'
|
// Map of id => 'showing' | 'hidden'
|
||||||
const threadDisplayOverride = ref(new Map())
|
const threadDisplayOverride = ref(new Map())
|
||||||
const threadDisplayDefault = computed(() => {
|
const threadDisplayDefault = computed(() => {
|
||||||
return conversation.value.reduce((map, status) => {
|
return toValue(conversation).reduce((map, status) => {
|
||||||
const { id } = status
|
const { id } = status
|
||||||
const depth = ancestors.value.get(id).size
|
const depth = ancestors.value.get(id).size
|
||||||
|
|
||||||
const state = (() => {
|
const state = (() => {
|
||||||
|
console.log(toValue(currentAncestors))
|
||||||
if (depth - currentDepth.value <= maxDepthToShowByDefault.value) {
|
if (depth - currentDepth.value <= maxDepthToShowByDefault.value) {
|
||||||
return 'showing'
|
return 'showing'
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -107,5 +113,9 @@ export function useTreeConversationTopology(conversation, replies, current) {
|
||||||
threadDisplay,
|
threadDisplay,
|
||||||
showThreadRecursively,
|
showThreadRecursively,
|
||||||
resetThreadDisplay,
|
resetThreadDisplay,
|
||||||
|
|
||||||
|
// For testing
|
||||||
|
topLevelIds,
|
||||||
|
ancestors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
163
test/unit/specs/composables/useTreeConversationTopology.spec.js
Normal file
163
test/unit/specs/composables/useTreeConversationTopology.spec.js
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
import { createTestingPinia } from '@pinia/testing'
|
||||||
|
import { setActivePinia } from 'pinia'
|
||||||
|
|
||||||
|
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||||
|
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||||
|
|
||||||
|
import { useTreeConversationTopology } from 'src/composables/useTreeConversationTopology.js'
|
||||||
|
|
||||||
|
describe('useTreeConversationTopology', () => {
|
||||||
|
const conversation = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
in_reply_to_status_id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
in_reply_to_status_id: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
in_reply_to_status_id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
in_reply_to_status_id: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
in_reply_to_status_id: 3,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const replies = new Map([
|
||||||
|
[1, new Set([{ id: 2 }, { id: 4 }])],
|
||||||
|
[2, new Set([{ id: 3 }])],
|
||||||
|
[3, new Set([{ id: 6 }])],
|
||||||
|
[4, new Set([{ id: 5 }])],
|
||||||
|
[6, new Set([])],
|
||||||
|
])
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
setActivePinia(createTestingPinia())
|
||||||
|
useStatusesStore().allStatuses = new Map(
|
||||||
|
conversation.map(({ id }) => [id, { id }]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should form a correct topology', () => {
|
||||||
|
const { topLevel, ancestors, currentAncestors } =
|
||||||
|
useTreeConversationTopology(conversation, null, 3)
|
||||||
|
|
||||||
|
expect(ancestors.value).to.eql(
|
||||||
|
new Map([
|
||||||
|
[1, new Set()],
|
||||||
|
[2, new Set([1])],
|
||||||
|
[3, new Set([2, 1])],
|
||||||
|
[4, new Set([1])],
|
||||||
|
[5, new Set([4, 1])],
|
||||||
|
[6, new Set([3, 2, 1])],
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
expect(currentAncestors.value).to.eql([{ id: 1 }, { id: 2 }])
|
||||||
|
expect(topLevel.value.map(({ id }) => id)).to.eql([1])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('ThreadDisplay', () => {
|
||||||
|
it('should set default ThreadDisplay with maxDepth 3', () => {
|
||||||
|
useMergedConfigStore().mergedConfig = { maxDepthInThread: 3 }
|
||||||
|
|
||||||
|
const { threadDisplay } = useTreeConversationTopology(conversation)
|
||||||
|
|
||||||
|
expect(threadDisplay.value).to.eql(
|
||||||
|
new Map([
|
||||||
|
[1, 'showing'],
|
||||||
|
[2, 'showing'],
|
||||||
|
[3, 'hidden'],
|
||||||
|
[4, 'showing'],
|
||||||
|
[5, 'hidden'],
|
||||||
|
[6, 'hidden'],
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should set default ThreadDisplay with maxDepth 6', () => {
|
||||||
|
useMergedConfigStore().mergedConfig = { maxDepthInThread: 6 }
|
||||||
|
|
||||||
|
const { threadDisplay } = useTreeConversationTopology(conversation)
|
||||||
|
|
||||||
|
expect(threadDisplay.value).to.eql(
|
||||||
|
new Map([
|
||||||
|
[1, 'showing'],
|
||||||
|
[2, 'showing'],
|
||||||
|
[3, 'showing'],
|
||||||
|
[4, 'showing'],
|
||||||
|
[5, 'showing'],
|
||||||
|
[6, 'showing'],
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should set default ThreadDisplay with maxDepth 3 && current depth being 3', () => {
|
||||||
|
useMergedConfigStore().mergedConfig = { maxDepthInThread: 3 }
|
||||||
|
|
||||||
|
const { threadDisplay } = useTreeConversationTopology(
|
||||||
|
conversation,
|
||||||
|
null,
|
||||||
|
4,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(threadDisplay.value).to.eql(
|
||||||
|
new Map([
|
||||||
|
[1, 'showing'],
|
||||||
|
[2, 'showing'],
|
||||||
|
[3, 'showing'],
|
||||||
|
[4, 'showing'],
|
||||||
|
[5, 'showing'],
|
||||||
|
[6, 'hidden'],
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should recursively expand thread when calling showThreadRecursively', () => {
|
||||||
|
useMergedConfigStore().mergedConfig = { maxDepthInThread: 3 }
|
||||||
|
|
||||||
|
const { threadDisplay, showThreadRecursively } =
|
||||||
|
useTreeConversationTopology(conversation, replies, 1)
|
||||||
|
|
||||||
|
showThreadRecursively(3)
|
||||||
|
expect(threadDisplay.value).to.eql(
|
||||||
|
new Map([
|
||||||
|
[1, 'showing'],
|
||||||
|
[2, 'showing'],
|
||||||
|
[3, 'showing'],
|
||||||
|
[4, 'showing'],
|
||||||
|
[5, 'hidden'],
|
||||||
|
[6, 'showing'],
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should reset thread when calling resetThreadDisplay', () => {
|
||||||
|
useMergedConfigStore().mergedConfig = { maxDepthInThread: 3 }
|
||||||
|
|
||||||
|
const { threadDisplay, showThreadRecursively, resetThreadDisplay } =
|
||||||
|
useTreeConversationTopology(conversation, replies, 1)
|
||||||
|
|
||||||
|
showThreadRecursively(3)
|
||||||
|
resetThreadDisplay()
|
||||||
|
expect(threadDisplay.value).to.eql(
|
||||||
|
new Map([
|
||||||
|
[1, 'showing'],
|
||||||
|
[2, 'showing'],
|
||||||
|
[3, 'hidden'],
|
||||||
|
[4, 'showing'],
|
||||||
|
[5, 'hidden'],
|
||||||
|
[6, 'hidden'],
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue