diff --git a/test/customElements/renderCustomElements.test.ts b/test/customElements/renderCustomElements.test.ts
index cf66f6f..41fb86e 100644
--- a/test/customElements/renderCustomElements.test.ts
+++ b/test/customElements/renderCustomElements.test.ts
@@ -1,152 +1,164 @@
+// test/customElements/renderCustomElements.test.ts
// @vitest-environment nuxt
-import { describe, it, expect, vi } from 'vitest'
+import { describe, it, expect } from 'vitest'
+import { mountSuspended } from '@nuxt/test-utils/runtime'
+import { defineComponent } from 'vue'
import { useDrupalCe } from '../../src/runtime/composables/useDrupalCe'
-// useDrupalCe uses Nuxt's module system with '#app' and '#imports' virtual modules.
-// For unit testing, we need to mock these, but we want to use real Vue features for what we're testing
-
-// Mock #app which provides Nuxt's app utilities (not used by renderCustomElements)
-vi.mock('#app', () => ({
- callWithNuxt: vi.fn(), // Used by other parts of useDrupalCe
-}))
-
-// Create a mock Vue app with component registry
-const mockComponents = new Map()
-
-// Define test components
-const TestComponent = {
- props: {
- foo: String
- },
- template: '
Test
'
-}
-
-const AnotherComponent = {
- props: {
- baz: String
- },
- template: 'Another
'
-}
-
-// Register components in our mock registry
-mockComponents.set('TestComponent', TestComponent)
-mockComponents.set('AnotherComponent', AnotherComponent)
-
-// Mock #imports which provides composables and Vue utilities
-vi.mock('#imports', () => ({
- h: (name: string) => ({
- name,
- __isComponent: true // some marker to identify it's a component
- }),
- useNuxtApp: () => ({
- vueApp: {
- component: (name) => mockComponents.get(name)
- }
- }),
- // Mock the rest that's only used by other parts of useDrupalCe
- useRuntimeConfig: () => ({
- public: { drupalCe: {} },
- drupalCe: {}
- }),
- ref: vi.fn(),
- computed: vi.fn(),
-}))
-
describe('renderCustomElements', () => {
const { renderCustomElements } = useDrupalCe()
- it('handles null input', () => {
- const result = renderCustomElements(null)
- expect(result).toBe(null)
+ // Define reusable test components
+ const TestComponent = defineComponent({
+ props: {
+ foo: String
+ },
+ template: 'Test Component: {{ foo || "" }}
'
})
- it('handles undefined input', () => {
- const result = renderCustomElements(undefined)
- expect(result).toBe(null)
+ const AnotherComponent = defineComponent({
+ props: {
+ bar: String
+ },
+ template: 'Another Component: {{ bar }}
'
})
- it('handles empty object input', () => {
- const result = renderCustomElements({})
- expect(result).toBe(null)
- })
+ describe('basic input handling', () => {
+ const NullRenderer = defineComponent({
+ setup() {
+ return { component: renderCustomElements(null) }
+ },
+ template: ''
+ })
- it('handles plain string input', () => {
- const result = renderCustomElements('Hello World')
- expect(result).toMatchObject({
- template: '',
- data: expect.any(Function)
+ it('should return null for empty inputs', () => {
+ expect(renderCustomElements(null)).toBe(null)
+ expect(renderCustomElements(undefined)).toBe(null)
+ expect(renderCustomElements({})).toBe(null)
})
- expect(result.data().content).toBe('Hello World')
- })
- it('handles HTML string input', () => {
- const htmlString = 'Hello World
'
- const result = renderCustomElements(htmlString)
- expect(result).toMatchObject({
- template: '',
- data: expect.any(Function)
+ it('should render nothing when component is null', async () => {
+ const wrapper = await mountSuspended(NullRenderer)
+ expect(wrapper.html()).toBe('')
})
- expect(result.data().content).toBe(htmlString)
})
- it('handles single custom element object', () => {
- const customElement = {
- element: 'test-component',
- props: { foo: 'bar' }
- }
- const result = renderCustomElements(customElement)
- expect(result).toBeTruthy()
- expect(result.type).toBe(TestComponent)
- })
+ describe('string rendering', () => {
+ it('should render plain text', async () => {
+ const TextRenderer = defineComponent({
+ setup() {
+ return { component: renderCustomElements('Hello World') }
+ },
+ template: ''
+ })
+ const wrapper = await mountSuspended(TextRenderer)
+ expect(wrapper.text()).toBe('Hello World')
+ })
- it('handles array of custom elements', () => {
- const customElements = [
- {
- element: 'test-component',
- props: { foo: 'bar' }
- },
- 'Plain text element',
- {
- element: 'another-component',
- props: { baz: 'qux' }
- }
- ]
- const result = renderCustomElements(customElements)
- expect(Array.isArray(result)).toBe(true)
- expect(result).toHaveLength(3)
+ it('should render HTML string preserving markup', async () => {
+ const htmlString = 'Hello World
'
+ const HtmlRenderer = defineComponent({
+ setup() {
+ return { component: renderCustomElements(htmlString) }
+ },
+ template: ''
+ })
+ const wrapper = await mountSuspended(HtmlRenderer)
+ expect(wrapper.html()).toContain(htmlString)
+ expect(wrapper.text()).toBe('Hello World')
+ })
+ })
- // First component
- expect(result[0].type).toBe(TestComponent)
- expect(result[0].props).toMatchObject({
- foo: 'bar'
+ describe('custom element rendering', () => {
+ it('should render a single custom element', async () => {
+ const ComponentRenderer = defineComponent({
+ components: { TestComponent },
+ setup() {
+ return { component: renderCustomElements({
+ element: 'test-component',
+ foo: 'bar'
+ })}
+ },
+ template: ''
+ })
+ const wrapper = await mountSuspended(ComponentRenderer)
+ expect(wrapper.text()).toBe('Test Component: bar')
})
+ })
- // Text element
- expect(result[1]).toMatchObject({
- template: '',
- data: expect.any(Function)
+ describe('array handling', () => {
+ it('should render array of strings', async () => {
+ const StringArrayRenderer = defineComponent({
+ setup() {
+ const content = ['Text 1', 'Text 2
']
+ return {
+ components: content.map(item => renderCustomElements(item))
+ }
+ },
+ template: '
'
+ })
+ const wrapper = await mountSuspended(StringArrayRenderer)
+ expect(wrapper.text()).toContain('Text 1')
+ expect(wrapper.text()).toContain('Text 2')
+ expect(wrapper.html()).toContain('Text 2
')
})
- expect(result[1].data().content).toBe('Plain text element')
- // Third component
- expect(result[2].type).toBe(AnotherComponent)
- expect(result[2].props).toMatchObject({
- baz: 'qux'
+ it('should render array of custom elements', async () => {
+ const ElementArrayRenderer = defineComponent({
+ components: { TestComponent, AnotherComponent },
+ setup() {
+ const content = [
+ { element: 'test-component', foo: 'one' },
+ { element: 'another-component', bar: 'two' }
+ ]
+ return {
+ components: content.map(item => renderCustomElements(item))
+ }
+ },
+ template: '
'
+ })
+ const wrapper = await mountSuspended(ElementArrayRenderer)
+ expect(wrapper.text()).toContain('Test Component: one')
+ expect(wrapper.text()).toContain('Another Component: two')
})
})
- it('handles array with only string elements', () => {
- const elements = ['Text 1', 'HTML text
']
- const result = renderCustomElements(elements)
- expect(Array.isArray(result)).toBe(true)
- expect(result).toHaveLength(2)
+ describe('edge cases', () => {
+ it('should handle malformed element objects', async () => {
+ const MalformedRenderer = defineComponent({
+ components: { TestComponent },
+ setup() {
+ return { component: renderCustomElements({ element: 'test-component' })}
+ },
+ template: ''
+ })
+ const wrapper = await mountSuspended(MalformedRenderer)
+ expect(wrapper.text()).toBe('Test Component:')
+ })
+
+ it('should handle nonexistent components', async () => {
+ const NonexistentRenderer = defineComponent({
+ setup() {
+ return { component: renderCustomElements({
+ element: 'nonexistent-component',
+ foo: 'bar'
+ })}
+ },
+ template: ''
+ })
+ const wrapper = await mountSuspended(NonexistentRenderer)
+ expect(wrapper.html()).toBe('')
+ })
- result.forEach((component, index) => {
- expect(component).toMatchObject({
- template: '',
- data: expect.any(Function)
+ it('should handle empty arrays', async () => {
+ const EmptyArrayRenderer = defineComponent({
+ setup() {
+ return { component: renderCustomElements([]) }
+ },
+ template: ''
})
- expect(component.data().content).toBe(elements[index])
+ const wrapper = await mountSuspended(EmptyArrayRenderer)
+ expect(wrapper.html()).toBe('')
})
})
})