diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 788dfdad4bb..7ef14f2cd81 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,4 +12,4 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - run: npm install - - run: npm run test -- **/solution + - run: npm run test -- solution diff --git a/README.md b/README.md index b05742224ea..c720d032279 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you have a suggestion to improve an exercise, an idea for a new exercise, or - A markdown file with a description of the task, an empty (or mostly empty) JavaScript file, and a set of tests. - A `solutions` directory that contains an example solution and the same test file with all of the tests unskipped. - To complete an exercise, you will need to go to the exercise directory with `cd exerciseName` in the terminal and run `npm test exerciseName.spec.js`. This should run the test file and show you the output. When you run a test for the first time, it will fail. This is by design! You must open the exercise file and write the code needed to get the test to pass. + To complete an exercise, you will need to go to the exercise directory with `cd ` in the terminal and run `npm test exerciseName.spec.js`. For example, to go to the first Foundations exercise "helloWorld", you need to `cd foundations/01_helloWorld` then run `npm rest helloWorld`. This should run the test file and show you the output. When you run a test for the first time, it will fail. This is by design! You must open the exercise file and write the code needed to get the test to pass. 1. Some of the exercises have test conditions defined in their spec file as `test.skip` instead of `test`. This is intentional. Once all `test`s pass, you will change the next `test.skip` to `test` and test your code again. You will do this until all conditions are satisfied. **All tests must pass at the same time**, and you should not have any instances of `test.skip` in the spec file when you are finished with an exercise. 1. Once you successfully finish an exercise, check the `solutions` directory within each exercise. diff --git a/13_factorial/README.md b/computer_science/recursion/1_factorial/README.md similarity index 95% rename from 13_factorial/README.md rename to computer_science/recursion/1_factorial/README.md index ecd8388fa6a..9635e2039f2 100644 --- a/13_factorial/README.md +++ b/computer_science/recursion/1_factorial/README.md @@ -1,4 +1,4 @@ -# Exercise 13 - Factorial +# Exercise 1 - Factorial Write a recursive [factorial](https://simple.wikipedia.org/wiki/Factorial) function that takes a non-negative integer, and returns the product of all positive integers less than or equal to the input integer. An input of `0` should return `1`. The function should only accept numbers, so `'4'` should not be accepted as it is a string. All invalid inputs should return `undefined`. diff --git a/13_factorial/factorial.js b/computer_science/recursion/1_factorial/factorial.js similarity index 100% rename from 13_factorial/factorial.js rename to computer_science/recursion/1_factorial/factorial.js diff --git a/13_factorial/factorial.spec.js b/computer_science/recursion/1_factorial/factorial.spec.js similarity index 100% rename from 13_factorial/factorial.spec.js rename to computer_science/recursion/1_factorial/factorial.spec.js diff --git a/13_factorial/solution/factorial-solution.js b/computer_science/recursion/1_factorial/solution/factorial-solution.js similarity index 100% rename from 13_factorial/solution/factorial-solution.js rename to computer_science/recursion/1_factorial/solution/factorial-solution.js diff --git a/13_factorial/solution/factorial-solution.spec.js b/computer_science/recursion/1_factorial/solution/factorial-solution.spec.js similarity index 100% rename from 13_factorial/solution/factorial-solution.spec.js rename to computer_science/recursion/1_factorial/solution/factorial-solution.spec.js diff --git a/14_contains/README.md b/computer_science/recursion/2_contains/README.md similarity index 91% rename from 14_contains/README.md rename to computer_science/recursion/2_contains/README.md index d2dab5789f0..3ca069fa451 100644 --- a/14_contains/README.md +++ b/computer_science/recursion/2_contains/README.md @@ -1,4 +1,4 @@ -# Exercise 14 - contains +# Exercise 2 - contains Write a function that searches for a value in a nested object. It returns true if the object contains that value. diff --git a/14_contains/contains.js b/computer_science/recursion/2_contains/contains.js similarity index 100% rename from 14_contains/contains.js rename to computer_science/recursion/2_contains/contains.js diff --git a/14_contains/contains.spec.js b/computer_science/recursion/2_contains/contains.spec.js similarity index 100% rename from 14_contains/contains.spec.js rename to computer_science/recursion/2_contains/contains.spec.js diff --git a/14_contains/solution/contains-solution.js b/computer_science/recursion/2_contains/solution/contains-solution.js similarity index 100% rename from 14_contains/solution/contains-solution.js rename to computer_science/recursion/2_contains/solution/contains-solution.js diff --git a/14_contains/solution/contains-solution.spec.js b/computer_science/recursion/2_contains/solution/contains-solution.spec.js similarity index 100% rename from 14_contains/solution/contains-solution.spec.js rename to computer_science/recursion/2_contains/solution/contains-solution.spec.js diff --git a/15_totalIntegers/README.md b/computer_science/recursion/3_totalIntegers/README.md similarity index 90% rename from 15_totalIntegers/README.md rename to computer_science/recursion/3_totalIntegers/README.md index 48d09cda822..f0aaa4d0aba 100644 --- a/15_totalIntegers/README.md +++ b/computer_science/recursion/3_totalIntegers/README.md @@ -1,4 +1,4 @@ -# Exercise 15 - totalIntegers +# Exercise 3 - totalIntegers Write a function that takes in an arbitrarily deep array or object and returns the total number of integers stored inside this array or object. diff --git a/15_totalIntegers/solution/totalIntegers-solution.js b/computer_science/recursion/3_totalIntegers/solution/totalIntegers-solution.js similarity index 100% rename from 15_totalIntegers/solution/totalIntegers-solution.js rename to computer_science/recursion/3_totalIntegers/solution/totalIntegers-solution.js diff --git a/15_totalIntegers/solution/totalIntegers-solution.spec.js b/computer_science/recursion/3_totalIntegers/solution/totalIntegers-solution.spec.js similarity index 100% rename from 15_totalIntegers/solution/totalIntegers-solution.spec.js rename to computer_science/recursion/3_totalIntegers/solution/totalIntegers-solution.spec.js diff --git a/15_totalIntegers/totalIntegers.js b/computer_science/recursion/3_totalIntegers/totalIntegers.js similarity index 100% rename from 15_totalIntegers/totalIntegers.js rename to computer_science/recursion/3_totalIntegers/totalIntegers.js diff --git a/15_totalIntegers/totalIntegers.spec.js b/computer_science/recursion/3_totalIntegers/totalIntegers.spec.js similarity index 100% rename from 15_totalIntegers/totalIntegers.spec.js rename to computer_science/recursion/3_totalIntegers/totalIntegers.spec.js diff --git a/16_permutations/README.md b/computer_science/recursion/4_permutations/README.md similarity index 93% rename from 16_permutations/README.md rename to computer_science/recursion/4_permutations/README.md index de5569ccbc2..eff389ffea4 100644 --- a/16_permutations/README.md +++ b/computer_science/recursion/4_permutations/README.md @@ -1,4 +1,4 @@ -# Exercise 16 - permutations +# Exercise 4 - permutations Write a function that takes in an empty array or an input array of an consecutive positive integers, starting at 1, and returns an array of all possible permutations of the original array diff --git a/16_permutations/permutations.js b/computer_science/recursion/4_permutations/permutations.js similarity index 100% rename from 16_permutations/permutations.js rename to computer_science/recursion/4_permutations/permutations.js diff --git a/16_permutations/permutations.spec.js b/computer_science/recursion/4_permutations/permutations.spec.js similarity index 100% rename from 16_permutations/permutations.spec.js rename to computer_science/recursion/4_permutations/permutations.spec.js diff --git a/16_permutations/solution/permutations-solution.js b/computer_science/recursion/4_permutations/solution/permutations-solution.js similarity index 100% rename from 16_permutations/solution/permutations-solution.js rename to computer_science/recursion/4_permutations/solution/permutations-solution.js diff --git a/16_permutations/solution/permutations-solution.spec.js b/computer_science/recursion/4_permutations/solution/permutations-solution.spec.js similarity index 100% rename from 16_permutations/solution/permutations-solution.spec.js rename to computer_science/recursion/4_permutations/solution/permutations-solution.spec.js diff --git a/19_pascal/README.md b/computer_science/recursion/5_pascal/README.md similarity index 96% rename from 19_pascal/README.md rename to computer_science/recursion/5_pascal/README.md index fa607c942ad..b951fc406b4 100644 --- a/19_pascal/README.md +++ b/computer_science/recursion/5_pascal/README.md @@ -1,4 +1,4 @@ -# Exercise 19 - pascal +# Exercise 5 - pascal The pascal's triangle is modelled as follows: - The first row is `1`. diff --git a/19_pascal/pascal.js b/computer_science/recursion/5_pascal/pascal.js similarity index 100% rename from 19_pascal/pascal.js rename to computer_science/recursion/5_pascal/pascal.js diff --git a/19_pascal/pascal.spec.js b/computer_science/recursion/5_pascal/pascal.spec.js similarity index 100% rename from 19_pascal/pascal.spec.js rename to computer_science/recursion/5_pascal/pascal.spec.js diff --git a/19_pascal/solution/pascal-solution.js b/computer_science/recursion/5_pascal/solution/pascal-solution.js similarity index 100% rename from 19_pascal/solution/pascal-solution.js rename to computer_science/recursion/5_pascal/solution/pascal-solution.js diff --git a/19_pascal/solution/pascal-solution.spec.js b/computer_science/recursion/5_pascal/solution/pascal-solution.spec.js similarity index 100% rename from 19_pascal/solution/pascal-solution.spec.js rename to computer_science/recursion/5_pascal/solution/pascal-solution.spec.js diff --git a/01_helloWorld/README.md b/foundations/01_helloWorld/README.md similarity index 100% rename from 01_helloWorld/README.md rename to foundations/01_helloWorld/README.md diff --git a/01_helloWorld/helloWorld.js b/foundations/01_helloWorld/helloWorld.js similarity index 100% rename from 01_helloWorld/helloWorld.js rename to foundations/01_helloWorld/helloWorld.js diff --git a/01_helloWorld/helloWorld.spec.js b/foundations/01_helloWorld/helloWorld.spec.js similarity index 100% rename from 01_helloWorld/helloWorld.spec.js rename to foundations/01_helloWorld/helloWorld.spec.js diff --git a/01_helloWorld/solution/helloWorld-solution.js b/foundations/01_helloWorld/solution/helloWorld-solution.js similarity index 100% rename from 01_helloWorld/solution/helloWorld-solution.js rename to foundations/01_helloWorld/solution/helloWorld-solution.js diff --git a/01_helloWorld/solution/helloWorld-solution.spec.js b/foundations/01_helloWorld/solution/helloWorld-solution.spec.js similarity index 100% rename from 01_helloWorld/solution/helloWorld-solution.spec.js rename to foundations/01_helloWorld/solution/helloWorld-solution.spec.js diff --git a/02_addNumbers/README.md b/foundations/02_addNumbers/README.md similarity index 100% rename from 02_addNumbers/README.md rename to foundations/02_addNumbers/README.md diff --git a/02_addNumbers/addNumbers.js b/foundations/02_addNumbers/addNumbers.js similarity index 100% rename from 02_addNumbers/addNumbers.js rename to foundations/02_addNumbers/addNumbers.js diff --git a/02_addNumbers/addNumbers.spec.js b/foundations/02_addNumbers/addNumbers.spec.js similarity index 100% rename from 02_addNumbers/addNumbers.spec.js rename to foundations/02_addNumbers/addNumbers.spec.js diff --git a/02_addNumbers/solution/addNumbers-solution.js b/foundations/02_addNumbers/solution/addNumbers-solution.js similarity index 100% rename from 02_addNumbers/solution/addNumbers-solution.js rename to foundations/02_addNumbers/solution/addNumbers-solution.js diff --git a/02_addNumbers/solution/addNumbers-solution.spec.js b/foundations/02_addNumbers/solution/addNumbers-solution.spec.js similarity index 100% rename from 02_addNumbers/solution/addNumbers-solution.spec.js rename to foundations/02_addNumbers/solution/addNumbers-solution.spec.js diff --git a/03_numberChecker/README.md b/foundations/03_numberChecker/README.md similarity index 100% rename from 03_numberChecker/README.md rename to foundations/03_numberChecker/README.md diff --git a/03_numberChecker/numberChecker.js b/foundations/03_numberChecker/numberChecker.js similarity index 100% rename from 03_numberChecker/numberChecker.js rename to foundations/03_numberChecker/numberChecker.js diff --git a/03_numberChecker/numberChecker.spec.js b/foundations/03_numberChecker/numberChecker.spec.js similarity index 100% rename from 03_numberChecker/numberChecker.spec.js rename to foundations/03_numberChecker/numberChecker.spec.js diff --git a/03_numberChecker/solution/numberChecker-solution.js b/foundations/03_numberChecker/solution/numberChecker-solution.js similarity index 100% rename from 03_numberChecker/solution/numberChecker-solution.js rename to foundations/03_numberChecker/solution/numberChecker-solution.js diff --git a/03_numberChecker/solution/numberChecker-solution.spec.js b/foundations/03_numberChecker/solution/numberChecker-solution.spec.js similarity index 100% rename from 03_numberChecker/solution/numberChecker-solution.spec.js rename to foundations/03_numberChecker/solution/numberChecker-solution.spec.js diff --git a/04_mathEquations/README.md b/foundations/04_mathEquations/README.md similarity index 100% rename from 04_mathEquations/README.md rename to foundations/04_mathEquations/README.md diff --git a/04_mathEquations/mathEquations.js b/foundations/04_mathEquations/mathEquations.js similarity index 100% rename from 04_mathEquations/mathEquations.js rename to foundations/04_mathEquations/mathEquations.js diff --git a/04_mathEquations/mathEquations.spec.js b/foundations/04_mathEquations/mathEquations.spec.js similarity index 100% rename from 04_mathEquations/mathEquations.spec.js rename to foundations/04_mathEquations/mathEquations.spec.js diff --git a/04_mathEquations/solution/mathEquations-solution.js b/foundations/04_mathEquations/solution/mathEquations-solution.js similarity index 100% rename from 04_mathEquations/solution/mathEquations-solution.js rename to foundations/04_mathEquations/solution/mathEquations-solution.js diff --git a/04_mathEquations/solution/mathEquations-solution.spec.js b/foundations/04_mathEquations/solution/mathEquations-solution.spec.js similarity index 100% rename from 04_mathEquations/solution/mathEquations-solution.spec.js rename to foundations/04_mathEquations/solution/mathEquations-solution.spec.js diff --git a/05_joinStrings/README.md b/foundations/05_joinStrings/README.md similarity index 100% rename from 05_joinStrings/README.md rename to foundations/05_joinStrings/README.md diff --git a/05_joinStrings/joinStrings-example.js b/foundations/05_joinStrings/joinStrings-example.js similarity index 100% rename from 05_joinStrings/joinStrings-example.js rename to foundations/05_joinStrings/joinStrings-example.js diff --git a/05_joinStrings/joinStrings-example.spec.js b/foundations/05_joinStrings/joinStrings-example.spec.js similarity index 100% rename from 05_joinStrings/joinStrings-example.spec.js rename to foundations/05_joinStrings/joinStrings-example.spec.js diff --git a/05_joinStrings/joinStrings.js b/foundations/05_joinStrings/joinStrings.js similarity index 100% rename from 05_joinStrings/joinStrings.js rename to foundations/05_joinStrings/joinStrings.js diff --git a/05_joinStrings/joinStrings.spec.js b/foundations/05_joinStrings/joinStrings.spec.js similarity index 100% rename from 05_joinStrings/joinStrings.spec.js rename to foundations/05_joinStrings/joinStrings.spec.js diff --git a/05_joinStrings/solution/joinStrings-solution.js b/foundations/05_joinStrings/solution/joinStrings-solution.js similarity index 100% rename from 05_joinStrings/solution/joinStrings-solution.js rename to foundations/05_joinStrings/solution/joinStrings-solution.js diff --git a/05_joinStrings/solution/joinStrings-solution.spec.js b/foundations/05_joinStrings/solution/joinStrings-solution.spec.js similarity index 100% rename from 05_joinStrings/solution/joinStrings-solution.spec.js rename to foundations/05_joinStrings/solution/joinStrings-solution.spec.js diff --git a/06_repeatString/README.md b/foundations/06_repeatString/README.md similarity index 100% rename from 06_repeatString/README.md rename to foundations/06_repeatString/README.md diff --git a/06_repeatString/repeatString.js b/foundations/06_repeatString/repeatString.js similarity index 100% rename from 06_repeatString/repeatString.js rename to foundations/06_repeatString/repeatString.js diff --git a/06_repeatString/repeatString.spec.js b/foundations/06_repeatString/repeatString.spec.js similarity index 100% rename from 06_repeatString/repeatString.spec.js rename to foundations/06_repeatString/repeatString.spec.js diff --git a/06_repeatString/solution/repeatString-solution.js b/foundations/06_repeatString/solution/repeatString-solution.js similarity index 100% rename from 06_repeatString/solution/repeatString-solution.js rename to foundations/06_repeatString/solution/repeatString-solution.js diff --git a/06_repeatString/solution/repeatString-solution.spec.js b/foundations/06_repeatString/solution/repeatString-solution.spec.js similarity index 100% rename from 06_repeatString/solution/repeatString-solution.spec.js rename to foundations/06_repeatString/solution/repeatString-solution.spec.js diff --git a/07_reverseString/README.md b/foundations/07_reverseString/README.md similarity index 100% rename from 07_reverseString/README.md rename to foundations/07_reverseString/README.md diff --git a/07_reverseString/reverseString.js b/foundations/07_reverseString/reverseString.js similarity index 100% rename from 07_reverseString/reverseString.js rename to foundations/07_reverseString/reverseString.js diff --git a/07_reverseString/reverseString.spec.js b/foundations/07_reverseString/reverseString.spec.js similarity index 100% rename from 07_reverseString/reverseString.spec.js rename to foundations/07_reverseString/reverseString.spec.js diff --git a/07_reverseString/solution/reverseString-solution.js b/foundations/07_reverseString/solution/reverseString-solution.js similarity index 100% rename from 07_reverseString/solution/reverseString-solution.js rename to foundations/07_reverseString/solution/reverseString-solution.js diff --git a/07_reverseString/solution/reverseString-solution.spec.js b/foundations/07_reverseString/solution/reverseString-solution.spec.js similarity index 100% rename from 07_reverseString/solution/reverseString-solution.spec.js rename to foundations/07_reverseString/solution/reverseString-solution.spec.js diff --git a/08_removeFromArray/README.md b/foundations/08_removeFromArray/README.md similarity index 100% rename from 08_removeFromArray/README.md rename to foundations/08_removeFromArray/README.md diff --git a/08_removeFromArray/removeFromArray.js b/foundations/08_removeFromArray/removeFromArray.js similarity index 100% rename from 08_removeFromArray/removeFromArray.js rename to foundations/08_removeFromArray/removeFromArray.js diff --git a/08_removeFromArray/removeFromArray.spec.js b/foundations/08_removeFromArray/removeFromArray.spec.js similarity index 100% rename from 08_removeFromArray/removeFromArray.spec.js rename to foundations/08_removeFromArray/removeFromArray.spec.js diff --git a/08_removeFromArray/solution/removeFromArray-solution.js b/foundations/08_removeFromArray/solution/removeFromArray-solution.js similarity index 100% rename from 08_removeFromArray/solution/removeFromArray-solution.js rename to foundations/08_removeFromArray/solution/removeFromArray-solution.js diff --git a/08_removeFromArray/solution/removeFromArray-solution.spec.js b/foundations/08_removeFromArray/solution/removeFromArray-solution.spec.js similarity index 100% rename from 08_removeFromArray/solution/removeFromArray-solution.spec.js rename to foundations/08_removeFromArray/solution/removeFromArray-solution.spec.js diff --git a/09_sumAll/README.md b/foundations/09_sumAll/README.md similarity index 100% rename from 09_sumAll/README.md rename to foundations/09_sumAll/README.md diff --git a/09_sumAll/solution/sumAll-solution.js b/foundations/09_sumAll/solution/sumAll-solution.js similarity index 100% rename from 09_sumAll/solution/sumAll-solution.js rename to foundations/09_sumAll/solution/sumAll-solution.js diff --git a/09_sumAll/solution/sumAll-solution.spec.js b/foundations/09_sumAll/solution/sumAll-solution.spec.js similarity index 100% rename from 09_sumAll/solution/sumAll-solution.spec.js rename to foundations/09_sumAll/solution/sumAll-solution.spec.js diff --git a/09_sumAll/sumAll.js b/foundations/09_sumAll/sumAll.js similarity index 100% rename from 09_sumAll/sumAll.js rename to foundations/09_sumAll/sumAll.js diff --git a/09_sumAll/sumAll.spec.js b/foundations/09_sumAll/sumAll.spec.js similarity index 100% rename from 09_sumAll/sumAll.spec.js rename to foundations/09_sumAll/sumAll.spec.js diff --git a/10_leapYears/README.md b/foundations/10_leapYears/README.md similarity index 100% rename from 10_leapYears/README.md rename to foundations/10_leapYears/README.md diff --git a/10_leapYears/leapYears.js b/foundations/10_leapYears/leapYears.js similarity index 100% rename from 10_leapYears/leapYears.js rename to foundations/10_leapYears/leapYears.js diff --git a/10_leapYears/leapYears.spec.js b/foundations/10_leapYears/leapYears.spec.js similarity index 100% rename from 10_leapYears/leapYears.spec.js rename to foundations/10_leapYears/leapYears.spec.js diff --git a/10_leapYears/solution/leapYears-solution.js b/foundations/10_leapYears/solution/leapYears-solution.js similarity index 100% rename from 10_leapYears/solution/leapYears-solution.js rename to foundations/10_leapYears/solution/leapYears-solution.js diff --git a/10_leapYears/solution/leapYears-solution.spec.js b/foundations/10_leapYears/solution/leapYears-solution.spec.js similarity index 100% rename from 10_leapYears/solution/leapYears-solution.spec.js rename to foundations/10_leapYears/solution/leapYears-solution.spec.js diff --git a/11_tempConversion/README.md b/foundations/11_tempConversion/README.md similarity index 100% rename from 11_tempConversion/README.md rename to foundations/11_tempConversion/README.md diff --git a/11_tempConversion/solution/tempConversion-solution.js b/foundations/11_tempConversion/solution/tempConversion-solution.js similarity index 100% rename from 11_tempConversion/solution/tempConversion-solution.js rename to foundations/11_tempConversion/solution/tempConversion-solution.js diff --git a/11_tempConversion/solution/tempConversion-solution.spec.js b/foundations/11_tempConversion/solution/tempConversion-solution.spec.js similarity index 100% rename from 11_tempConversion/solution/tempConversion-solution.spec.js rename to foundations/11_tempConversion/solution/tempConversion-solution.spec.js diff --git a/11_tempConversion/tempConversion.js b/foundations/11_tempConversion/tempConversion.js similarity index 100% rename from 11_tempConversion/tempConversion.js rename to foundations/11_tempConversion/tempConversion.js diff --git a/11_tempConversion/tempConversion.spec.js b/foundations/11_tempConversion/tempConversion.spec.js similarity index 100% rename from 11_tempConversion/tempConversion.spec.js rename to foundations/11_tempConversion/tempConversion.spec.js diff --git a/12_calculator/README.md b/foundations/12_calculator/README.md similarity index 100% rename from 12_calculator/README.md rename to foundations/12_calculator/README.md diff --git a/12_calculator/calculator.js b/foundations/12_calculator/calculator.js similarity index 100% rename from 12_calculator/calculator.js rename to foundations/12_calculator/calculator.js diff --git a/12_calculator/calculator.spec.js b/foundations/12_calculator/calculator.spec.js similarity index 100% rename from 12_calculator/calculator.spec.js rename to foundations/12_calculator/calculator.spec.js diff --git a/12_calculator/solution/calculator-solution.js b/foundations/12_calculator/solution/calculator-solution.js similarity index 100% rename from 12_calculator/solution/calculator-solution.js rename to foundations/12_calculator/solution/calculator-solution.js diff --git a/12_calculator/solution/calculator-solution.spec.js b/foundations/12_calculator/solution/calculator-solution.spec.js similarity index 100% rename from 12_calculator/solution/calculator-solution.spec.js rename to foundations/12_calculator/solution/calculator-solution.spec.js diff --git a/13_palindromes/README.md b/foundations/13_palindromes/README.md similarity index 100% rename from 13_palindromes/README.md rename to foundations/13_palindromes/README.md diff --git a/13_palindromes/palindromes.js b/foundations/13_palindromes/palindromes.js similarity index 100% rename from 13_palindromes/palindromes.js rename to foundations/13_palindromes/palindromes.js diff --git a/13_palindromes/palindromes.spec.js b/foundations/13_palindromes/palindromes.spec.js similarity index 100% rename from 13_palindromes/palindromes.spec.js rename to foundations/13_palindromes/palindromes.spec.js diff --git a/13_palindromes/solution/palindromes-solution.js b/foundations/13_palindromes/solution/palindromes-solution.js similarity index 100% rename from 13_palindromes/solution/palindromes-solution.js rename to foundations/13_palindromes/solution/palindromes-solution.js diff --git a/13_palindromes/solution/palindromes-solution.spec.js b/foundations/13_palindromes/solution/palindromes-solution.spec.js similarity index 100% rename from 13_palindromes/solution/palindromes-solution.spec.js rename to foundations/13_palindromes/solution/palindromes-solution.spec.js diff --git a/14_fibonacci/README.md b/foundations/14_fibonacci/README.md similarity index 100% rename from 14_fibonacci/README.md rename to foundations/14_fibonacci/README.md diff --git a/14_fibonacci/fibonacci.js b/foundations/14_fibonacci/fibonacci.js similarity index 100% rename from 14_fibonacci/fibonacci.js rename to foundations/14_fibonacci/fibonacci.js diff --git a/14_fibonacci/fibonacci.spec.js b/foundations/14_fibonacci/fibonacci.spec.js similarity index 100% rename from 14_fibonacci/fibonacci.spec.js rename to foundations/14_fibonacci/fibonacci.spec.js diff --git a/14_fibonacci/solution/fibonacci-solution.js b/foundations/14_fibonacci/solution/fibonacci-solution.js similarity index 100% rename from 14_fibonacci/solution/fibonacci-solution.js rename to foundations/14_fibonacci/solution/fibonacci-solution.js diff --git a/14_fibonacci/solution/fibonacci-solution.spec.js b/foundations/14_fibonacci/solution/fibonacci-solution.spec.js similarity index 100% rename from 14_fibonacci/solution/fibonacci-solution.spec.js rename to foundations/14_fibonacci/solution/fibonacci-solution.spec.js diff --git a/15_getTheTitles/README.md b/foundations/15_getTheTitles/README.md similarity index 100% rename from 15_getTheTitles/README.md rename to foundations/15_getTheTitles/README.md diff --git a/15_getTheTitles/getTheTitles.js b/foundations/15_getTheTitles/getTheTitles.js similarity index 100% rename from 15_getTheTitles/getTheTitles.js rename to foundations/15_getTheTitles/getTheTitles.js diff --git a/15_getTheTitles/getTheTitles.spec.js b/foundations/15_getTheTitles/getTheTitles.spec.js similarity index 100% rename from 15_getTheTitles/getTheTitles.spec.js rename to foundations/15_getTheTitles/getTheTitles.spec.js diff --git a/15_getTheTitles/solution/getTheTitles-solution.js b/foundations/15_getTheTitles/solution/getTheTitles-solution.js similarity index 100% rename from 15_getTheTitles/solution/getTheTitles-solution.js rename to foundations/15_getTheTitles/solution/getTheTitles-solution.js diff --git a/15_getTheTitles/solution/getTheTitles-solution.spec.js b/foundations/15_getTheTitles/solution/getTheTitles-solution.spec.js similarity index 100% rename from 15_getTheTitles/solution/getTheTitles-solution.spec.js rename to foundations/15_getTheTitles/solution/getTheTitles-solution.spec.js diff --git a/16_findTheOldest/README.md b/foundations/16_findTheOldest/README.md similarity index 100% rename from 16_findTheOldest/README.md rename to foundations/16_findTheOldest/README.md diff --git a/16_findTheOldest/findTheOldest.js b/foundations/16_findTheOldest/findTheOldest.js similarity index 100% rename from 16_findTheOldest/findTheOldest.js rename to foundations/16_findTheOldest/findTheOldest.js diff --git a/16_findTheOldest/findTheOldest.spec.js b/foundations/16_findTheOldest/findTheOldest.spec.js similarity index 100% rename from 16_findTheOldest/findTheOldest.spec.js rename to foundations/16_findTheOldest/findTheOldest.spec.js diff --git a/16_findTheOldest/solution/findTheOldest-solution.js b/foundations/16_findTheOldest/solution/findTheOldest-solution.js similarity index 100% rename from 16_findTheOldest/solution/findTheOldest-solution.js rename to foundations/16_findTheOldest/solution/findTheOldest-solution.js diff --git a/16_findTheOldest/solution/findTheOldest-solution.spec.js b/foundations/16_findTheOldest/solution/findTheOldest-solution.spec.js similarity index 100% rename from 16_findTheOldest/solution/findTheOldest-solution.spec.js rename to foundations/16_findTheOldest/solution/findTheOldest-solution.spec.js diff --git a/generators/helpers.js b/generators/helpers.js index 65513343d65..0a8c8b8081e 100644 --- a/generators/helpers.js +++ b/generators/helpers.js @@ -1,30 +1,56 @@ const { readdir } = require("fs/promises"); +const { basename, dirname, join } = require("path"); function splitDirectoryName(directoryName) { + const exerciseDirectoryName = directoryName.endsWith("solution") + ? basename(dirname(directoryName)) + : basename(directoryName); return { - exerciseNumber: directoryName.match(/\d+/), - exerciseName: directoryName.match(/[a-z]+/i), + exerciseNumber: exerciseDirectoryName.match(/\d+/), + exerciseName: exerciseDirectoryName.match(/[a-z]+/i), }; } -async function getLatestExerciseDirectory() { +async function getDirsWithExercises(path) { + const ignoredDirs = ["archive", "node_modules", "generators"]; try { - const files = await readdir("./"); + const dirs = await readdir(join(process.cwd(), path), { + withFileTypes: true, + }); + const exerciseDirs = dirs.filter( + (entry) => + entry.isDirectory() && + !entry.name.startsWith(".") && + !ignoredDirs.includes(entry.name), + ); + return exerciseDirs.map((dir) => dir.name); + } catch { + return []; + } +} + +async function getLatestExerciseDirectory(path) { + try { + const files = await readdir(join(process.cwd(), path)); return files.findLast((file) => /^\d+_\w+$/.test(file)); - } catch (err) { - console.error(err); + } catch { + return "0"; } } -async function createExerciseDirectoryName(directoryName) { - const latestExerciseDirectory = await getLatestExerciseDirectory(); +async function createExerciseDirectoryName(exerciseName, path) { + const latestExerciseDirectory = await getLatestExerciseDirectory(path); const latestExerciseNumber = parseInt(latestExerciseDirectory.match(/^\d+/)); - if (latestExerciseDirectory === `${latestExerciseNumber}_${directoryName}`) { - throw new Error(`Exercise already exists with name "${directoryName}"`); + if (latestExerciseDirectory === `${latestExerciseNumber}_${exerciseName}`) { + throw new Error(`Exercise already exists with name "${exerciseName}"`); } - return `${latestExerciseNumber + 1}_${directoryName}`; + return `${latestExerciseNumber + 1}_${exerciseName}`; } -module.exports = { createExerciseDirectoryName, splitDirectoryName }; +module.exports = { + getDirsWithExercises, + createExerciseDirectoryName, + splitDirectoryName, +}; diff --git a/generators/writeExercise.js b/generators/writeExercise.js index 82d54aa814f..9de60a0050d 100644 --- a/generators/writeExercise.js +++ b/generators/writeExercise.js @@ -6,9 +6,9 @@ async function writeExercise(exercisePath) { const { exerciseName } = splitDirectoryName(exercisePath); const isSolutionFile = exercisePath.includes("/solution"); const exerciseContent = `const ${exerciseName} = function() { - ${isSolutionFile ? "// Replace this comment with the solution code" : ""} +${isSolutionFile ? " // Replace this comment with the solution code" : ""} }; - + // Do not edit below this line module.exports = ${exerciseName}; `; diff --git a/generators/writeExerciseSpec.js b/generators/writeExerciseSpec.js index e0aaf2bd554..5ddee0b5480 100644 --- a/generators/writeExerciseSpec.js +++ b/generators/writeExerciseSpec.js @@ -17,7 +17,7 @@ describe('${exerciseName}', () => { expect(${exerciseName}()).toBe(''); }); - + test${isSolutionFile ? "" : ".skip"}('Second test description', () => { // Replace this comment with any other necessary code, and update the expect line as necessary diff --git a/plopFile.js b/plopFile.js index 914659fc0a3..8e4261181af 100644 --- a/plopFile.js +++ b/plopFile.js @@ -1,46 +1,103 @@ const { mkdir } = require("fs/promises"); const { join } = require("path"); const { camelCase } = require("case-anything"); -const { createExerciseDirectoryName } = require("./generators/helpers"); +const { + createExerciseDirectoryName, + getDirsWithExercises, +} = require("./generators/helpers"); const { writeReadme } = require("./generators/writeReadme"); const { writeExercise } = require("./generators/writeExercise"); const { writeExerciseSpec } = require("./generators/writeExerciseSpec"); +/** + * @typedef {import('plop').NodePlopAPI} Plop + * @param {Plop} plop + */ module.exports = function (plop) { - plop.setActionType("createExercise", async function (answers) { - const { exerciseName } = answers; - if (!exerciseName) { - throw new Error( - `Invalid exerciseName. Expected: valid string. Actual: "${exerciseName}"` + const NEW_DIR_OPTION = ""; + + plop.setActionType( + "createExercise", + async function ({ pathForExercise, exerciseName }) { + if (!exerciseName) { + throw new Error( + `Invalid exerciseName. Expected: valid string. Actual: "${exerciseName}"`, + ); + } else if (!pathForExercise.length) { + throw new Error( + "The new exercise cannot be placed in the project root", + ); + } + + const camelExerciseName = camelCase(exerciseName); + const exerciseDirectoryName = await createExerciseDirectoryName( + camelExerciseName, + join(...pathForExercise), ); - } - - const camelExerciseName = camelCase(exerciseName); - const exerciseDirectoryName = await createExerciseDirectoryName( - camelExerciseName - ); - const basePath = join("./", exerciseDirectoryName); - const solutionPath = join(basePath, "solution"); - - await mkdir(basePath); - await mkdir(solutionPath); - - await writeReadme(basePath); - await writeExercise(basePath); - await writeExercise(solutionPath); - await writeExerciseSpec(basePath); - await writeExerciseSpec(solutionPath); - }); + const basePath = join( + process.cwd(), + ...pathForExercise, + exerciseDirectoryName, + ); + const solutionPath = join(basePath, "solution"); + + await mkdir(basePath, { recursive: true }); + await mkdir(solutionPath); + + await writeReadme(basePath); + await writeExercise(basePath); + await writeExercise(solutionPath); + await writeExerciseSpec(basePath); + await writeExerciseSpec(solutionPath); + }, + ); plop.setGenerator("Basic", { description: "Create a basic JavaScript exercise.", - prompts: [ - { + prompts: async function (inquirer) { + async function getPathForExercise(dirPath = []) { + const exerciseDirs = await getDirsWithExercises(dirPath.join("/")); + + // Will only be empty when entering a new dir on a recursive call + // Recursive call only happens when new dir required which can bypass this question + const { dir } = exerciseDirs.length + ? await inquirer.prompt({ + type: "list", + name: "dir", + message: "Which directory should this exercise go in?", + choices: [NEW_DIR_OPTION, ...exerciseDirs], + }) + : { dir: NEW_DIR_OPTION }; + + if (dir === NEW_DIR_OPTION) { + const { newDirName } = await inquirer.prompt({ + type: "input", + name: "newDirName", + message: "What is the name of the new directory?", + }); + dirPath.push(newDirName); + } else { + dirPath.push(dir); + } + + const { needMoreDirs } = await inquirer.prompt({ + type: "confirm", + name: "needMoreDirs", + message: "Does this exercise need to be nested in a subdirectory?", + }); + + return needMoreDirs ? await getPathForExercise(dirPath) : dirPath; + } + + const pathForExercise = await getPathForExercise(); + const { exerciseName } = await inquirer.prompt({ type: "input", name: "exerciseName", - message: "What is the name of the exercise? (camelCase)", - }, - ], + message: "What is the name of the new exercise (in camelCase)?", + }); + + return { pathForExercise, exerciseName }; + }, actions: [{ type: "createExercise" }], }); };