1// @vitest-environment jsdom
2
3import { expect, it, describe } from 'vitest';
4import { defineComponent, effectScope, h } from 'vue';
5import { mount } from '@vue/test-utils';
6import { Client } from '@urql/core';
7import { useClient, provideClient } from './useClient';
8
9describe('provideClient and useClient', () => {
10 it('provides client to current component instance', async () => {
11 const TestComponent = defineComponent({
12 setup() {
13 provideClient(
14 new Client({
15 url: 'test',
16 exchanges: [],
17 })
18 );
19
20 const client = useClient();
21 expect(client).toBeDefined();
22 return null;
23 },
24 });
25
26 mount(TestComponent);
27 });
28
29 it('provides client to child components via provide/inject', async () => {
30 const ChildComponent = defineComponent({
31 setup() {
32 const client = useClient();
33 expect(client).toBeDefined();
34 return () => null;
35 },
36 });
37
38 const ParentComponent = defineComponent({
39 components: { ChildComponent },
40 setup() {
41 provideClient(
42 new Client({
43 url: 'test',
44 exchanges: [],
45 })
46 );
47 return () => h(ChildComponent);
48 },
49 });
50
51 mount(ParentComponent);
52 });
53
54 it('works in effect scopes outside components', () => {
55 const scope = effectScope();
56
57 scope.run(() => {
58 provideClient(
59 new Client({
60 url: 'test',
61 exchanges: [],
62 })
63 );
64
65 const client = useClient();
66 expect(client).toBeDefined();
67 });
68 });
69
70 it('throws error when no client is provided', () => {
71 expect(() => {
72 const TestComponent = defineComponent({
73 setup() {
74 // No provideClient called
75 useClient(); // Should throw
76 return null;
77 },
78 });
79
80 mount(TestComponent);
81 }).toThrow('No urql Client was provided');
82 });
83
84 it('throws error when called outside reactive context', () => {
85 expect(() => {
86 // Called outside any component or scope
87 useClient();
88 }).toThrow('reactive context');
89 });
90});