fix(#24,#25,#26,#27,#30): action按钮顺序; group边界; Notification权限; queue catch; 新增功能测试

This commit is contained in:
tianhao
2026-06-16 13:09:50 +08:00
parent 531438cc9c
commit 900e965ae6
3 changed files with 89 additions and 6 deletions
+15 -4
View File
@@ -1018,7 +1018,7 @@ const meToast = {
const t = this._emit({ const t = this._emit({
...normalized, ...normalized,
html: _actionHTML(actions) + (normalized.html || ''), html: (normalized.html || '') + _actionHTML(actions),
}); });
if (Array.isArray(actions)) { if (Array.isArray(actions)) {
@@ -1090,6 +1090,7 @@ const meToast = {
}); });
return { return {
then: (fn, rj) => promise.then(fn, rj), then: (fn, rj) => promise.then(fn, rj),
catch: (rj) => promise.catch(rj),
cancel: () => { cancelled = true; }, cancel: () => { cancelled = true; },
}; };
}, },
@@ -1167,9 +1168,19 @@ const meToast = {
const g = { _group: name }; const g = { _group: name };
methods.forEach(m => { methods.forEach(m => {
g[m] = (...args) => { g[m] = (...args) => {
const last = typeof args[args.length - 1] === 'object' && args[args.length - 1] !== null && !Array.isArray(args[args.length - 1]) const lastArg = args[args.length - 1];
? args.pop() : {}; const isObj = typeof lastArg === 'object' && lastArg !== null && !Array.isArray(lastArg);
return self[m](...args, { ...last, group: name }); // 单对象参数:直接合并group
if (isObj && args.length === 1) {
return self[m]({ ...lastArg, group: name });
}
// 末尾是配置对象:pop后合并
if (isObj) {
args.pop();
return self[m](...args, { ...lastArg, group: name });
}
// 无配置对象
return self[m](...args, { group: name });
}; };
}); });
g.dismiss = () => self.dismissGroup(name); g.dismiss = () => self.dismissGroup(name);
+10 -2
View File
@@ -260,10 +260,18 @@ if (typeof window !== 'undefined') {
// Notification API — 页面不可见时自动发送系统通知 // Notification API — 页面不可见时自动发送系统通知
enhancedMeToast._notify = (toast) => { enhancedMeToast._notify = (toast) => {
if (typeof Notification === 'undefined' || Notification.permission !== 'granted') return; if (typeof Notification === 'undefined') return;
if (Notification.permission === 'denied') return;
if (!document.hidden) return; if (!document.hidden) return;
if (Notification.permission === 'default') {
Notification.requestPermission().then(p => { if (p === 'granted') sendNotification(toast); });
return;
}
sendNotification(toast);
};
const sendNotification = (toast) => {
try { try {
new Notification(toast.title || toast.type, { body: toast.message, icon: '/favicon.ico' }); new Notification(toast.title || toast.type, { body: toast.message });
} catch (_) {} } catch (_) {}
}; };
Toast.on('afterShow', (toast) => { Toast.on('afterShow', (toast) => {
+64
View File
@@ -1931,3 +1931,67 @@ describe('边界情况', () => {
expect(MeToast.getToast()).toBeNull(); expect(MeToast.getToast()).toBeNull();
}); });
}); });
// ========== 新增功能测试 ==========
describe('新增功能', () => {
beforeEach(() => {
MeToast._toasts.clear();
});
test('resetTimerOnUpdate — update后重置计时器', () => {
const t = MeToast.info('test', { duration: 5000, resetTimerOnUpdate: true });
const oldRemaining = t.remaining;
t.update({ message: 'updated' });
expect(t.remaining).toBe(5000);
expect(t.paused).toBe(false);
});
test('onUpdate 回调触发', () => {
const fn = jest.fn();
const t = MeToast.success('test', { onUpdate: fn });
t.update({ message: 'changed' });
expect(fn).toHaveBeenCalledWith(t);
});
test('action 返回控制对象', () => {
const a = MeToast.action('test', [{ text: 'OK', onClick: () => {} }]);
expect(a).toBeDefined();
expect(a.id).toBeDefined();
expect(a.toast).toBeDefined();
expect(a.dismiss).toBeInstanceOf(Function);
});
test('queue 返回可取消对象', () => {
const q = MeToast.queue(['a', 'b'], { delay: 10, duration: 10 });
expect(q.then).toBeInstanceOf(Function);
expect(q.catch).toBeInstanceOf(Function);
expect(q.cancel).toBeInstanceOf(Function);
q.cancel();
});
test('group 创建分组并正常工作', () => {
const g = MeToast.group('test-group');
expect(g._group).toBe('test-group');
expect(g.dismiss).toBeInstanceOf(Function);
expect(g.count).toBeInstanceOf(Function);
const t = g.info('grouped message');
expect(t.group).toBe('test-group');
});
test('dismissGroup 按组关闭', () => {
const g = MeToast.group('batch');
g.success('m1');
g.error('m2');
expect(MeToast._groupCount('batch')).toBe(2);
MeToast.dismissGroup('batch');
});
test('自定义渲染函数', () => {
const t = MeToast.show({
render: (toast) => `<b>${toast.message}</b>`,
message: 'rendered',
});
expect(t.config.render).toBeInstanceOf(Function);
});
});