From 78e394311081ef2df109363fea0605507f74b9c7 Mon Sep 17 00:00:00 2001 From: Derek Ledoux Date: Thu, 25 Apr 2024 10:38:11 -0400 Subject: [PATCH] setting up challenge --- .github/workflows/go.yml | 29 +++++++++++++++++++++++++ .github/workflows/javascript.yml | 25 +++++++++++++++++++++ .github/workflows/python.yml | 31 ++++++++++++++++++++++++++ .github/workflows/ruby.yml | 28 ++++++++++++++++++++++++ .github/workflows/typescript.yml | 36 +++++++++++++++++++++++++++++++ .gitignore | 3 +++ .vscode/settings.json | 5 +++++ README.md | 37 ++++++++++++++++++++++++++++++++ go/README.md | 3 +++ go/go.mod | 3 +++ go/solution.go | 1 + go/solution_test.go | 24 +++++++++++++++++++++ javascript/README.md | 4 ++++ javascript/package.json | 14 ++++++++++++ javascript/solution.js | 0 javascript/solution.test.js | 12 +++++++++++ python/README.md | 3 +++ python/solution.py | 0 python/solution.test.py | 15 +++++++++++++ ruby/Gemfile | 3 +++ ruby/README.md | 3 +++ ruby/solution.rb | 0 ruby/solution.test.rb | 6 ++++++ typescript/README.md | 4 ++++ typescript/jest.config.js | 4 ++++ typescript/package.json | 20 +++++++++++++++++ typescript/solution.test.ts | 13 +++++++++++ typescript/solution.ts | 0 28 files changed, 326 insertions(+) create mode 100644 .github/workflows/go.yml create mode 100644 .github/workflows/javascript.yml create mode 100644 .github/workflows/python.yml create mode 100644 .github/workflows/ruby.yml create mode 100644 .github/workflows/typescript.yml create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 go/README.md create mode 100644 go/go.mod create mode 100644 go/solution.go create mode 100644 go/solution_test.go create mode 100644 javascript/README.md create mode 100644 javascript/package.json create mode 100644 javascript/solution.js create mode 100644 javascript/solution.test.js create mode 100644 python/README.md create mode 100644 python/solution.py create mode 100644 python/solution.test.py create mode 100644 ruby/Gemfile create mode 100644 ruby/README.md create mode 100644 ruby/solution.rb create mode 100644 ruby/solution.test.rb create mode 100644 typescript/README.md create mode 100644 typescript/jest.config.js create mode 100644 typescript/package.json create mode 100644 typescript/solution.test.ts create mode 100644 typescript/solution.ts diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..398119c --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,29 @@ +name: PR Tests + +on: + pull_request: + branches: + - main + paths: + - 'go/**' + +jobs: + go-tests: + name: Run Go Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - id: changes + uses: jitterbit/get-changed-files@v1 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: '1.21.5' # Specify your Go version here + + - name: Set Environment Variable + run: echo "TEST_ANSWER=${{ secrets.TEST_ANSWER }}" >> $GITHUB_ENV + + - name: Run Go Tests + run: cd go && go test ./... \ No newline at end of file diff --git a/.github/workflows/javascript.yml b/.github/workflows/javascript.yml new file mode 100644 index 0000000..6b1fc8f --- /dev/null +++ b/.github/workflows/javascript.yml @@ -0,0 +1,25 @@ +name: PR Tests + +on: + pull_request: + branches: + - main + paths: + - 'javascript/**' + +jobs: + javascript-tests: + name: Run JavaScript Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - id: changes + uses: jitterbit/get-changed-files@v1 + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + - name: Set Environment Variable + run: echo "TEST_ANSWER=${{ secrets.TEST_ANSWER }}" >> $GITHUB_ENV + - run: cd javascript && npm install + - run: cd javascript && npm test diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 0000000..a746f7e --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,31 @@ +name: PR Tests + +on: + pull_request: + branches: + - main + paths: + - 'python/**' + +jobs: + python-tests: + name: Run Python Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - id: changes + uses: jitterbit/get-changed-files@v1 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.8' # Specify the Python version here + + - name: Set Environment Variable + run: echo "TEST_ANSWER=${{ secrets.TEST_ANSWER }}" >> $GITHUB_ENV + + - name: Run Python Tests + run: | + cd python + python3 solution.test.py \ No newline at end of file diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml new file mode 100644 index 0000000..a4f2e3a --- /dev/null +++ b/.github/workflows/ruby.yml @@ -0,0 +1,28 @@ +name: PR Tests + +on: + pull_request: + branches: + - main + paths: + - 'ruby/**' + +jobs: + ruby-tests: + name: Run Ruby Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.0' + bundler-cache: true + + - name: Set Environment Variable + run: echo "TEST_ANSWER=${{ secrets.TEST_ANSWER }}" >> $GITHUB_ENV + + - run: cd ruby && bundle install + - run: cd ruby && rspec solution.test.rb diff --git a/.github/workflows/typescript.yml b/.github/workflows/typescript.yml new file mode 100644 index 0000000..249ed39 --- /dev/null +++ b/.github/workflows/typescript.yml @@ -0,0 +1,36 @@ +name: PR Tests + +on: + pull_request: + branches: + - main + paths: + - 'typescript/**' + +jobs: + typescript-tests: + name: Run TypeScript Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - id: changes + uses: jitterbit/get-changed-files@v1 + + - name: Setup Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: Set Environment Variable + run: echo "TEST_ANSWER=${{ secrets.TEST_ANSWER }}" >> $GITHUB_ENV + + - name: Install dependencies + run: | + cd typescript + npm install + + - name: Run TypeScript Tests + run: | + cd typescript + npm test \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c6e07c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +package-lock.json +Gemfile.lock \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ce1c6cc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "Thematics" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5a19ae2 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# Engineering Internship +## Technical Assessment Challenge + +### Playfair Cipher Solver + +#### Challenge +Your goal is to build an application that can solve a Playfair Cipher. To learn more about Playfair Ciphers and how they are constructed, consult the following Wikipedia page on the subject: [https://en.wikipedia.org/wiki/Playfair_cipher](https://en.wikipedia.org/wiki/Playfair_cipher). + +Ideally this challenge should be able to be completed in 3 hours or less. You may choose one of the 5 following programming languages to complete this challenge: +- Ruby +- JavaScript +- TypeScript +- Python +- Go + +Ensure your code is properly commented and formatted for readability and ease-of-understanding. + +#### Thematics +*"Attention spy network! You've been assigned a task of the utmost importance! We've received an encrypted message from an agent in the field containing the password to a top secret club for super spies. The encrypted message reads as follows: **"IKEWENENXLNQLPZSLERUMRHEERYBOFNEINCHCV"**. We've been told if we can crack this code and give the password to the door-person at the corner of 32nd Street, we will gain access to the illustrious spy club **Spy City**! We must get inside! However the password has been encrypted with an older system known as a **Playfair Cipher**. Our agent in the field says the key to the cipher is the string **"SUPERSPIES"**. However, for the life of us we cannot crack this code! Devise an application that can solve this encryption, get the password, and join us inside Spy City for what we are sure will be a night to remember!"* + +#### Instructions +1. Fork this repo to your personal Github account. +2. Clone your forked repo to begin working on the challenge locally. +3. Create a new Branch in your repo where you will be pushing your code to. +4. Choose which programming language you wish to complete the challenge with. + - Navigate to the folder of that programming language and complete your work in the `solution` file found inside. ie: `ruby/solution.rb` + - **Do not** edit the test file in the folder. Tests will only work as intended after you have submitted a PR. + - You'll find a separate `README.md` in that folder with language specific instructions. +5. Ensure your application is executable from the command-line by running your `solution` file. +6. Your decrypted string must by entirely **UPPER CASE**, and not include `spaces`, the letter `"X"`, or `special characters`. Ensure you meet all these conditions before outputting the result. +7. Your application must output ***only*** the decrypted Playfair Cipher string. + - ie: `BANANAS` ***not*** `The decrypted text is: BANANAS` + +#### Submission +Upon completion of the challenge, create a PR of your work and compare it against the original Assessment Repo's `main` branch. Submit a link to your PR with your internship application in the appropriate field. + +This repo is designed to run a test against your work to ensure the correct decrypted string is outputted to the console when executing your code. Admins on this repo will deploy the test manually only after you have submitted your PR. \ No newline at end of file diff --git a/go/README.md b/go/README.md new file mode 100644 index 0000000..db6932f --- /dev/null +++ b/go/README.md @@ -0,0 +1,3 @@ +# Go Instructions + +- Ensure your code can run in the command-line with the command `go run solution.go` \ No newline at end of file diff --git a/go/go.mod b/go/go.mod new file mode 100644 index 0000000..87c0cd8 --- /dev/null +++ b/go/go.mod @@ -0,0 +1,3 @@ +module solution + +go 1.21.5 diff --git a/go/solution.go b/go/solution.go new file mode 100644 index 0000000..06ab7d0 --- /dev/null +++ b/go/solution.go @@ -0,0 +1 @@ +package main diff --git a/go/solution_test.go b/go/solution_test.go new file mode 100644 index 0000000..cade6cd --- /dev/null +++ b/go/solution_test.go @@ -0,0 +1,24 @@ +package main + +import ( + "os" + "os/exec" + "strings" + "testing" +) + +func TestSolutionOutput(t *testing.T) { + cmd := exec.Command("go", "run", "solution.go") + outputBytes, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Failed to run the command: %v", err) + } + + // Trim space from output and expected value + output := strings.TrimSpace(string(outputBytes)) + expected := strings.TrimSpace(os.Getenv("TEST_ANSWER")) + + if output != expected { + t.Errorf("Unexpected output, got: %q, want: %q", output, expected) + } +} diff --git a/javascript/README.md b/javascript/README.md new file mode 100644 index 0000000..ca22aff --- /dev/null +++ b/javascript/README.md @@ -0,0 +1,4 @@ +# JavaScript Instructions + +- Install all dependencies with the command `npm install` +- Ensure your code can run in the command-line with the command `node solution.js` \ No newline at end of file diff --git a/javascript/package.json b/javascript/package.json new file mode 100644 index 0000000..23f0e39 --- /dev/null +++ b/javascript/package.json @@ -0,0 +1,14 @@ +{ + "name": "javascript", + "version": "1.0.0", + "description": "", + "main": "solution.js", + "scripts": { + "test": "jest" + }, + "author": "", + "license": "ISC", + "dependencies": { + "jest": "^29.7.0" + } +} diff --git a/javascript/solution.js b/javascript/solution.js new file mode 100644 index 0000000..e69de29 diff --git a/javascript/solution.test.js b/javascript/solution.test.js new file mode 100644 index 0000000..72ec205 --- /dev/null +++ b/javascript/solution.test.js @@ -0,0 +1,12 @@ +const { exec } = require("child_process"); + +describe('solution.js script', () => { + it('should output correct answer to the console', (done) => { + exec("node solution.js", (error, stdout, stderr) => { + expect(error).toBeNull(); + expect(stderr).toBe(""); + expect(stdout.trim()).toBe(process.env.TEST_ANSWER); // trim to remove any extra newlines that console.log might generate + done(); // indicate that this async test is complete + }); + }); +}); diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..73ba16e --- /dev/null +++ b/python/README.md @@ -0,0 +1,3 @@ +# Python Instructions + +- Ensure your code can run in the command-line with the command `python3 solution.py` \ No newline at end of file diff --git a/python/solution.py b/python/solution.py new file mode 100644 index 0000000..e69de29 diff --git a/python/solution.test.py b/python/solution.test.py new file mode 100644 index 0000000..1da56ff --- /dev/null +++ b/python/solution.test.py @@ -0,0 +1,15 @@ +import unittest +import subprocess +import os + +class TestSolution(unittest.TestCase): + def test_decryption_output(self): + # Run the solution.py script + result = subprocess.run(['python3', 'solution.py'], text=True, capture_output=True) + + # Check the output + expected_output = os.getenv('TEST_ANSWER') + self.assertEqual(result.stdout.strip(), expected_output) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/ruby/Gemfile b/ruby/Gemfile new file mode 100644 index 0000000..4a05f85 --- /dev/null +++ b/ruby/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "rspec" diff --git a/ruby/README.md b/ruby/README.md new file mode 100644 index 0000000..f666acc --- /dev/null +++ b/ruby/README.md @@ -0,0 +1,3 @@ +# Ruby Instructions + +- Ensure your code can run in the command-line with the command `ruby solution.rb` \ No newline at end of file diff --git a/ruby/solution.rb b/ruby/solution.rb new file mode 100644 index 0000000..e69de29 diff --git a/ruby/solution.test.rb b/ruby/solution.test.rb new file mode 100644 index 0000000..e76f4fa --- /dev/null +++ b/ruby/solution.test.rb @@ -0,0 +1,6 @@ +RSpec.describe 'Playfair Decryption Script' do + it 'outputs the correct decrypted text' do + output = `ruby solution.rb` # Using backticks to execute the script and capture the output. + expect(output.strip).to eq(ENV['TEST_ANSWER']) # Compares the stripped output to the expected string. + end +end diff --git a/typescript/README.md b/typescript/README.md new file mode 100644 index 0000000..8e4d139 --- /dev/null +++ b/typescript/README.md @@ -0,0 +1,4 @@ +# TypeScript Instructions + +- Install all dependencies with the command `npm install` +- Ensure your code can run in the command-line with the command `ts-node solution.ts` or `npx ts-node solution.ts` \ No newline at end of file diff --git a/typescript/jest.config.js b/typescript/jest.config.js new file mode 100644 index 0000000..91a2d2c --- /dev/null +++ b/typescript/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; \ No newline at end of file diff --git a/typescript/package.json b/typescript/package.json new file mode 100644 index 0000000..56d9d7b --- /dev/null +++ b/typescript/package.json @@ -0,0 +1,20 @@ +{ + "name": "typescript", + "version": "1.0.0", + "description": "", + "main": "solution.js", + "scripts": { + "test": "jest" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "^20.12.7", + "jest": "^29.7.0", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" + } +} diff --git a/typescript/solution.test.ts b/typescript/solution.test.ts new file mode 100644 index 0000000..e329198 --- /dev/null +++ b/typescript/solution.test.ts @@ -0,0 +1,13 @@ +import { exec } from 'child_process'; +import { promisify } from 'util'; + +const execAsync = promisify(exec); + +describe('solution.ts output', () => { + it('should print the correct output to the console', async () => { + const { stdout } = await execAsync('ts-node solution.ts'); + + const expected = process.env.TEST_ANSWER; + expect(stdout.trim()).toBe(expected); + }); +}); \ No newline at end of file diff --git a/typescript/solution.ts b/typescript/solution.ts new file mode 100644 index 0000000..e69de29