Skip to content

Commit d72af75

Browse files
committed
feat: add more tests to improve coverage
1 parent 3a28232 commit d72af75

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

test/IMQMetadata.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*!
2+
* IMQMetadata Unit Tests
3+
*
4+
* I'm Queue Software Project
5+
* Copyright (C) 2025 imqueue.com <[email protected]>
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*
20+
* If you want to use this code in a closed source (commercial) project, you can
21+
* purchase a proprietary commercial license. Please contact us at
22+
* <[email protected]> to get commercial licensing options.
23+
*/
24+
import './mocks';
25+
import { expect } from 'chai';
26+
import { IMQMetadata } from '..';
27+
28+
describe('IMQMetadata', () => {
29+
it('should be a class', () => {
30+
expect(typeof IMQMetadata).to.equal('function');
31+
});
32+
33+
it('should copy provided metadata props to instance index', () => {
34+
const data = { a: 1, b: 'x', c: { y: true } } as any;
35+
const m = new IMQMetadata(data);
36+
// direct property access
37+
expect((m as any).a).to.equal(1);
38+
expect((m as any).b).to.equal('x');
39+
expect((m as any).c).to.deep.equal({ y: true });
40+
// index signature behavior
41+
const keys = Object.keys(m);
42+
expect(keys.sort()).to.deep.equal(['a','b','c']);
43+
});
44+
});

test/decorators/logged.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import 'reflect-metadata';
2+
import { expect } from 'chai';
3+
import * as sinon from 'sinon';
4+
import { logged } from '../../src/decorators/logged';
5+
6+
describe('decorators/logged()', () => {
7+
it('should be a function and return decorator function', () => {
8+
expect(typeof logged).to.equal('function');
9+
// @ts-ignore
10+
const decorator = logged();
11+
expect(typeof decorator).to.equal('function');
12+
});
13+
14+
it('should fallback to console logger and rethrow by default', async () => {
15+
const error = new Error('boom');
16+
const stub = sinon.stub(console, 'error');
17+
class A {
18+
// @ts-ignore
19+
@logged()
20+
public fail() {
21+
throw error;
22+
}
23+
}
24+
25+
try {
26+
await new A().fail();
27+
expect.fail('should throw');
28+
} catch (e) {
29+
expect(e).to.equal(error);
30+
expect(stub.calledOnce).to.equal(true);
31+
expect(stub.firstCall.args[0]).to.equal(error);
32+
} finally {
33+
stub.restore();
34+
}
35+
});
36+
37+
it('should use provided logger, level and suppress throw when doNotThrow', async () => {
38+
const error = new Error('warned');
39+
const myLogger = {
40+
warn: sinon.stub(),
41+
error: sinon.stub(),
42+
log: sinon.stub(),
43+
info: sinon.stub(),
44+
} as any;
45+
46+
class B {
47+
// @ts-ignore
48+
@logged({ logger: myLogger, level: 'warn', doNotThrow: true })
49+
public fail() {
50+
throw error;
51+
}
52+
}
53+
54+
const res = await new B().fail();
55+
expect(res).to.equal(undefined);
56+
expect(myLogger.warn.calledOnce).to.equal(true);
57+
expect(myLogger.warn.firstCall.args[0]).to.equal(error);
58+
});
59+
60+
it('should accept ILogger directly and rethrow by default', async () => {
61+
const error = new Error('as-logger');
62+
const myLogger = {
63+
warn: sinon.stub(),
64+
error: sinon.stub(),
65+
log: sinon.stub(),
66+
info: sinon.stub(),
67+
} as any;
68+
69+
class C {
70+
// @ts-ignore
71+
@logged(myLogger)
72+
public fail() {
73+
throw error;
74+
}
75+
}
76+
77+
try {
78+
await new C().fail();
79+
expect.fail('should throw');
80+
} catch (e) {
81+
expect(e).to.equal(error);
82+
expect(myLogger.error.calledOnce).to.equal(true);
83+
expect(myLogger.error.firstCall.args[0]).to.equal(error);
84+
}
85+
});
86+
87+
it('should pass through successful return value', async () => {
88+
class D {
89+
// @ts-ignore
90+
@logged()
91+
public ok() {
92+
return 42;
93+
}
94+
}
95+
96+
const v = await new D().ok();
97+
expect(v).to.equal(42);
98+
});
99+
});

0 commit comments

Comments
 (0)