velxio/frontend/src/__tests__/issue-139-espidf-mode.test.ts

106 lines
3.9 KiB
TypeScript

/**
* Tests for GitHub issue #139 — pure ESP-IDF language mode
* https://github.com/davidmonterocrespo24/velxio/issues/139
*
* The ESP32 family gains a third entry in the language selector next to
* Arduino C++ and MicroPython: "ESP-IDF". In that mode the user writes a
* plain IDF project (app_main() entry point, FreeRTOS + driver APIs) and
* the backend compiles it through the same ESP-IDF toolchain it already
* uses for Arduino sketches — just without the arduino-esp32 component.
*
* Pure Vitest unit tests — no QEMU, no network, no DOM.
*/
import { describe, it, expect } from 'vitest';
import { BOARD_SUPPORTS_ESPIDF, BOARD_SUPPORTS_MICROPYTHON } from '../types/board';
import type { BoardKind } from '../types/board';
import { useEditorStore } from '../store/useEditorStore';
import { exampleProjects } from '../data/examples';
describe('issue #139 — BOARD_SUPPORTS_ESPIDF', () => {
const ESP32_KINDS: BoardKind[] = [
'esp32',
'esp32-devkit-c-v4',
'esp32-cam',
'wemos-lolin32-lite',
'esp32-s3',
'xiao-esp32-s3',
'arduino-nano-esp32',
'esp32-c3',
'xiao-esp32-c3',
'aitewinrobot-esp32c3-supermini',
];
for (const kind of ESP32_KINDS) {
it(`${kind} supports ESP-IDF mode`, () => {
expect(BOARD_SUPPORTS_ESPIDF.has(kind)).toBe(true);
});
}
it('non-ESP32 boards do NOT support ESP-IDF mode', () => {
const NON_ESP32: BoardKind[] = [
'arduino-uno',
'raspberry-pi-pico',
'pi-pico-w',
'raspberry-pi-3',
'stm32-bluepill',
'attiny85',
];
for (const kind of NON_ESP32) {
expect(BOARD_SUPPORTS_ESPIDF.has(kind)).toBe(false);
}
});
it('every ESP-IDF board also offers the language selector (MicroPython set)', () => {
// The toolbar renders the selector when BOARD_SUPPORTS_MICROPYTHON
// matches and adds the ESP-IDF option when BOARD_SUPPORTS_ESPIDF also
// matches — so every espidf-capable board must be in the outer set or
// the option would be unreachable.
for (const kind of BOARD_SUPPORTS_ESPIDF) {
expect(BOARD_SUPPORTS_MICROPYTHON.has(kind)).toBe(true);
}
});
});
describe('issue #139 — espidf file group defaults', () => {
it("createFileGroup(groupId, 'espidf') seeds main.c with app_main()", () => {
const groupId = 'group-esp32-espidf-test';
useEditorStore.getState().createFileGroup(groupId, 'espidf');
const files = useEditorStore.getState().getGroupFiles(groupId);
expect(files).toHaveLength(1);
expect(files[0].name).toBe('main.c');
expect(files[0].content).toContain('app_main');
expect(files[0].content).toContain('freertos/FreeRTOS.h');
expect(files[0].content).toContain('driver/gpio.h');
// Must NOT be an Arduino sketch — that's the whole point of the mode.
expect(files[0].content).not.toContain('setup()');
expect(files[0].content).not.toContain('Arduino.h');
useEditorStore.getState().deleteFileGroup(groupId);
});
it("createFileGroup(groupId, 'arduino') still seeds sketch.ino (regression)", () => {
const groupId = 'group-esp32-arduino-test';
useEditorStore.getState().createFileGroup(groupId, 'arduino');
const files = useEditorStore.getState().getGroupFiles(groupId);
expect(files[0].name).toBe('sketch.ino');
useEditorStore.getState().deleteFileGroup(groupId);
});
});
describe('issue #139 — esp32-idf-blink gallery example', () => {
const example = exampleProjects.find((e) => e.id === 'esp32-idf-blink');
it('exists and targets an ESP32 board in espidf mode', () => {
expect(example).toBeDefined();
expect(example?.boardType).toBe('esp32');
expect(example?.languageMode).toBe('espidf');
});
it('ships a main.c with an app_main() entry point', () => {
const mainFile = example?.files?.find((f) => f.name === 'main.c');
expect(mainFile).toBeDefined();
expect(mainFile?.content).toContain('void app_main(void)');
expect(mainFile?.content).not.toContain('Arduino.h');
});
});