diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..33c9829
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,79 @@
+name: Step-time Biofeedback Project
+
+on:
+ push:
+ branches:
+ - feature/*
+ pull_request:
+ branches:
+ - feature/*
+ workflow_dispatch:
+
+env:
+ BUILD_TYPE: Release
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [20.x]
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.x'
+
+ - name: Download and cache virtual environment
+ run: |
+ pip install virtualenv
+ virtualenv env
+ source env/bin/activate
+ pip install -r requirements.txt
+
+ - name: Install frontend dependencies
+ run: |
+ cd ${{github.workspace}}/frontend
+ npm install
+ npm test
+
+ - name: Run backend tests
+ run: |
+ source env/bin/activate
+ cd ${{github.workspace}}/backend
+ pytest -s websocketUnitTest.py
+
+
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.x'
+
+ - name: Download and cache virtual environment
+ run: |
+ pip install virtualenv
+ virtualenv env
+ source env/bin/activate
+ pip install -r requirements.txt
+
+ - name: Lint Python Files
+ run: |
+ cd ${{github.workspace}}/backend
+ pylint *.py || true
+
+ - name: Lint JavaScript files
+ run: |
+ cd ${{github.workspace}}/frontend
+ npm install
+ npm run lint
\ No newline at end of file
diff --git a/backend/connect_to_qtm.py b/backend/connect_to_qtm.py
index 029f7b3..4130184 100644
--- a/backend/connect_to_qtm.py
+++ b/backend/connect_to_qtm.py
@@ -14,7 +14,7 @@ def stream_data (stream_type= 'Force', sleep_time= 0.1):
return
# create an inlet to read from the stream
- inlet= StreamInlet(stream[0])
+ inlet= StreamInlet(streams[0])
# pull and log samples
try:
@@ -25,6 +25,6 @@ def stream_data (stream_type= 'Force', sleep_time= 0.1):
except KeyboardInterrupt:
print("Streaming stopped by user.")
- if __name__ == "__main__":
+if __name__ == "__main__":
stream_data()
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 0366338..d83c345 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -17,6 +17,7 @@
},
"devDependencies": {
"@testing-library/react": "^16.0.1",
+ "eslint": "^8.57.1",
"jest": "^27.5.1",
"jest-websocket-mock": "^2.5.0",
"react-test-renderer": "^18.3.1"
@@ -108,9 +109,9 @@
}
},
"node_modules/@babel/eslint-parser": {
- "version": "7.25.1",
- "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz",
- "integrity": "sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.8.tgz",
+ "integrity": "sha512-Po3VLMN7fJtv0nsOjBDSbO1J71UhzShE9MuOSkWEV9IZQXzhZklYtzKZ8ZD/Ij3a0JBv1AG3Ny2L3jvAHQVOGg==",
"dependencies": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
"eslint-visitor-keys": "^2.1.0",
@@ -2371,20 +2372,20 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
- "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.14",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
- "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
"deprecated": "Use @eslint/config-array instead",
"dependencies": {
- "@humanwhocodes/object-schema": "^2.0.2",
+ "@humanwhocodes/object-schema": "^2.0.3",
"debug": "^4.3.1",
"minimatch": "^3.0.5"
},
@@ -4208,9 +4209,9 @@
}
},
"node_modules/@types/estree": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
},
"node_modules/@types/express": {
"version": "4.17.21",
@@ -7323,9 +7324,9 @@
}
},
"node_modules/es-iterator-helpers": {
- "version": "1.0.19",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz",
- "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz",
+ "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
@@ -7334,12 +7335,12 @@
"es-set-tostringtag": "^2.0.3",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
- "globalthis": "^1.0.3",
+ "globalthis": "^1.0.4",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.7",
- "iterator.prototype": "^1.1.2",
+ "iterator.prototype": "^1.1.3",
"safe-array-concat": "^1.1.2"
},
"engines": {
@@ -7450,15 +7451,16 @@
}
},
"node_modules/eslint": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
- "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -7549,9 +7551,9 @@
}
},
"node_modules/eslint-module-utils": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz",
- "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dependencies": {
"debug": "^3.2.7"
},
@@ -7590,9 +7592,9 @@
}
},
"node_modules/eslint-plugin-import": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz",
- "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@@ -7602,7 +7604,7 @@
"debug": "^3.2.7",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.9",
- "eslint-module-utils": "^2.9.0",
+ "eslint-module-utils": "^2.12.0",
"hasown": "^2.0.2",
"is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
@@ -7611,13 +7613,14 @@
"object.groupby": "^1.0.3",
"object.values": "^1.2.0",
"semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
"tsconfig-paths": "^3.15.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
}
},
"node_modules/eslint-plugin-import/node_modules/debug": {
@@ -7700,9 +7703,9 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.35.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz",
- "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==",
+ "version": "7.37.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.1.tgz",
+ "integrity": "sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==",
"dependencies": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
@@ -10201,15 +10204,18 @@
}
},
"node_modules/iterator.prototype": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
- "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz",
+ "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==",
"dependencies": {
"define-properties": "^1.2.1",
"get-intrinsic": "^1.2.1",
"has-symbols": "^1.0.3",
"reflect.getprototypeof": "^1.0.4",
"set-function-name": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/jackspeak": {
@@ -18857,9 +18863,9 @@
}
},
"@babel/eslint-parser": {
- "version": "7.25.1",
- "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz",
- "integrity": "sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==",
+ "version": "7.25.8",
+ "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.8.tgz",
+ "integrity": "sha512-Po3VLMN7fJtv0nsOjBDSbO1J71UhzShE9MuOSkWEV9IZQXzhZklYtzKZ8ZD/Ij3a0JBv1AG3Ny2L3jvAHQVOGg==",
"requires": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
"eslint-visitor-keys": "^2.1.0",
@@ -20295,16 +20301,16 @@
}
},
"@eslint/js": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
- "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g=="
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="
},
"@humanwhocodes/config-array": {
- "version": "0.11.14",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
- "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
"requires": {
- "@humanwhocodes/object-schema": "^2.0.2",
+ "@humanwhocodes/object-schema": "^2.0.3",
"debug": "^4.3.1",
"minimatch": "^3.0.5"
}
@@ -21603,9 +21609,9 @@
}
},
"@types/estree": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
},
"@types/express": {
"version": "4.17.21",
@@ -23917,9 +23923,9 @@
}
},
"es-iterator-helpers": {
- "version": "1.0.19",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz",
- "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz",
+ "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==",
"requires": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
@@ -23928,12 +23934,12 @@
"es-set-tostringtag": "^2.0.3",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
- "globalthis": "^1.0.3",
+ "globalthis": "^1.0.4",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.7",
- "iterator.prototype": "^1.1.2",
+ "iterator.prototype": "^1.1.3",
"safe-array-concat": "^1.1.2"
}
},
@@ -24013,15 +24019,15 @@
}
},
"eslint": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
- "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -24208,9 +24214,9 @@
}
},
"eslint-module-utils": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz",
- "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"requires": {
"debug": "^3.2.7"
},
@@ -24235,9 +24241,9 @@
}
},
"eslint-plugin-import": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz",
- "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"requires": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@@ -24247,7 +24253,7 @@
"debug": "^3.2.7",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.9",
- "eslint-module-utils": "^2.9.0",
+ "eslint-module-utils": "^2.12.0",
"hasown": "^2.0.2",
"is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
@@ -24256,6 +24262,7 @@
"object.groupby": "^1.0.3",
"object.values": "^1.2.0",
"semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
"tsconfig-paths": "^3.15.0"
},
"dependencies": {
@@ -24314,9 +24321,9 @@
}
},
"eslint-plugin-react": {
- "version": "7.35.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz",
- "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==",
+ "version": "7.37.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.1.tgz",
+ "integrity": "sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==",
"requires": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
@@ -25919,9 +25926,9 @@
}
},
"iterator.prototype": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
- "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz",
+ "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==",
"requires": {
"define-properties": "^1.2.1",
"get-intrinsic": "^1.2.1",
diff --git a/frontend/package.json b/frontend/package.json
index 34d4c19..42faae5 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,7 +14,8 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
- "eject": "react-scripts eject"
+ "eject": "react-scripts eject",
+ "lint": "eslint ."
},
"eslintConfig": {
"extends": [
@@ -36,6 +37,7 @@
},
"devDependencies": {
"@testing-library/react": "^16.0.1",
+ "eslint": "^8.57.1",
"jest": "^27.5.1",
"jest-websocket-mock": "^2.5.0",
"react-test-renderer": "^18.3.1"
diff --git a/frontend/src/App.js b/frontend/src/App.js
index fb516c0..38b8a0a 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -17,7 +17,7 @@ function App() {
};
let websocket = useRef(null);
- let websocketConnected = false;
+ // let websocketConnected = false;
useEffect(() => {
websocket.current = new WebSocket("ws://localhost:8000/ws");
@@ -25,7 +25,7 @@ function App() {
websocket.current.onopen = () => {
console.log("WebSocket Connected to React");
websocket.current.send("Websocket Connected to React")
- websocketConnected = true;
+ // websocketConnected = true;
};
websocket.current.onmessage = function(event) {
@@ -34,7 +34,7 @@ function App() {
websocket.current.onclose = (event) => {
console.log("WebSocket connection closed: ", event);
- websocketConnected = false;
+ // websocketConnected = false;
};
return () => {
diff --git a/frontend/src/App.test.js b/frontend/src/App.test.js
deleted file mode 100644
index dc5925b..0000000
--- a/frontend/src/App.test.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import { render } from '@testing-library/react';
-import { act } from 'react';
-import App from './App';
-import WS from 'jest-websocket-mock';
-
-describe('WebSocket in App Component', () => {
- let server;
-
- beforeEach(() => {
- server = new WS("ws://localhost:8000/ws");
- });
-
- afterEach(() => {
- server.close();
- WS.clean();
- });
-
- test('WebSocket connection messages', async () => {
- const consoleLogSpy = jest.spyOn(console, 'log');
-
- await act(async () => {
- render();
- });
-
- await server.connected;
-
- server.send("Message from backend");
-
- await act(async () => {
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
-
- expect(consoleLogSpy).toHaveBeenCalledWith("Data received from backend: ", "Message from backend");
-
- consoleLogSpy.mockRestore();
-
- });
- test('Message on WebSocket connection open', async () => {
- await act(async () => {
- render();
- });
-
- // Wait for the server connection to be established
- await server.connected;
-
- // Wait a bit to ensure the message is sent
- await act(async () => {
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
-
- // Check if the WebSocket has received the expected message
- expect(server).toHaveReceivedMessages(["Websocket Connected to React"]);
-
- });
-
-
-
- test("User is notified on WS Close", async () => {
- const consoleLogSpy = jest.spyOn(console, 'log');
-
- await act(async () => {
- render();
- });
-
- await server.connected;
-
- // Simulate WebSocket close
- await act(async () => {
- server.close();
- });
-
- // Check if "WebSocket connection closed" is logged
- expect(consoleLogSpy).toHaveBeenCalledWith("WebSocket connection closed: ", expect.any(Object));
-
- consoleLogSpy.mockRestore();
- });
-});
diff --git a/frontend/src/__tests__/App.test.js b/frontend/src/__tests__/App.test.js
index 45d533c..7a3921a 100644
--- a/frontend/src/__tests__/App.test.js
+++ b/frontend/src/__tests__/App.test.js
@@ -1,77 +1,76 @@
-import { render, screen, fireEvent } from '@testing-library/react';
-import App from '../App';
-import useStepTime from '../useStepTime';
-import { act } from 'react';
-import WS from 'jest-websocket-mock';
+import { render, screen, fireEvent } from "@testing-library/react";
+import App from "../App";
+import useStepTime from "../useStepTime";
+import WS from "jest-websocket-mock";
-jest.mock('../useStepTime');
+jest.mock("../useStepTime");
-test('Step Time Component is rendered on screen', () => {
+test("Step Time Component is rendered on screen", () => {
useStepTime.mockReturnValue({
left: 0,
right: 0,
targetZones: {
left: { min: 25, max: 30 },
- right: { min: 50, max: 45 }
- }
+ right: { min: 50, max: 45 },
+ },
});
-
+
render();
- expect(screen.getByTestId('step-time-digits-view')).toBeInTheDocument();
+ expect(screen.getByTestId("step-time-digits-view")).toBeInTheDocument();
});
-describe('Navbar Component', () => {
+describe("Navbar Component", () => {
beforeEach(() => {
useStepTime.mockReturnValue({
left: 0,
right: 0,
targetZones: {
left: { min: 25, max: 30 },
- right: { min: 50, max: 45 }
- }
+ right: { min: 50, max: 45 },
+ },
});
});
- test('Navbar is rendered on screen', () => {
+ test("Navbar is rendered on screen", () => {
render();
- expect(screen.getByRole('navigation')).toBeInTheDocument();
+ expect(screen.getByRole("navigation")).toBeInTheDocument();
});
- describe('View Swapping', () => {
- test('Navbar swap renders StepTimeChart view', () => {
+ describe("View Swapping", () => {
+ test("Navbar swap renders StepTimeChart view", () => {
render();
- fireEvent.click(screen.getByTestId('step-time-chart-nav'));
- expect(screen.getByTestId('step-time-chart-view')).toBeInTheDocument();
+ fireEvent.click(screen.getByTestId("step-time-chart-nav"));
+ expect(screen.getByTestId("step-time-chart-view")).toBeInTheDocument();
});
-
- test('Navbar swap renders StepTimeGraph view', () => {
+
+ test("Navbar swap renders StepTimeGraph view", () => {
render();
- fireEvent.click(screen.getByTestId('step-time-graph-nav'));
- expect(screen.getByTestId('step-time-graph-view')).toBeInTheDocument();
+ fireEvent.click(screen.getByTestId("step-time-graph-nav"));
+ expect(screen.getByTestId("step-time-graph-view")).toBeInTheDocument();
});
-
- test('Navbar swap renders StepTimeDigits view', () => {
+
+ test("Navbar swap renders StepTimeDigits view", () => {
render();
- fireEvent.click(screen.getByTestId('step-time-graph-nav'));
- fireEvent.click(screen.getByTestId('step-time-digits-nav'));
- expect(screen.getByTestId('step-time-digits-view')).toBeInTheDocument();
+ fireEvent.click(screen.getByTestId("step-time-graph-nav"));
+ fireEvent.click(screen.getByTestId("step-time-digits-nav"));
+ expect(screen.getByTestId("step-time-digits-view")).toBeInTheDocument();
});
});
});
-describe('WebSocket in App Component', () => {
+describe("WebSocket in App Component", () => {
let server;
beforeEach(() => {
server = new WS("ws://localhost:8000/ws");
-
+
useStepTime.mockReturnValue({
left: 0,
right: 0,
targetZones: {
left: { min: 25, max: 30 },
- right: { min: 50, max: 45 }
- }
+ right: { min: 50, max: 45 },
+ },
});
});
@@ -79,33 +78,48 @@ describe('WebSocket in App Component', () => {
WS.clean();
});
- test('WebSocket connection messages', async () => {
- const consoleLogSpy = jest.spyOn(console, 'log');
+ test("WebSocket connection messages", async () => {
+ const consoleLogSpy = jest.spyOn(console, "log");
- await act(async () => {
- render();
- });
+ render(); // Removed act wrapper
await server.connected;
server.send("Message from backend");
- await act(async () => {
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
+ // Await for the effects of the message
+ await new Promise((resolve) => setTimeout(resolve, 100));
- expect(consoleLogSpy).toHaveBeenCalledWith("Data received from backend: ", "Message from backend");
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ "Data received from backend: ",
+ "Message from backend"
+ );
consoleLogSpy.mockRestore();
});
- test('Message on WebSocket connection open', async () => {
- await act(async () => {
- render();
- });
+ test("Message on WebSocket connection open", async () => {
+ render(); // Removed act wrapper
await server.connected;
expect(server).toReceiveMessage("Websocket Connected to React");
});
-});
\ No newline at end of file
+
+ test("User is notified on WS Close", async () => {
+ const consoleLogSpy = jest.spyOn(console, "log");
+
+ render(); // Removed act wrapper
+
+ await server.connected;
+
+ server.close(); // Removed act wrapper
+
+ expect(consoleLogSpy).toHaveBeenCalledWith(
+ "WebSocket connection closed: ",
+ expect.any(Object)
+ );
+
+ consoleLogSpy.mockRestore();
+ });
+});
diff --git a/backend/requirements.txt b/requirements.txt
similarity index 72%
rename from backend/requirements.txt
rename to requirements.txt
index a37b4cb..058bc2e 100644
--- a/backend/requirements.txt
+++ b/requirements.txt
@@ -12,4 +12,9 @@ pytest==8.3.3
httpcore==1.0.5
httpx==0.27.2
pytest-asyncio==0.24.0
-websockets==13.1
\ No newline at end of file
+websockets==13.1
+astroid==3.3.5
+dill==0.3.9
+isort==5.13.2
+pylint==3.3.1
+tomlkit==0.13.2
\ No newline at end of file