Skip to content

Commit b538682

Browse files
authored
Refactor argument resolver to address edge cases (#1259)
1 parent 2974f00 commit b538682

File tree

4 files changed

+291
-43
lines changed

4 files changed

+291
-43
lines changed

.changeset/fast-lions-kick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-next': patch
3+
---
4+
5+
Add support for more argument resolver edge cases

packages/browser/src/core/analytics/interfaces.ts

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,169 @@ export interface AnalyticsClassic extends AnalyticsClassicStubs {
7777
* Interface implemented by concrete Analytics class (commonly accessible if you use "await" on AnalyticsBrowser.load())
7878
*/
7979
export interface AnalyticsCore extends CoreAnalytics {
80+
/**
81+
* Tracks an event.
82+
* @param args - Event parameters.
83+
* @example
84+
* ```ts
85+
* analytics.track('Event Name', {
86+
* property1: 'value1',
87+
* property2: 'value2'
88+
* });
89+
* ```
90+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#track
91+
* @returns A promise that resolves to a dispatched event.
92+
*/
8093
track(...args: EventParams): Promise<DispatchedEvent>
94+
95+
/**
96+
* Tracks a page view.
97+
* @param args - `[category], [name], [properties], [options], [callback]`
98+
* @example
99+
* ```ts
100+
* analytics.page('My Category', 'Pricing', {
101+
* title: 'My Overridden Title',
102+
* myExtraProp: 'foo'
103+
* })
104+
*
105+
* analytics.page('Pricing', {
106+
* title: 'My Overridden Title',
107+
* myExtraProp: 'foo'
108+
* });
109+
* ```
110+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#page
111+
* @returns A promise that resolves to a dispatched event.
112+
*/
81113
page(...args: PageParams): Promise<DispatchedEvent>
114+
115+
/**
116+
* Identifies a user.
117+
* @param args - Identify parameters.
118+
* @example
119+
* ```ts
120+
* analytics.identify('userId123', {
121+
* email: 'user@example.com',
122+
* name: 'John Doe'
123+
* });
124+
* ```
125+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#identify
126+
* @returns A promise that resolves to a dispatched event.
127+
*/
82128
identify(...args: IdentifyParams): Promise<DispatchedEvent>
129+
130+
/**
131+
* Gets the group.
132+
* @returns The group.
133+
*/
83134
group(): Group
135+
136+
/**
137+
* Sets the group.
138+
* @param args - Group parameters.
139+
* @example
140+
* ```ts
141+
* analytics.group('groupId123', {
142+
* name: 'Company Inc.',
143+
* industry: 'Software'
144+
* });
145+
* ```
146+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#group
147+
* @returns A promise that resolves to a dispatched event.
148+
*/
84149
group(...args: GroupParams): Promise<DispatchedEvent>
150+
151+
/**
152+
* Creates an alias for a user.
153+
* @param args - Alias parameters.
154+
* @example
155+
* ```ts
156+
* analytics.alias('newUserId123', 'oldUserId456');
157+
* ```
158+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#alias
159+
* @returns A promise that resolves to a dispatched event.
160+
*/
85161
alias(...args: AliasParams): Promise<DispatchedEvent>
162+
163+
/**
164+
* Tracks a screen view.
165+
* @param args - Page parameters.
166+
* @example
167+
* ```ts
168+
* analytics.screen('Home Screen', {
169+
* title: 'Home',
170+
* section: 'Main'
171+
* });
172+
* ```
173+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#screen
174+
* @returns A promise that resolves to a dispatched event.
175+
*/
86176
screen(...args: PageParams): Promise<DispatchedEvent>
177+
178+
/**
179+
* Registers plugins.
180+
* @param plugins - Plugins to register.
181+
* @example
182+
* ```ts
183+
* analytics.register(plugin1, plugin2);
184+
* ```
185+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#register
186+
* @returns A promise that resolves to the context.
187+
*/
87188
register(...plugins: Plugin[]): Promise<Context>
189+
190+
/**
191+
* Deregisters plugins.
192+
* @param plugins - Plugin names to deregister.
193+
* @example
194+
* ```ts
195+
* analytics.deregister('plugin1', 'plugin2');
196+
* ```
197+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#deregister
198+
* @returns A promise that resolves to the context.
199+
*/
88200
deregister(...plugins: string[]): Promise<Context>
201+
202+
/**
203+
* Gets the user.
204+
* @returns The user.
205+
*/
89206
user(): User
207+
208+
/**
209+
* The version of the analytics library.
210+
*/
90211
readonly VERSION: string
91212
}
92213

93214
/**
94215
* Interface implemented by AnalyticsBrowser (buffered version of analytics) (commonly accessible through AnalyticsBrowser.load())
95216
*/
96-
export type AnalyticsBrowserCore = Omit<AnalyticsCore, 'group' | 'user'> & {
217+
export interface AnalyticsBrowserCore
218+
extends Omit<AnalyticsCore, 'group' | 'user'> {
219+
/**
220+
* Gets the group.
221+
* @returns A promise that resolves to the group.
222+
*/
97223
group(): Promise<Group>
224+
225+
/**
226+
* Sets the group.
227+
* @param args - Group parameters.
228+
* @example
229+
* ```ts
230+
* analytics.group('groupId123', {
231+
* name: 'Company Inc.',
232+
* industry: 'Software'
233+
* });
234+
* ```
235+
* @link https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#group
236+
* @returns A promise that resolves to a dispatched event.
237+
*/
98238
group(...args: GroupParams): Promise<DispatchedEvent>
239+
240+
/**
241+
* Gets the user.
242+
* @returns A promise that resolves to the user.
243+
*/
99244
user(): Promise<User>
100245
}

packages/browser/src/core/arguments-resolver/__tests__/index.test.ts

Lines changed: 112 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
resolvePageArguments,
44
resolveUserArguments,
55
resolveAliasArguments,
6-
} from '../'
6+
} from '../index'
77
import { Callback } from '../../events'
88
import { User } from '../../user'
99

@@ -219,6 +219,37 @@ describe(resolvePageArguments, () => {
219219
},
220220
},
221221
})
222+
expect(properties).toEqual({})
223+
})
224+
225+
it('should accept (category, name)', () => {
226+
const [category, name, properties, options, cb] = resolvePageArguments(
227+
'category',
228+
'name'
229+
)
230+
231+
expect(name).toEqual('name')
232+
expect(category).toEqual('category')
233+
expect(properties).toEqual({})
234+
expect(options).toEqual({})
235+
expect(cb).toEqual(undefined)
236+
})
237+
238+
it('should accept (category, name, properties, options, cb)', () => {
239+
const fn = jest.fn()
240+
const [category, name, properties, options, cb] = resolvePageArguments(
241+
'foo',
242+
'name',
243+
bananaPhone,
244+
baseOptions,
245+
fn
246+
)
247+
248+
expect(category).toEqual('foo')
249+
expect(name).toEqual('name')
250+
expect(properties).toEqual(bananaPhone)
251+
expect(options).toEqual(baseOptions)
252+
expect(cb).toEqual(fn)
222253
})
223254

224255
test('should accept (category, name, properties, callback)', () => {
@@ -254,52 +285,48 @@ describe(resolvePageArguments, () => {
254285
expect(options).toEqual({})
255286
})
256287

257-
it('should accept (name, properties, options, callback)', () => {
258-
const fn = jest.fn()
288+
it('should accept (name, properties)', () => {
259289
const [category, name, properties, options, cb] = resolvePageArguments(
260290
'name',
261-
bananaPhone,
262-
baseOptions,
263-
fn
291+
bananaPhone
264292
)
265293

266-
expect(category).toEqual(null)
267294
expect(name).toEqual('name')
295+
expect(category).toEqual(null)
268296
expect(properties).toEqual(bananaPhone)
269-
expect(options).toEqual(baseOptions)
270-
expect(cb).toEqual(fn)
297+
expect(options).toEqual({})
298+
expect(cb).toEqual(undefined)
271299
})
272300

273-
it('should accept (name, properties, callback)', () => {
301+
it('should accept (name, properties, options, callback)', () => {
274302
const fn = jest.fn()
275303
const [category, name, properties, options, cb] = resolvePageArguments(
276304
'name',
277305
bananaPhone,
306+
baseOptions,
278307
fn
279308
)
280309

281310
expect(category).toEqual(null)
282311
expect(name).toEqual('name')
283312
expect(properties).toEqual(bananaPhone)
313+
expect(options).toEqual(baseOptions)
284314
expect(cb).toEqual(fn)
285-
expect(options).toEqual({})
286315
})
287316

288-
it('should accept (category, name, properties, options, cb)', () => {
317+
it('should accept (name, properties, callback)', () => {
289318
const fn = jest.fn()
290319
const [category, name, properties, options, cb] = resolvePageArguments(
291-
'foo',
292320
'name',
293321
bananaPhone,
294-
baseOptions,
295322
fn
296323
)
297324

298-
expect(category).toEqual('foo')
325+
expect(category).toEqual(null)
299326
expect(name).toEqual('name')
300327
expect(properties).toEqual(bananaPhone)
301-
expect(options).toEqual(baseOptions)
302328
expect(cb).toEqual(fn)
329+
expect(options).toEqual({})
303330
})
304331

305332
it('should accept (name, callback)', () => {
@@ -348,7 +375,7 @@ describe(resolvePageArguments, () => {
348375
expect(category).toEqual(null)
349376
})
350377

351-
test('should accept (category = null, name, properties, options, callback)', () => {
378+
test('should accept (null, name, properties, options, callback)', () => {
352379
const fn = jest.fn()
353380
const [category, name, properties, options, cb] = resolvePageArguments(
354381
null,
@@ -365,6 +392,64 @@ describe(resolvePageArguments, () => {
365392
expect(cb).toEqual(fn)
366393
})
367394

395+
test('should accept (name, null, properties, options, callback)', () => {
396+
const fn = jest.fn()
397+
const [category, name, properties, options, cb] = resolvePageArguments(
398+
'name',
399+
null,
400+
bananaPhone,
401+
baseOptions,
402+
fn
403+
)
404+
405+
expect(category).toEqual(null)
406+
expect(name).toEqual('name')
407+
expect(properties).toEqual(bananaPhone)
408+
expect(options).toEqual(baseOptions)
409+
expect(cb).toEqual(fn)
410+
})
411+
412+
test('should accept (name, null, properties)', () => {
413+
const [category, name, properties, options] = resolvePageArguments(
414+
'name',
415+
null,
416+
bananaPhone
417+
)
418+
419+
expect(name).toEqual('name')
420+
expect(category).toEqual(null)
421+
expect(properties).toEqual(bananaPhone)
422+
expect(options).toEqual({})
423+
})
424+
425+
test('should accept (name, null, null, options)', () => {
426+
const [category, name, properties, options] = resolvePageArguments(
427+
'name',
428+
null,
429+
null,
430+
baseOptions
431+
)
432+
433+
expect(name).toEqual('name')
434+
expect(category).toEqual(null)
435+
expect(properties).toEqual({})
436+
expect(options).toEqual(baseOptions)
437+
})
438+
439+
test('should accept (null, null, properties)', () => {
440+
const [category, name, properties, options, cb] = resolvePageArguments(
441+
null,
442+
null,
443+
bananaPhone
444+
)
445+
446+
expect(category).toEqual(null)
447+
expect(name).toEqual(null)
448+
expect(properties).toEqual(bananaPhone)
449+
expect(options).toEqual({})
450+
expect(cb).toEqual(undefined)
451+
})
452+
368453
test('should accept (null, null, properties, options, callback)', () => {
369454
const fn = jest.fn()
370455
const [category, name, properties, options, cb] = resolvePageArguments(
@@ -425,6 +510,16 @@ describe(resolvePageArguments, () => {
425510
expect(options).toEqual({})
426511
expect(cb).toEqual(fn)
427512
})
513+
514+
test('should accept (null, null, null, null, callback)', () => {
515+
const fn = jest.fn()
516+
const [category, name, properties, options, cb] = resolvePageArguments(fn)
517+
expect(category).toEqual(null)
518+
expect(name).toEqual(null)
519+
expect(properties).toEqual({})
520+
expect(options).toEqual({})
521+
expect(cb).toEqual(fn)
522+
})
428523
})
429524

430525
describe(resolveUserArguments, () => {

0 commit comments

Comments
 (0)