Skip to content

Commit cea78ba

Browse files
committed
adjust tests
1 parent e21944b commit cea78ba

File tree

2 files changed

+235
-85
lines changed

2 files changed

+235
-85
lines changed

packages/core/src/scope.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,12 @@ export class Scope {
335335
/**
336336
* Sets an attribute onto the scope.
337337
*
338-
* TODO:
339-
* Currently, these attributes are not applied to any telemetry data but they will be in the future.
338+
* These attributes are currently only applied to logs.
339+
* In the future, they will be applied to metrics and spans.
340+
*
341+
* Important: For now, only strings, numbers and boolean attributes are supported, despite types allowing for
342+
* more complex attribute types. We'll add this support in the future but already specify the wider type to
343+
* avoid a breaking change in the future.
340344
*
341345
* @param key - The attribute key.
342346
* @param value - the attribute value. You can either pass in a raw value, or an attribute
@@ -345,7 +349,6 @@ export class Scope {
345349
* @example
346350
* ```typescript
347351
* scope.setAttribute('is_admin', true);
348-
* scope.setAttribute('clicked_products', [130, 554, 292]);
349352
* scope.setAttribute('render_duration', { value: 'render_duration', unit: 'ms' });
350353
* ```
351354
*/

packages/core/test/lib/attributes.test.ts

Lines changed: 229 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,111 +2,258 @@ import { describe, expect, it } from 'vitest';
22
import { attributeValueToTypedAttributeValue, isAttributeObject } from '../../src/attributes';
33

44
describe('attributeValueToTypedAttributeValue', () => {
5-
describe('primitive values', () => {
6-
it('converts a string value to a typed attribute value', () => {
7-
const result = attributeValueToTypedAttributeValue('test');
8-
expect(result).toStrictEqual({
9-
value: 'test',
10-
type: 'string',
5+
describe('without fallback (default behavior)', () => {
6+
describe('valid primitive values', () => {
7+
it('converts a string value to a typed attribute value', () => {
8+
const result = attributeValueToTypedAttributeValue('test');
9+
expect(result).toStrictEqual({
10+
value: 'test',
11+
type: 'string',
12+
});
1113
});
12-
});
1314

14-
it('converts an interger number value to a typed attribute value', () => {
15-
const result = attributeValueToTypedAttributeValue(42);
16-
expect(result).toStrictEqual({
17-
value: 42,
18-
type: 'integer',
15+
it('converts an integer number value to a typed attribute value', () => {
16+
const result = attributeValueToTypedAttributeValue(42);
17+
expect(result).toStrictEqual({
18+
value: 42,
19+
type: 'integer',
20+
});
1921
});
20-
});
2122

22-
it('converts a double number value to a typed attribute value', () => {
23-
const result = attributeValueToTypedAttributeValue(42.34);
24-
expect(result).toStrictEqual({
25-
value: 42.34,
26-
type: 'double',
23+
it('converts a double number value to a typed attribute value', () => {
24+
const result = attributeValueToTypedAttributeValue(42.34);
25+
expect(result).toStrictEqual({
26+
value: 42.34,
27+
type: 'double',
28+
});
2729
});
28-
});
2930

30-
it('converts a boolean value to a typed attribute value', () => {
31-
const result = attributeValueToTypedAttributeValue(true);
32-
expect(result).toStrictEqual({
33-
value: true,
34-
type: 'boolean',
31+
it('converts a boolean value to a typed attribute value', () => {
32+
const result = attributeValueToTypedAttributeValue(true);
33+
expect(result).toStrictEqual({
34+
value: true,
35+
type: 'boolean',
36+
});
3537
});
3638
});
37-
});
3839

39-
describe('arrays', () => {
40-
it.each([
41-
['foo', 'bar'],
42-
[1, 2, 3],
43-
[true, false, true],
44-
[1, 'foo', true],
45-
{ foo: 'bar' },
46-
() => 'test',
47-
Symbol('test'),
48-
])('returns undefined for none-primitive values (%s)', value => {
49-
const result = attributeValueToTypedAttributeValue(value);
50-
expect(result).toBeUndefined();
51-
});
52-
});
40+
describe('valid attribute objects', () => {
41+
it('converts a primitive value without unit to a typed attribute value', () => {
42+
const result = attributeValueToTypedAttributeValue({ value: 123.45 });
43+
expect(result).toStrictEqual({
44+
value: 123.45,
45+
type: 'double',
46+
});
47+
});
48+
49+
it('converts a primitive value with unit to a typed attribute value', () => {
50+
const result = attributeValueToTypedAttributeValue({ value: 123.45, unit: 'ms' });
51+
expect(result).toStrictEqual({
52+
value: 123.45,
53+
type: 'double',
54+
unit: 'ms',
55+
});
56+
});
5357

54-
describe('attribute objects without units', () => {
55-
it('converts a primitive value to a typed attribute value', () => {
56-
const result = attributeValueToTypedAttributeValue({ value: 123.45 });
57-
expect(result).toStrictEqual({
58-
value: 123.45,
59-
type: 'double',
58+
it('extracts the value property and ignores other properties', () => {
59+
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit: 'ms', bar: 'baz' });
60+
expect(result).toStrictEqual({
61+
value: 'foo',
62+
unit: 'ms',
63+
type: 'string',
64+
});
6065
});
66+
67+
it.each([1, true, null, undefined, NaN, Symbol('test'), { foo: 'bar' }])(
68+
'ignores invalid (non-string) units (%s)',
69+
unit => {
70+
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit });
71+
expect(result).toStrictEqual({
72+
value: 'foo',
73+
type: 'string',
74+
});
75+
},
76+
);
6177
});
6278

63-
it.each([
64-
['foo', 'bar'],
65-
[1, 2, 3],
66-
[true, false, true],
67-
[1, 'foo', true],
68-
{ foo: 'bar' },
69-
() => 'test',
70-
Symbol('test'),
71-
])('returns undefined for none-primitive values (%s)', value => {
72-
const result = attributeValueToTypedAttributeValue({ value });
73-
expect(result).toBeUndefined();
79+
describe('invalid values (non-primitives)', () => {
80+
it.each([
81+
['foo', 'bar'],
82+
[1, 2, 3],
83+
[true, false, true],
84+
[1, 'foo', true],
85+
{ foo: 'bar' },
86+
() => 'test',
87+
Symbol('test'),
88+
])('returns undefined for non-primitive raw values (%s)', value => {
89+
const result = attributeValueToTypedAttributeValue(value);
90+
expect(result).toBeUndefined();
91+
});
92+
93+
it.each([
94+
['foo', 'bar'],
95+
[1, 2, 3],
96+
[true, false, true],
97+
[1, 'foo', true],
98+
{ foo: 'bar' },
99+
() => 'test',
100+
Symbol('test'),
101+
])('returns undefined for non-primitive attribute object values (%s)', value => {
102+
const result = attributeValueToTypedAttributeValue({ value });
103+
expect(result).toBeUndefined();
104+
});
74105
});
75106
});
76107

77-
describe('attribute objects with units', () => {
78-
// Note: These tests only test exemplar type and fallback behaviour (see above for more cases)
79-
it('converts a primitive value to a typed attribute value', () => {
80-
const result = attributeValueToTypedAttributeValue({ value: 123.45, unit: 'ms' });
81-
expect(result).toStrictEqual({
82-
value: 123.45,
83-
type: 'double',
84-
unit: 'ms',
108+
describe('with fallback=true', () => {
109+
describe('valid primitive values', () => {
110+
it('converts a string value to a typed attribute value', () => {
111+
const result = attributeValueToTypedAttributeValue('test', true);
112+
expect(result).toStrictEqual({
113+
value: 'test',
114+
type: 'string',
115+
});
116+
});
117+
118+
it('converts an integer number value to a typed attribute value', () => {
119+
const result = attributeValueToTypedAttributeValue(42, true);
120+
expect(result).toStrictEqual({
121+
value: 42,
122+
type: 'integer',
123+
});
124+
});
125+
126+
it('converts a double number value to a typed attribute value', () => {
127+
const result = attributeValueToTypedAttributeValue(42.34, true);
128+
expect(result).toStrictEqual({
129+
value: 42.34,
130+
type: 'double',
131+
});
132+
});
133+
134+
it('converts a boolean value to a typed attribute value', () => {
135+
const result = attributeValueToTypedAttributeValue(true, true);
136+
expect(result).toStrictEqual({
137+
value: true,
138+
type: 'boolean',
139+
});
85140
});
86141
});
87142

88-
it('extracts the value property of an object with a value property', () => {
89-
// and ignores other properties.
90-
// For now we're fine with this but we may reconsider in the future.
91-
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit: 'ms', bar: 'baz' });
92-
expect(result).toStrictEqual({
93-
value: 'foo',
94-
unit: 'ms',
95-
type: 'string',
143+
describe('valid attribute objects', () => {
144+
it('converts a primitive value without unit to a typed attribute value', () => {
145+
const result = attributeValueToTypedAttributeValue({ value: 123.45 }, true);
146+
expect(result).toStrictEqual({
147+
value: 123.45,
148+
type: 'double',
149+
});
150+
});
151+
152+
it('converts a primitive value with unit to a typed attribute value', () => {
153+
const result = attributeValueToTypedAttributeValue({ value: 123.45, unit: 'ms' }, true);
154+
expect(result).toStrictEqual({
155+
value: 123.45,
156+
type: 'double',
157+
unit: 'ms',
158+
});
159+
});
160+
161+
it('extracts the value property and ignores other properties', () => {
162+
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit: 'ms', bar: 'baz' }, true);
163+
expect(result).toStrictEqual({
164+
value: 'foo',
165+
unit: 'ms',
166+
type: 'string',
167+
});
168+
});
169+
170+
it.each([1, true, null, undefined, NaN, { foo: 'bar' }])(
171+
'ignores invalid (non-string) units and preserves unit on fallback (%s)',
172+
unit => {
173+
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit }, true);
174+
expect(result).toStrictEqual({
175+
value: 'foo',
176+
type: 'string',
177+
});
178+
},
179+
);
180+
181+
it('preserves valid unit when falling back on invalid value', () => {
182+
const result = attributeValueToTypedAttributeValue({ value: { nested: 'object' }, unit: 'ms' }, true);
183+
expect(result).toStrictEqual({
184+
value: '{"nested":"object"}',
185+
type: 'string',
186+
unit: 'ms',
187+
});
96188
});
97189
});
98-
});
99190

100-
it.each([1, true, null, undefined, NaN, Symbol('test'), { foo: 'bar' }])(
101-
'ignores invalid (non-string) units (%s)',
102-
unit => {
103-
const result = attributeValueToTypedAttributeValue({ value: 'foo', unit });
104-
expect(result).toStrictEqual({
105-
value: 'foo',
106-
type: 'string',
191+
describe('invalid values (non-primitives) - stringified fallback', () => {
192+
it('stringifies string arrays', () => {
193+
const result = attributeValueToTypedAttributeValue(['foo', 'bar'], true);
194+
expect(result).toStrictEqual({
195+
value: '["foo","bar"]',
196+
type: 'string',
197+
});
107198
});
108-
},
109-
);
199+
200+
it('stringifies number arrays', () => {
201+
const result = attributeValueToTypedAttributeValue([1, 2, 3], true);
202+
expect(result).toStrictEqual({
203+
value: '[1,2,3]',
204+
type: 'string',
205+
});
206+
});
207+
208+
it('stringifies boolean arrays', () => {
209+
const result = attributeValueToTypedAttributeValue([true, false, true], true);
210+
expect(result).toStrictEqual({
211+
value: '[true,false,true]',
212+
type: 'string',
213+
});
214+
});
215+
216+
it('stringifies mixed arrays', () => {
217+
const result = attributeValueToTypedAttributeValue([1, 'foo', true], true);
218+
expect(result).toStrictEqual({
219+
value: '[1,"foo",true]',
220+
type: 'string',
221+
});
222+
});
223+
224+
it('stringifies objects', () => {
225+
const result = attributeValueToTypedAttributeValue({ foo: 'bar' }, true);
226+
expect(result).toStrictEqual({
227+
value: '{"foo":"bar"}',
228+
type: 'string',
229+
});
230+
});
231+
232+
it('returns empty string for non-stringifiable values (functions)', () => {
233+
const result = attributeValueToTypedAttributeValue(() => 'test', true);
234+
expect(result).toStrictEqual({
235+
value: '',
236+
type: 'string',
237+
});
238+
});
239+
240+
it('returns empty string for non-stringifiable values (symbols)', () => {
241+
const result = attributeValueToTypedAttributeValue(Symbol('test'), true);
242+
expect(result).toStrictEqual({
243+
value: '',
244+
type: 'string',
245+
});
246+
});
247+
248+
it('stringifies non-primitive attribute object values', () => {
249+
const result = attributeValueToTypedAttributeValue({ value: { nested: 'object' } }, true);
250+
expect(result).toStrictEqual({
251+
value: '{"nested":"object"}',
252+
type: 'string',
253+
});
254+
});
255+
});
256+
});
110257
});
111258

112259
describe('isAttributeObject', () => {

0 commit comments

Comments
 (0)