Using atom to automate unit tests in C with Ceedling

I’m trying to use Atom to write unit tests with Ceedling and C production code side-by-side. It would be great if any time I save the source code, Atom could automatically execute a shell command (e.g. “ceedling test:all”) to re-check all of the unit tests.

It seems like packages like on-save or save-autorun should be able to do this, but I have been unable to make them work. Any suggestions?

The TextEditor has an onDidSave event, and the global atom.workspace has a TextEditor subscription method. So you can subscribe a function to be run on every TextEditor, and if it’s the right kind of file also subscribe a function to run each time the TextEditor saves.

I got the following onDidSave event working:

atom.workspace.observeTextEditors (editor) ->
editor.onDidSave ->
console.log “Saved! #{editor.getPath()}”

and this successfully prints the “Saved!” message to the atom Console. It’s not obvious how to generalize this to execute a command.

For example, normally, from a platformio-ide-terminal window pointed to the project directory, I execute the command “ceedling test:all”. Can this type of command be executed from the console?

Thanks for your patience… I’m very new to Atom

process-palette can handle this. You can run a command that triggers when you save, but it would be more effective and less dependent on brittle code to design a save-and-run workflow step (you can replace ctrl-s situationally or opt for ctrl-shift-s or whatever you want) using settings like the following:

That command will prompt you to save all of the files in your project (you can change it) and then run whatever command you ask it to.

Running the commands is less Atom and more NodeJS (which Atom uses underneath); but yes, it’s possible. Here’s an example

const child_process = require("child_process")

atom.workspace.observeTextEditors(editor => {
  if (!wantToSubscribe(editor)) return
  editor.onDidSave(() => {
    child_process.exec("ceedling test:all", (err, stdout) => {
      if (err) atom.notifications.addError(err)

function wantToSubscribe (editor) {
  const scopes = editor.getRootScopeDescriptor().getScopesArray()
  return scopes.length > 0 && scopes[0] === "source.c"

process-palette may still be the better choice, but I like having access to the raw JS to fine tune execution and result handling.

Documentation on child_process can be found here

1 Like

Thanks! I was able to get it working with the following setup:

With this setup, I have the process-palette output streamed to “Panel.” Unfortunately, this panel isn’t an interactive shell, where I could type additional commands. Is it possible to choose the process-palette Target as a separate shell window (e.g. a terminal window provided by the package platformio-ide-terminal)?

It’s possible to make it happen, but to my knowledge nobody has done so yet. platformio-ide-terminal makes available some external methods that allow other packages to use it. This is a core feature of Atom, and all that’s required for process-palette to make use of the terminal service is for it to ask. There’s a chance that I might find the time to implement this myself (I know how, in theory), and if you’re interested in learning more about Atom packages it would be a great exploration.

For now, the most expedient answer would be to have process-palette open a separate window for the command to run in. You can do that on Windows with cmd /c "ceedling test:all && pause", which will spawn a new window, run your program, and give you a “press any key” prompt before it closes itself.