Files
Eric FELIXINE e30ae8ed09 feat(smart-app): implement complete mobile app MVP
- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
2026-06-01 18:00:35 -04:00

249 lines
5.6 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
'use strict';
const Enum = require('../index');
describe('Enum', () => {
const E = Enum({A: 1, B: 2});
test('access members', () => {
expect(E.A).toBe(1);
expect(E.B).toBe(2);
});
test('only two own properties', () => {
expect(Object.getOwnPropertyNames(E).length).toBe(2);
});
test('no enumerable properties', () => {
let count = 0;
for (const _ in E) {
count++;
}
expect(count).toBe(0);
});
test('not extensible', () => {
expect(Object.isExtensible(E)).toBe(false);
expect(() => {
E.C = 3;
}).toThrow();
expect(E.C).toBe(undefined);
expect(Object.getOwnPropertyNames(E).length).toBe(2);
});
test('not writable', () => {
expect(() => {
E.A = 66;
}).toThrow();
expect(() => {
E.B = 66;
}).toThrow();
expect(E.A).toBe(1);
expect(E.B).toBe(2);
});
test('not deletable', () => {
expect(() => {
delete E.A;
}).toThrow();
expect(() => {
delete E.B;
}).toThrow();
expect(E.A).toBe(1);
expect(E.B).toBe(2);
});
test('not configurable', () => {
expect(() => {
Object.defineProperty(E, 'A', {
value: 66,
writable: true,
enumerable: true,
configurable: true,
});
}).toThrow('Cannot redefine property: A');
});
test('not castable to primitive', () => {
expect(() => {
'' + E;
}).toThrow('Cannot convert object to primitive value');
});
test('prototype frozen', () => {
const F = Enum({A: 1});
expect(() => {
Object.getPrototypeOf(F).isValid = () => true;
}).toThrow();
expect(F.isValid(1)).toBe(true);
});
describe('prototype methods', () => {
test('isValid', () => {
expect(E.isValid(1)).toBe(true);
expect(E.isValid(2)).toBe(true);
expect(E.isValid(3)).toBe(false);
expect(E.isValid(null)).toBe(false);
expect(E.isValid(undefined)).toBe(false);
});
test('cast', () => {
expect(E.cast(1)).toBe(E.A);
expect(E.cast(2)).toBe(E.B);
expect(E.cast(3)).toBe(undefined);
});
test('members iterable', () => {
expect(Array.from(E.members())).toEqual([1, 2]);
let i = 1;
for (const x of E.members()) {
expect(x).toEqual(i);
i++;
}
});
test('members iterator', () => {
const iter = E.members();
expect(iter.next()).toEqual({value: 1, done: false});
expect(iter.next()).toEqual({value: 2, done: false});
expect(iter.next()).toEqual({value: undefined, done: true});
});
test('getName', () => {
expect(E.getName(E.A)).toBe('A');
expect(E.getName(E.B)).toBe('B');
});
});
});
describe('Enum.Mirrored', () => {
const E = Enum.Mirrored(['A', 'B']);
test('access members', () => {
expect(E.A).toBe('A');
expect(E.B).toBe('B');
});
test('only two own properties', () => {
expect(Object.getOwnPropertyNames(E).length).toBe(2);
});
test('no enumerable properties', () => {
let count = 0;
for (const _ in E) {
count++;
}
expect(count).toBe(0);
});
test('not extensible', () => {
expect(Object.isExtensible(E)).toBe(false);
expect(() => {
E.C = 'C';
}).toThrow();
expect(E.C).toBe(undefined);
expect(Object.getOwnPropertyNames(E).length).toBe(2);
});
test('not writable', () => {
expect(() => {
E.A = 'foo';
}).toThrow();
expect(() => {
E.B = 'bar';
}).toThrow();
expect(E.A).toBe('A');
expect(E.B).toBe('B');
});
test('not deletable', () => {
expect(() => {
delete E.A;
}).toThrow();
expect(() => {
delete E.B;
}).toThrow();
expect(E.A).toBe('A');
expect(E.B).toBe('B');
});
test('not configurable', () => {
expect(() => {
Object.defineProperty(E, 'A', {
value: 'x',
writable: true,
enumerable: true,
configurable: true,
});
}).toThrow('Cannot redefine property: A');
});
test('not castable to primitive', () => {
expect(() => {
'' + E;
}).toThrow('Cannot convert object to primitive value');
});
test('prototype frozen', () => {
const F = Enum.Mirrored(['A']);
expect(() => {
Object.getPrototypeOf(F).isValid = () => true;
}).toThrow();
expect(F.isValid('A')).toBe(true);
});
describe('prototype methods', () => {
test('isValid', () => {
expect(E.isValid('A')).toBe(true);
expect(E.isValid('B')).toBe(true);
expect(E.isValid('C')).toBe(false);
expect(E.isValid(null)).toBe(false);
expect(E.isValid(undefined)).toBe(false);
const s = {
toString() {
return 'A';
},
};
expect(E.isValid(s)).toBe(false);
});
test('cast', () => {
expect(E.cast('A')).toBe(E.A);
expect(E.cast('B')).toBe(E.B);
expect(E.cast('C')).toBe(undefined);
});
test('members iterable', () => {
const expected = ['A', 'B'];
expect(Array.from(E.members())).toEqual(expected);
let i = 0;
for (const x of E.members()) {
expect(x).toEqual(expected[i]);
i++;
}
});
test('members iterator', () => {
const iter = E.members();
expect(iter.next()).toEqual({value: 'A', done: false});
expect(iter.next()).toEqual({value: 'B', done: false});
expect(iter.next()).toEqual({value: undefined, done: true});
});
test('getName', () => {
expect(E.getName(E.A)).toBe('A');
expect(E.getName(E.B)).toBe('B');
});
});
});