Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// ====== tests
import { nextTick } from 'vue'
import { mount } from '../framework'
import { FilterPosts } from '../app/FilterPosts'
describe('FilterPosts', () => {
it('renders today posts by default', async () => {
const wrapper = mount(FilterPosts)
expect(wrapper.find('.post').text()).toBe('In the news today...')
expect(wrapper.findAll('.post')).toHaveLength(1)
})
it('toggles the filter', async () => {
const wrapper = mount(FilterPosts)
wrapper.findAll('button')[1].trigger('click')
await nextTick()
expect(wrapper.findAll('.post')).toHaveLength(2)
expect(wrapper.find('h1').text()).toBe('Posts from this week')
expect(wrapper.findAll('.post')[0].text()).toBe('In the news today...')
expect(wrapper.findAll('.post')[1].text()).toBe('In the news this week...')
})
})
// ====== component
import { defineComponent, ref, h, computed } from 'vue'
import moment, { Moment } from 'moment'
interface Post {
id: number
title: string
created: Moment
}
const posts: Post[] = [
{
id: 1,
title: 'In the news today...',
created: moment()
},
{
id: 2,
title: 'In the news this week...',
created: moment().add(4 ,'days')
}
]
export const NewsPost = defineComponent({
props: {
post: {
type: Object as () => Post,
required: true
},
},
setup(props) {
return () => h('div', { className: 'post' }, props.post.title)
}
})
type FilterPeriod = 'today' | 'this week'
const filters: FilterPeriod[] = ['today', 'this week']
export const Filter = defineComponent({
props: {
filter: {
type: String as () => FilterPeriod,
required: true
}
},
setup(props, ctx) {
return () => h('button', { onClick: () => ctx.emit('select', props.filter) }, props.filter)
}
})
export const FilterPosts = defineComponent({
setup() {
const selectedFilter = ref<FilterPeriod>('today')
const filteredPosts = computed(() => {
return posts.filter(post => {
if (selectedFilter.value === 'today') {
return post.created.isSameOrBefore(moment().add(0, 'days'))
}
if (selectedFilter.value === 'this week') {
return post.created.isSameOrBefore(moment().add(1, 'week'))
}
return post
})
})
return () =>
h('div',
[
h('h1', `Posts from ${selectedFilter.value}`),
filters.map(filter => h(Filter, { filter, onSelect: filter => selectedFilter.value = filter })),
filteredPosts.value.map(post => h(NewsPost, { post }))
]
)
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.