Skip to content

Instantly share code, notes, and snippets.

@wesleylhandy
Last active June 6, 2020 02:05
Show Gist options
  • Save wesleylhandy/3d3d931f19c00c79528ef40e89c814d3 to your computer and use it in GitHub Desktop.
Save wesleylhandy/3d3d931f19c00c79528ef40e89c814d3 to your computer and use it in GitHub Desktop.
MacOS Bash Command to Create (empty) Test Files for any JavaScript or TypeScript files in your project.
#!/bin/bash
find . \( -iname "*.js*" -or -iname "*.ts*" \) \
-and \( ! -path "*/__mocks__/*" ! -name "*.test.*" ! -name "*.spec.*" \) \
-exec sh -c \
'b=$(basename $1);f=${b%.*};d=$(dirname $1);e=${b##*.}; mkdir -p $d/__tests__ && > $d/__tests__/$f.test.$e' \
sh {} \;
@wesleylhandy
Copy link
Author

This command will ignore __mocks__ folders and existing *.spec.* or *.test.* files.
Run from bash at the root of your project.

Below explains the Bash commands being called:

  • find will search for files within a directory recursively.
  • iname identifies files that match a shell pattern ignoring case.
  • or and and are logical operators
  • ! is short for the not logical operator
  • path identifies paths that match a shell pattern
  • exec executes a shell function on each returned file from the search. It replaces {} with the current file name
  • sh runs a command on an input
  • c tells sh the input is a string
b=$(basename $1);f=${b%.*};d=$(dirname $1);e=${b##*.}; mkdir -p $d/__tests__ && > $d/__tests__/$f.test.$e

Above creates three variables, b, f, d, and e, respectively that return the basename, filename without extension, the extension, and the the directory name, respectively. The command that follows creates a new __tests__ directory in the parent directory of the file (if its missing) and then creates a new file in that director with the with the following format: <filename>.test.<extension>.

@szepeviktor
Copy link

szepeviktor commented Jun 3, 2020

Here is the same script in sustainable form

#!/bin/bash
#
# Create (empty) Test Files for any JavaScript/TypeScript files
#

find . -iname "*.[jt]s*" \
  "(" -not -path "*/__mocks__/*" -not -name "*.test.*" -not -name "*.spec.*" ")" \
  -exec bash -c \
  'b="$(basename "$1")"; f="${b%.*}"; d="$(dirname "$1")"; e="${b##*.}"; mkdir -p "${d}/__tests__" && >"${d}/__tests__/${f}.test.${e}"' \
  bash "{}" ";"

@wesleylhandy
Copy link
Author

Thanks @szepeviktor, but your version of the script doesn't run on my iMac within the terminal on VSCode.

@szepeviktor
Copy link

szepeviktor commented Jun 3, 2020

I see.
Which part needs GNU find? -iname "*.[jt]s*" ??

@wesleylhandy
Copy link
Author

What is the difference between using sh in my script and bash in yours?

In my script, I want all .[jt]x files not currently in __mocks__ folder and who are already not named a *.test.* or *.spec.*. I've updated to also exclude __tests__ folder and node_modules folder.

The result of find goes all the way through to the end.

I've updated it to the following:

find . -iname "*.[jt]s*" \
  -and \( \
    ! -path "*/__mocks__/*" \
    ! -path "*/node_modules/*" \
    ! -path "*/__tests__/*" \
    ! -name "*.test.*" \
    ! -name "*.spec.*" \
  \) \
-exec sh -c \
  'b=$(basename $1);f=${b%.*};d=$(dirname $1);e=${b##*.}; mkdir -p $d/__tests__ && > $d/__tests__/$f.test.$e' \
sh {} \;

@szepeviktor
Copy link

szepeviktor commented Jun 6, 2020

What is the difference between using sh in my script and bash in yours?

bash starts Bash, sh depends on some settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment