wwf
8 天以前 938c3e5a587ce950a94964ea509b9e7f8834dfae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
import {
  asyncRunSafe,
  canFindTool,
  correctModelProvider,
  correctToolProvider,
  fetchWithRetry,
  getPurifyHref,
  getTextWidthWithCanvas,
  randomString,
  removeSpecificQueryParam,
  sleep,
} from './index'
 
describe('sleep', () => {
  it('should wait for the specified time', async () => {
    const timeVariance = 10
    const sleepTime = 100
    const start = Date.now()
    await sleep(sleepTime)
    const elapsed = Date.now() - start
    expect(elapsed).toBeGreaterThanOrEqual(sleepTime - timeVariance)
  })
})
 
describe('asyncRunSafe', () => {
  it('should return [null, result] when promise resolves', async () => {
    const result = await asyncRunSafe(Promise.resolve('success'))
    expect(result).toEqual([null, 'success'])
  })
 
  it('should return [error] when promise rejects', async () => {
    const error = new Error('test error')
    const result = await asyncRunSafe(Promise.reject(error))
    expect(result).toEqual([error])
  })
 
  it('should return [Error] when promise rejects with undefined', async () => {
    // eslint-disable-next-line prefer-promise-reject-errors
    const result = await asyncRunSafe(Promise.reject())
    expect(result[0]).toBeInstanceOf(Error)
    expect(result[0]?.message).toBe('unknown error')
  })
})
 
describe('getTextWidthWithCanvas', () => {
  let originalCreateElement: typeof document.createElement
 
  beforeEach(() => {
    // Store original implementation
    originalCreateElement = document.createElement
 
    // Mock canvas and context
    const measureTextMock = jest.fn().mockReturnValue({ width: 100 })
    const getContextMock = jest.fn().mockReturnValue({
      measureText: measureTextMock,
      font: '',
    })
 
    document.createElement = jest.fn().mockReturnValue({
      getContext: getContextMock,
    })
  })
 
  afterEach(() => {
    // Restore original implementation
    document.createElement = originalCreateElement
  })
 
  it('should return the width of text', () => {
    const width = getTextWidthWithCanvas('test text')
    expect(width).toBe(100)
  })
 
  it('should return 0 if context is not available', () => {
    // Override mock for this test
    document.createElement = jest.fn().mockReturnValue({
      getContext: () => null,
    })
 
    const width = getTextWidthWithCanvas('test text')
    expect(width).toBe(0)
  })
})
 
describe('randomString', () => {
  it('should generate string of specified length', () => {
    const result = randomString(10)
    expect(result.length).toBe(10)
  })
 
  it('should only contain valid characters', () => {
    const result = randomString(100)
    const validChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'
    for (const char of result)
      expect(validChars).toContain(char)
  })
 
  it('should generate different strings on consecutive calls', () => {
    const result1 = randomString(20)
    const result2 = randomString(20)
    expect(result1).not.toEqual(result2)
  })
})
 
describe('getPurifyHref', () => {
  it('should return empty string for falsy input', () => {
    expect(getPurifyHref('')).toBe('')
    expect(getPurifyHref(undefined as any)).toBe('')
  })
 
  it('should escape HTML characters', () => {
    expect(getPurifyHref('<script>alert("xss")</script>')).not.toContain('<script>')
  })
})
 
describe('fetchWithRetry', () => {
  it('should return successfully on first try', async () => {
    const successData = { status: 'success' }
    const promise = Promise.resolve(successData)
 
    const result = await fetchWithRetry(promise)
 
    expect(result).toEqual([null, successData])
  })
 
  // it('should retry and succeed on second attempt', async () => {
  //   let attemptCount = 0
  //   const mockFn = new Promise((resolve, reject) => {
  //     attemptCount++
  //     if (attemptCount === 1)
  //       reject(new Error('First attempt failed'))
  //     else
  //       resolve('success')
  //   })
 
  //   const result = await fetchWithRetry(mockFn)
 
  //   expect(result).toEqual([null, 'success'])
  //   expect(attemptCount).toBe(2)
  // })
 
  // it('should stop after max retries and return last error', async () => {
  //   const testError = new Error('Test error')
  //   const promise = Promise.reject(testError)
 
  //   const result = await fetchWithRetry(promise, 2)
 
  //   expect(result).toEqual([testError])
  // })
 
  // it('should handle non-Error rejection with custom error', async () => {
  //   const stringError = 'string error message'
  //   const promise = Promise.reject(stringError)
 
  //   const result = await fetchWithRetry(promise, 0)
 
  //   expect(result[0]).toBeInstanceOf(Error)
  //   expect(result[0]?.message).toBe('unknown error')
  // })
 
  // it('should use default 3 retries when retries parameter is not provided', async () => {
  //   let attempts = 0
  //   const mockFn = () => new Promise((resolve, reject) => {
  //     attempts++
  //     reject(new Error(`Attempt ${attempts} failed`))
  //   })
 
  //   await fetchWithRetry(mockFn())
 
  //   expect(attempts).toBe(4) // Initial attempt + 3 retries
  // })
})
 
describe('correctModelProvider', () => {
  it('should return empty string for falsy input', () => {
    expect(correctModelProvider('')).toBe('')
  })
 
  it('should return the provider if it already contains a slash', () => {
    expect(correctModelProvider('company/model')).toBe('company/model')
  })
 
  it('should format google provider correctly', () => {
    expect(correctModelProvider('google')).toBe('langgenius/gemini/google')
  })
 
  it('should format standard providers correctly', () => {
    expect(correctModelProvider('openai')).toBe('langgenius/openai/openai')
  })
})
 
describe('correctToolProvider', () => {
  it('should return empty string for falsy input', () => {
    expect(correctToolProvider('')).toBe('')
  })
 
  it('should return the provider if toolInCollectionList is true', () => {
    expect(correctToolProvider('any-provider', true)).toBe('any-provider')
  })
 
  it('should return the provider if it already contains a slash', () => {
    expect(correctToolProvider('company/tool')).toBe('company/tool')
  })
 
  it('should format special tool providers correctly', () => {
    expect(correctToolProvider('stepfun')).toBe('langgenius/stepfun_tool/stepfun')
    expect(correctToolProvider('jina')).toBe('langgenius/jina_tool/jina')
  })
 
  it('should format standard tool providers correctly', () => {
    expect(correctToolProvider('standard')).toBe('langgenius/standard/standard')
  })
})
 
describe('canFindTool', () => {
  it('should match when IDs are identical', () => {
    expect(canFindTool('tool-id', 'tool-id')).toBe(true)
  })
 
  it('should match when provider ID is formatted with standard pattern', () => {
    expect(canFindTool('langgenius/tool-id/tool-id', 'tool-id')).toBe(true)
  })
 
  it('should match when provider ID is formatted with tool pattern', () => {
    expect(canFindTool('langgenius/tool-id_tool/tool-id', 'tool-id')).toBe(true)
  })
 
  it('should not match when IDs are completely different', () => {
    expect(canFindTool('provider-a', 'tool-b')).toBe(false)
  })
})
 
describe('removeSpecificQueryParam', () => {
  let originalLocation: Location
  let originalReplaceState: typeof window.history.replaceState
 
  beforeEach(() => {
    originalLocation = window.location
    originalReplaceState = window.history.replaceState
 
    const mockUrl = new URL('https://example.com?param1=value1&param2=value2&param3=value3')
 
    // Mock window.location using defineProperty to handle URL properly
    delete (window as any).location
    Object.defineProperty(window, 'location', {
      writable: true,
      value: {
        ...originalLocation,
        href: mockUrl.href,
        search: mockUrl.search,
        toString: () => mockUrl.toString(),
      },
    })
 
    window.history.replaceState = jest.fn()
  })
 
  afterEach(() => {
    Object.defineProperty(window, 'location', {
      writable: true,
      value: originalLocation,
    })
    window.history.replaceState = originalReplaceState
  })
 
  it('should remove a single query parameter', () => {
    removeSpecificQueryParam('param2')
    expect(window.history.replaceState).toHaveBeenCalledTimes(1)
    const replaceStateCall = (window.history.replaceState as jest.Mock).mock.calls[0]
    expect(replaceStateCall[0]).toBe(null)
    expect(replaceStateCall[1]).toBe('')
    expect(replaceStateCall[2]).toMatch(/param1=value1/)
    expect(replaceStateCall[2]).toMatch(/param3=value3/)
    expect(replaceStateCall[2]).not.toMatch(/param2=value2/)
  })
 
  it('should remove multiple query parameters', () => {
    removeSpecificQueryParam(['param1', 'param3'])
    expect(window.history.replaceState).toHaveBeenCalledTimes(1)
    const replaceStateCall = (window.history.replaceState as jest.Mock).mock.calls[0]
    expect(replaceStateCall[2]).toMatch(/param2=value2/)
    expect(replaceStateCall[2]).not.toMatch(/param1=value1/)
    expect(replaceStateCall[2]).not.toMatch(/param3=value3/)
  })
 
  it('should handle non-existent parameters gracefully', () => {
    removeSpecificQueryParam('nonexistent')
 
    expect(window.history.replaceState).toHaveBeenCalledTimes(1)
    const replaceStateCall = (window.history.replaceState as jest.Mock).mock.calls[0]
    expect(replaceStateCall[2]).toMatch(/param1=value1/)
    expect(replaceStateCall[2]).toMatch(/param2=value2/)
    expect(replaceStateCall[2]).toMatch(/param3=value3/)
  })
})