From 2ff4fc3dcfc946ae2346a4055d2faa92efee46c9 Mon Sep 17 00:00:00 2001
From: Jordan Hisel
Date: Wed, 6 Oct 2021 19:38:29 -0700
Subject: [PATCH 1/2] beefed up testing suite with mutually recursive
components, redux connections, integration tests
Co-authored-by: Charles Gutwirth
Co-authored-by: Lindsay Baird
Co-authored-by: Paul Coster
---
sapling/package.json | 3 +-
sapling/src/test/suite/extension.test.ts | 37 +++-
sapling/src/test/suite/parser.test.ts | 79 ++++++-
sapling/src/test/test_apps/test_2/index.js | 2 +
sapling/src/test/test_apps/test_3/App.jsx | 21 ++
.../test/test_apps/test_3/actions/actions.js | 10 +
.../test/test_apps/test_3/components/App.jsx | 55 -----
.../test_3/components/DrillCreator.jsx | 204 -----------------
.../test_3/components/ExerciseCreator.jsx | 208 ------------------
.../test_3/components/ExercisesDisplay.jsx | 42 ----
.../test_3/components/HistoryDisplay.jsx | 40 ----
.../test_apps/test_3/components/Login.jsx | 115 ----------
.../test_apps/test_3/components/Logout.jsx | 11 -
.../test/test_apps/test_3/components/Nav.jsx | 40 ----
.../test_apps/test_3/components/Signup.jsx | 129 -----------
.../test_apps/test_3/constants/actionTypes.js | 3 +
.../test_3/containers/ConnectedContainer.jsx | 28 +++
.../containers/UnconnectedContainer.jsx | 13 ++
sapling/src/test/test_apps/test_3/index.html | 18 ++
sapling/src/test/test_apps/test_3/index.js | 13 ++
sapling/src/test/test_apps/test_3/index.jsx | 18 --
.../test_apps/test_3/reducers/fakeReducer.js | 27 +++
.../test/test_apps/test_3/reducers/index.js | 6 +
sapling/src/test/test_apps/test_3/store.js | 12 +
.../test/test_apps/test_8/components/App.jsx | 3 +-
.../test/test_apps/test_9/components/App.jsx | 7 +-
sapling/src/test/test_apps/test_9/index.js | 2 +-
27 files changed, 260 insertions(+), 886 deletions(-)
create mode 100644 sapling/src/test/test_apps/test_3/App.jsx
create mode 100644 sapling/src/test/test_apps/test_3/actions/actions.js
delete mode 100644 sapling/src/test/test_apps/test_3/components/App.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/DrillCreator.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/ExerciseCreator.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/ExercisesDisplay.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/HistoryDisplay.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/Login.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/Logout.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/Nav.jsx
delete mode 100644 sapling/src/test/test_apps/test_3/components/Signup.jsx
create mode 100644 sapling/src/test/test_apps/test_3/constants/actionTypes.js
create mode 100644 sapling/src/test/test_apps/test_3/containers/ConnectedContainer.jsx
create mode 100644 sapling/src/test/test_apps/test_3/containers/UnconnectedContainer.jsx
create mode 100644 sapling/src/test/test_apps/test_3/index.html
create mode 100644 sapling/src/test/test_apps/test_3/index.js
delete mode 100644 sapling/src/test/test_apps/test_3/index.jsx
create mode 100644 sapling/src/test/test_apps/test_3/reducers/fakeReducer.js
create mode 100644 sapling/src/test/test_apps/test_3/reducers/index.js
create mode 100644 sapling/src/test/test_apps/test_3/store.js
diff --git a/sapling/package.json b/sapling/package.json
index ed179fe..39329ff 100644
--- a/sapling/package.json
+++ b/sapling/package.json
@@ -10,8 +10,9 @@
"vscode": "^1.60.0"
},
"categories": [
- "Other"
+ "Visualization"
],
+ "keywords": ["react", "component hierarchy", "devtools"],
"activationEvents": [
"onStartupFinished"
],
diff --git a/sapling/src/test/suite/extension.test.ts b/sapling/src/test/suite/extension.test.ts
index f6e1453..6070477 100644
--- a/sapling/src/test/suite/extension.test.ts
+++ b/sapling/src/test/suite/extension.test.ts
@@ -1,4 +1,5 @@
-import * as assert from 'assert';
+import { describe, suite , test, before} from 'mocha';
+import { expect } from 'chai';
// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
@@ -8,13 +9,33 @@ import * as vscode from 'vscode';
suite('Extension Test Suite', () => {
vscode.window.showInformationMessage('Start all tests.');
- test('Sample test', () => {
- assert.strictEqual(-1, [1, 2, 3].indexOf(5));
- assert.strictEqual(-1, [1, 2, 3].indexOf(0));
- });
+ describe('Sapling loads correctly', () => {
+ let saplingExtension;
+ before (() => {
+ saplingExtension = vscode.extensions.getExtension('team-sapling.sapling');
+ });
- test('Sample test 2', () => {
- assert.strictEqual(1, 1);
- });
+ test('Sapling is registered as an extension', () => {
+ expect(saplingExtension).to.not.be.undefined;
+ });
+ test('Sapling extension is activated after VSCode startup', () => {
+ expect(saplingExtension.isActive).to.be.true;
+ });
+
+ test('Sapling extension package.json exists', () => {
+ expect(saplingExtension.packageJSON).to.not.be.undefined;
+ });
+ });
+
+ describe('It registers saplings commands successfully', () => {
+ let commandList;
+ before( async () => {
+ commandList = await vscode.commands.getCommands();
+ });
+
+ test('It registers the sapling.generateTree command', () => {
+ expect(commandList).to.be.an('array').that.does.include('sapling.generateTree');
+ });
+ });
});
diff --git a/sapling/src/test/suite/parser.test.ts b/sapling/src/test/suite/parser.test.ts
index 4917beb..adbb025 100644
--- a/sapling/src/test/suite/parser.test.ts
+++ b/sapling/src/test/suite/parser.test.ts
@@ -83,10 +83,12 @@ suite('Parser Test Suite', () => {
tree = parser.parse();
});
- test('Should parse destructured imports', () => {
- expect(tree.children).to.have.lengthOf(2);
+ test('Should parse destructured and third party imports', () => {
+ expect(tree.children).to.have.lengthOf(3);
expect(tree.children[0]).to.have.own.property('name').that.is.oneOf(['Switch', 'Route']);
expect(tree.children[1]).to.have.own.property('name').that.is.oneOf(['Switch', 'Route']);
+ expect(tree.children[2]).to.have.own.property('name').that.is.equal('Tippy');
+
});
test('reactRouter should be designated as third party and reactRouter', () => {
@@ -97,10 +99,28 @@ suite('Parser Test Suite', () => {
expect(tree.children[1]).to.have.own.property('reactRouter').to.be.true;
});
- //test for third party without reactRouter
+ test('Tippy should be designated as third party and not reactRouter', () => {
+ expect(tree.children[2]).to.have.own.property('thirdParty').to.be.true;
+ expect(tree.children[2]).to.have.own.property('reactRouter').to.be.false;
+ });
});
- // TEST 3: WOBBEGAINZ
+ // TEST 3: IDENTIFIES REDUX STORE CONNECTION
+ describe('It identifies a Redux store connection and designates the component as such', () => {
+ before(() => {
+ file = path.join(__dirname, '../../../src/test/test_apps/test_3/index.js');
+ parser = new SaplingParser(file);
+ tree = parser.parse();
+ });
+
+ test('The reduxConnect properties of the connected component and the unconnected component should be true and false, respectively', () => {
+ expect(tree.children[1].children[0].name).to.equal('ConnectedContainer');
+ expect(tree.children[1].children[0]).to.have.own.property('reduxConnect').that.is.true;
+
+ expect(tree.children[1].children[1].name).to.equal('UnconnectedContainer');
+ expect(tree.children[1].children[1]).to.have.own.property('reduxConnect').that.is.false;
+ });
+ });
// TEST 4: ALIASED IMPORTS
describe('It works for aliases', () => {
@@ -156,7 +176,7 @@ suite('Parser Test Suite', () => {
});
});
- // TEST 6: Bad import of App2 from App1 Component
+ // TEST 6: BAD IMPORT OF APP2 FROM APP1 COMPONENT
describe('It works for badly imported children nodes', () => {
before(() => {
file = path.join(__dirname, '../../../src/test/test_apps/test_6/index.js');
@@ -170,7 +190,7 @@ suite('Parser Test Suite', () => {
});
});
- // TEST 7: Syntax error in app file causes parser error
+ // TEST 7: SYNTAX ERROR IN APP FILE CAUSES PARSER ERROR
describe('It should log an error when the parser encounters a javascript syntax error', () => {
before(() => {
file = path.join(__dirname, '../../../src/test/test_apps/test_7/index.js');
@@ -185,7 +205,7 @@ suite('Parser Test Suite', () => {
});
});
- // Test 8: Props check
+ // TEST 8: MULTIPLE PROPS ON ONE COMPONENT
describe('It should properly count repeat components and consolidate and grab their props', () => {
before(() => {
file = path.join(__dirname, '../../../src/test/test_apps/test_8/index.js');
@@ -193,6 +213,25 @@ suite('Parser Test Suite', () => {
tree = parser.parse();
});
+ test('Grandchild should have a count of 1', () => {
+ expect(tree.children[0].children[0]).to.have.own.property('count').that.equals(1);
+ });
+
+ test('Grandchild should have the correct three props', () => {
+ expect(tree.children[0].children[0].props).has.own.property('prop1').that.is.true;
+ expect(tree.children[0].children[0].props).has.own.property('prop2').that.is.true;
+ expect(tree.children[0].children[0].props).has.own.property('prop3').that.is.true;
+ });
+ });
+
+ // TEST 9: FINDING DIFFERENT PROPS ACROSS TWO OR MORE IDENTICAL COMPONENTS
+ describe('It should properly count repeat components and consolidate and grab their props', () => {
+ before(() => {
+ file = path.join(__dirname, '../../../src/test/test_apps/test_9/index.js');
+ parser = new SaplingParser(file);
+ tree = parser.parse();
+ });
+
test('Grandchild should have a count of 2', () => {
expect(tree.children[0].children[0]).to.have.own.property('count').that.equals(2);
});
@@ -203,7 +242,7 @@ suite('Parser Test Suite', () => {
});
});
- // Test 10: check children works and component works
+ // TEST 10: CHECK CHILDREN WORKS AND COMPONENTS WORK
describe('It should render children when children are rendered as values of prop called component', () => {
before(() => {
file = path.join(__dirname, '../../../src/test/test_apps/test_10/index.jsx');
@@ -219,4 +258,28 @@ suite('Parser Test Suite', () => {
expect(tree.children[1].children[4]).to.have.own.property('name').that.is.equal('HistoryDisplay');
});
});
+
+ // TEST 11: PARSER DOESN'T BREAK UPON RECURSIVE COMPONENTS
+ describe('It should render the second call of mutually recursive components, but no further', () => {
+ before(() => {
+ file = path.join(__dirname, '../../../src/test/test_apps/test_11/index.js');
+ parser = new SaplingParser(file);
+ tree = parser.parse();
+ });
+
+ test('Tree should not be undefined', () => {
+ expect(tree).to.not.be.undefined;
+ });
+
+ test('Tree should have an index component while child App1, grandchild App2, great-grandchild App1', () => {
+ expect(tree).to.have.own.property('name').that.is.equal('index');
+ expect(tree.children).to.have.lengthOf(1);
+ expect(tree.children[0]).to.have.own.property('name').that.is.equal('App1');
+ expect(tree.children[0].children).to.have.lengthOf(1);
+ expect(tree.children[0].children[0]).to.have.own.property('name').that.is.equal('App2');
+ expect(tree.children[0].children[0].children).to.have.lengthOf(1);
+ expect(tree.children[0].children[0].children[0]).to.have.own.property('name').that.is.equal('App1');
+ expect(tree.children[0].children[0].children[0].children).to.have.lengthOf(0);
+ });
+ });
});
\ No newline at end of file
diff --git a/sapling/src/test/test_apps/test_2/index.js b/sapling/src/test/test_apps/test_2/index.js
index 41e4698..48e6afa 100644
--- a/sapling/src/test/test_apps/test_2/index.js
+++ b/sapling/src/test/test_apps/test_2/index.js
@@ -1,6 +1,7 @@
import React from 'react';
import { render } from 'react-dom';
import { Switch, Route } from 'react-router-dom';
+import Tippy from 'tippy';
// TEST 2 - Third Party Components, Destructuring Import
@@ -9,5 +10,6 @@ render(
+
, document.getElementById('root'));
diff --git a/sapling/src/test/test_apps/test_3/App.jsx b/sapling/src/test/test_apps/test_3/App.jsx
new file mode 100644
index 0000000..f02cad8
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/App.jsx
@@ -0,0 +1,21 @@
+import React, { Component } from 'react';
+import ConnectedContainer from './containers/ConnectedContainer'
+import UnconnectedContainer from './containers/UnconnectedContainer'
+
+
+class App extends Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ return (
+
+
+
+
+ );
+ }
+}
+
+export default App;
diff --git a/sapling/src/test/test_apps/test_3/actions/actions.js b/sapling/src/test/test_apps/test_3/actions/actions.js
new file mode 100644
index 0000000..c235427
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/actions/actions.js
@@ -0,0 +1,10 @@
+import * as types from '../constants/actionTypes';
+
+export const fakeAction1Creator = () => ({
+ type: types.FAKE_ACTION_1,
+});
+
+export const fakeAction2Creator = () => ({
+ type: types.FAKE_ACTION_2,
+});
+
diff --git a/sapling/src/test/test_apps/test_3/components/App.jsx b/sapling/src/test/test_apps/test_3/components/App.jsx
deleted file mode 100644
index eb0feb6..0000000
--- a/sapling/src/test/test_apps/test_3/components/App.jsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import React, { useState } from 'react';
-import { Switch, Route, Redirect } from 'react-router-dom';
-
-// Import React Components
-import Nav from './Nav.jsx';
-import ExercisesDisplay from './ExercisesDisplay.jsx';
-import ExerciseCreator from './ExerciseCreator.jsx';
-import DrillCreator from './DrillCreator.jsx';
-import HistoryDisplay from './HistoryDisplay.jsx';
-import Signup from './Signup.jsx';
-import Login from './Login.jsx';
-import Logout from './Logout.jsx';
-
-// App Component
-const App = () => {
- const [userInfo, setUserInfo] = useState({ name: '', email: '' });
-
- return (
-
-
-
- {/* React Router Switches */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* If not logged in force redirect to login page */}
- {!userInfo.name ? : null}
-
-
- );
-};
-
-export default App;
diff --git a/sapling/src/test/test_apps/test_3/components/DrillCreator.jsx b/sapling/src/test/test_apps/test_3/components/DrillCreator.jsx
deleted file mode 100644
index 3955655..0000000
--- a/sapling/src/test/test_apps/test_3/components/DrillCreator.jsx
+++ /dev/null
@@ -1,204 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { useParams, Link, Redirect } from 'react-router-dom';
-
-const DrillCreator = () => {
- const { id } = useParams();
- const [drillData, setDrillData] = useState({});
- const [redirect, setRedirect] = useState(false);
- const [formVals, setFormVals] = useState({
- exercise_id: id,
- weight: '',
- sets: '',
- reps: '',
- rest_interval: '',
- });
-
- // Helper function to update state formVals on form change
- const updateFormVal = (key, val) => {
- setFormVals({ ...formVals, [key]: val });
- };
-
- // TODO MAKE REAL API CALL OR LIFT STATE TO APP
- // Is there a route for creating a drill? I only see createExercise
- const getExercise = () => {
- fetch(`/api/exercise/${id}`)
- .then((response) => {
- if (response.status === 200) {
- return response.json();
- }
- throw new Error('Error when trying to get exercise details');
- })
- .then((data) => {
- console.log('exercise drill data is', data);
- setDrillData(data);
- })
- .catch((error) => console.error(error));
- };
-
- // Get exercise data for drill info (CURRENTLY FAKE DATA)
- useEffect(() => {
- console.log('Getting data from server for drill');
- getExercise();
- }, []);
-
- // Function to submit drill form data to server, create new drill
- const createDrill = () => {
- console.log('trying to create new drill', formVals);
-
- fetch('/api/drill', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(formVals),
- })
- .then((response) => {
- console.log('drill create response', response.status);
- if (response.status === 201) {
- return response.json();
- }
- throw new Error('error when trying to create a drill');
- })
- .then((data) => {
- console.log('response is 201, data is', data);
- setRedirect(true);
- })
- .catch((error) => console.error(error));
- };
-
- const { weight, sets, reps, rest_interval } = formVals;
-
- // Redirect to home page if drill created successfully
- if (redirect === true) {
- return ;
- }
-
- return (
-
-
Create a new drill:
-
- Exercise Name: {drillData.name}
-
- Exercise Description: {drillData.description}
-
- Exercise Type: {drillData.type}
-
- Last Weight (LBs): {drillData.last_weight}
-
- Last Reps: {drillData.last_reps}
-
- Last Sets: {drillData.last_sets}
-
- Last Rest (Mins): {drillData.last_rest}
-
-
- {/* DRILL INPUT FORM */}
-
-
- );
-};
-
-export default DrillCreator;
diff --git a/sapling/src/test/test_apps/test_3/components/ExerciseCreator.jsx b/sapling/src/test/test_apps/test_3/components/ExerciseCreator.jsx
deleted file mode 100644
index 36a6a8e..0000000
--- a/sapling/src/test/test_apps/test_3/components/ExerciseCreator.jsx
+++ /dev/null
@@ -1,208 +0,0 @@
-import React, { useState } from 'react';
-import { Link, Redirect } from 'react-router-dom';
-
-// React element allowing users to create a new exercise via form
-const ExerciseCreator = () => {
- const [redirect, setRedirect] = useState(false);
- const [formVals, setFormVals] = useState({
- name: '',
- description: '',
- type_id: '1',
- init_weight: '',
- init_reps: '',
- init_sets: '',
- init_rest: '',
- });
-
- // Helper function to update state formVals on form change
- const updateFormVal = (key, val) => {
- setFormVals({ ...formVals, [key]: val });
- };
-
- // Function to submit new exercise form data to server for processing
- const createExercise = () => {
- console.log('Trying to create exercise: ', formVals);
- fetch('/api/exercise', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(formVals),
- })
- .then((response) => {
- // If creation successful, redirect to exercises
- console.log('CREATE RESPONSE: ', response.status);
- if (response.status === 200) {
- return response.json();
- }
- throw new Error('Error when trying to login a user!');
- }).then((data) => {
- console.log('Added new exercise: ', data);
- setRedirect(true);
- })
- .catch((err) => console.error(err));
- };
-
- const {
- name, description, type, init_weight, init_reps, init_sets, init_rest,
- } = formVals;
-
- // If successfully created new exercise, redirect to '/' route:
- if (redirect) {
- return ;
- }
-
- return (
-
- Create a new Exercise:
-
- {/* NEW EXERCISE FORM */}
-
-
- );
-};
-
-export default ExerciseCreator;
diff --git a/sapling/src/test/test_apps/test_3/components/ExercisesDisplay.jsx b/sapling/src/test/test_apps/test_3/components/ExercisesDisplay.jsx
deleted file mode 100644
index 34cb6bc..0000000
--- a/sapling/src/test/test_apps/test_3/components/ExercisesDisplay.jsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { Link } from 'react-router-dom';
-
-const ExercisesDisplay = () => {
- const [exerciseData, setExerciseData] = useState([]);
-
- useEffect(() => {
- console.log('Getting data from server');
- // getExercises();
- fetch('/api/')
- .then((res) => res.json())
- .then((exercises) => {
- console.log('exercises are', exercises);
- setExerciseData(exercises);
- })
- .catch((error) => {
- console.log('error on ExercisesDisplay', error);
- });
- }, []);
-
- return (
-
-
Pick an Exercise:
- {exerciseData.map((exercise, i) => {
- console.log('makes all data exercises');
- return (
-
-
{exercise.name}
- Type: {exercise.typesname}
- Description: {exercise.description}
-
- Start Drill
-
-
-
- );
- })}
-
- );
-};
-
-export default ExercisesDisplay;
diff --git a/sapling/src/test/test_apps/test_3/components/HistoryDisplay.jsx b/sapling/src/test/test_apps/test_3/components/HistoryDisplay.jsx
deleted file mode 100644
index aca3e7e..0000000
--- a/sapling/src/test/test_apps/test_3/components/HistoryDisplay.jsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import React, { useState, useEffect } from 'react';
-
-const HistoryDisplay = () => {
- const [history, setHistory] = useState([]);
-
- const getHistory = () => {
- fetch('/api/history')
- .then((res) => {
- if (res.status === 200) {
- return res.json();
- }
- throw new Error ('Error getting history from server.');
- })
- .then((data) => {
- console.log('Our getHistory data is:', data);
- setHistory(data);
- })
- .catch((error) => console.error(error));
- };
-
- useEffect(() => {
- console.log('GETTING HISTROY FROM SERVER');
- getHistory();
- }, []);
-
- const drills = history.map((drill, i) => {
- return Date: {drill.date}, id: {drill.exercise_id}, Weight: {drill.weight}, Sets: {drill.sets}, Reps: {drill.reps}, Rest: {drill.rest_interval}
- });
-
- return(
-
- );
-};
-
-export default HistoryDisplay;
diff --git a/sapling/src/test/test_apps/test_3/components/Login.jsx b/sapling/src/test/test_apps/test_3/components/Login.jsx
deleted file mode 100644
index 33446d6..0000000
--- a/sapling/src/test/test_apps/test_3/components/Login.jsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import React, { useState } from 'react';
-import { Redirect, Link } from 'react-router-dom';
-
-// React element to render login form and submit login to server
-const Login = ({ setUserInfo }) => {
- const [formVals, setFormVals] = useState({ email: '', password: '' });
- const [loggedIn, setLoggedIn] = useState(false);
- const [errorMessage, setErrorMessage] = useState('');
-
- // Helper function to update state formVals on form change
- const updateFormVal = (key, val) => {
- setFormVals({ ...formVals, [key]: val });
- };
-
- // Function to submit signup form data to server, create new account
- const login = () => {
- console.log('logging in!', formVals);
-
- fetch('/api/login', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(formVals),
- })
- .then((response) => {
- // If login successful, set state for redirect
- console.log('LOGIN RESPONSE: ', response.status);
- if (response.status === 200 || response.status === 400) {
- return response.json();
- }
- throw new Error('Error when trying to login a user!');
- }).then((data) => {
- // If Error on Login display error message
- if (data.message) {
- setErrorMessage(data.message);
- return;
- }
- // Successful login, redirect to main page:
- setUserInfo(data);
- setLoggedIn(true);
- })
- .catch((err) => console.error(err));
- };
-
- const { email, password } = formVals;
-
- // If signed up correctly, redirect to main page
- if (loggedIn) {
- return ;
- }
-
- // If not logged in render login form
- if (!loggedIn) {
- return (
-
- );
- }
-};
-
-export default Login;
diff --git a/sapling/src/test/test_apps/test_3/components/Logout.jsx b/sapling/src/test/test_apps/test_3/components/Logout.jsx
deleted file mode 100644
index 56de830..0000000
--- a/sapling/src/test/test_apps/test_3/components/Logout.jsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import { Redirect } from 'react-router-dom';
-
-// React component that fakes logging out and returns user to login page
-const Logout = ({ setUserInfo }) => {
- setUserInfo({ name: '', email: '' });
-
- return ;
-};
-
-export default Logout;
diff --git a/sapling/src/test/test_apps/test_3/components/Nav.jsx b/sapling/src/test/test_apps/test_3/components/Nav.jsx
deleted file mode 100644
index 90b8229..0000000
--- a/sapling/src/test/test_apps/test_3/components/Nav.jsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-
-const Nav = ({ userInfo }) => {
- console.log('this is the navbar speaking', userInfo);
-
- // Navbar when not signed in:
- if (!userInfo.name) {
- return (
-
- Login
- Signup
-
- );
- }
-
- // Signed in Navbar:
- return (
-
- Home
- Create Exercise
- History
- Logout
-
- {userInfo.name
- ? (
-
- Logged in as:
- {userInfo.name}
- -
- {userInfo.email}
-
- )
- : null}
-
-
- );
-};
-
-export default Nav;
diff --git a/sapling/src/test/test_apps/test_3/components/Signup.jsx b/sapling/src/test/test_apps/test_3/components/Signup.jsx
deleted file mode 100644
index 8bc4b31..0000000
--- a/sapling/src/test/test_apps/test_3/components/Signup.jsx
+++ /dev/null
@@ -1,129 +0,0 @@
-import React, { useState } from 'react';
-import { Redirect, Link } from 'react-router-dom';
-
-// React component to render signup form and send form data to server
-const Signup = ({ setUserInfo }) => {
- const [formVals, setFormVals] = useState({ email: '', name: '', password: '' });
- const [loggedIn, setLoggedIn] = useState(false);
- const [errorMessage, setErrorMessage] = useState('');
-
- // Helper function to update state formVals on form change
- const updateFormVal = (key, val) => {
- setFormVals({ ...formVals, [key]: val });
- };
-
- // Function to submit signup form data to server, create new account
- const signup = () => {
- console.log('signing up!', formVals);
- fetch('/api/signup', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(formVals),
- })
- .then((response) => {
- // If signup successful, login
- console.log('SIGNUP RESPONSE: ', response.status);
- if (response.status === 201 || 400) {
- return response.json();
- }
- throw new Error('Error when trying to create new user!');
- })
- .then((data) => {
- if (data.message) {
- setErrorMessage(data.message);
- return;
- }
- setUserInfo(data);
- setLoggedIn(true);
- })
- .catch((err) => console.error(err));
- };
-
- const { email, name, password } = formVals;
-
- // If signed up correctly, redirect to main page
- if (loggedIn) {
- return ;
- }
-
- // If not logged in render signup form
- if (!loggedIn) {
- return (
-
- );
- }
-};
-
-export default Signup;
diff --git a/sapling/src/test/test_apps/test_3/constants/actionTypes.js b/sapling/src/test/test_apps/test_3/constants/actionTypes.js
new file mode 100644
index 0000000..1ff00ba
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/constants/actionTypes.js
@@ -0,0 +1,3 @@
+// Action Types
+export const FAKE_ACTION_1 = 'FAKE_ACTION_1';
+export const FAKE_ACTION_2 = 'FAKE_ACTION_2';
diff --git a/sapling/src/test/test_apps/test_3/containers/ConnectedContainer.jsx b/sapling/src/test/test_apps/test_3/containers/ConnectedContainer.jsx
new file mode 100644
index 0000000..918dccc
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/containers/ConnectedContainer.jsx
@@ -0,0 +1,28 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import * as actions from '../actions/actions';
+
+const mapStateToProps = state => {
+ return {
+ count: state.fake.count,
+ }
+}
+
+const mapDispatchToProps = dispatch => ({
+ fakeAction1: () => dispatch(actions.FAKE_ACTION_1()),
+ fakeAction2: () => dispatch(actions.FAKE_ACTION_2()),
+})
+
+class ConnectedContainer extends Component {
+ constructor(props) {
+ super(props)
+ }
+
+ render() {
+ return (
+ This is a container connected to the redux Store
+ )
+ }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(ConnectedContainer);
diff --git a/sapling/src/test/test_apps/test_3/containers/UnconnectedContainer.jsx b/sapling/src/test/test_apps/test_3/containers/UnconnectedContainer.jsx
new file mode 100644
index 0000000..80c9253
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/containers/UnconnectedContainer.jsx
@@ -0,0 +1,13 @@
+import React, { Component } from 'react';
+
+class UnconnectedContainer extends Component {
+ constructor(props) {
+ super(props)
+ }
+
+ render() {
+ This is a container not connected to the Redux store.
+ }
+}
+
+export default UnconnectedContainer;
\ No newline at end of file
diff --git a/sapling/src/test/test_apps/test_3/index.html b/sapling/src/test/test_apps/test_3/index.html
new file mode 100644
index 0000000..5931ae3
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+ NOSEBLEEDS
+
+
+
+
+
+
+ NOSEBLEEDS
+
+
+
\ No newline at end of file
diff --git a/sapling/src/test/test_apps/test_3/index.js b/sapling/src/test/test_apps/test_3/index.js
new file mode 100644
index 0000000..974ecb5
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/index.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import { render } from 'react-dom';
+import App from './App.jsx';
+
+import { Provider } from 'react-redux';
+import store from './store';
+
+render (
+
+
+ ,
+ document.getElementById('root')
+);
diff --git a/sapling/src/test/test_apps/test_3/index.jsx b/sapling/src/test/test_apps/test_3/index.jsx
deleted file mode 100644
index 3827277..0000000
--- a/sapling/src/test/test_apps/test_3/index.jsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { render } from 'react-dom';
-import { BrowserRouter as Router } from 'react-router-dom';
-
-// Import styles from SASS
-import styles from './scss/application.scss';
-
-// Import React Components
-import App from './components/App.jsx';
-
-// TEST 3 - Multi component application including react-router components
-
-render(
-
-
- ,
- document.getElementById('root'),
-);
diff --git a/sapling/src/test/test_apps/test_3/reducers/fakeReducer.js b/sapling/src/test/test_apps/test_3/reducers/fakeReducer.js
new file mode 100644
index 0000000..77ae21c
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/reducers/fakeReducer.js
@@ -0,0 +1,27 @@
+import * as types from '../constants/actionTypes';
+
+const initialState = {
+ count: 0,
+};
+
+const fakeReducer = (state = initialState, action) => {
+
+ switch (action.type) {
+ case types.FAKE_ACTION_1: {
+ return {
+ count: count + 1,
+ }
+ }
+
+ case types.FAKE_ACTION_2: {
+ return {
+ count: count + 2,
+ }
+ }
+
+ default:
+ return state;
+ }
+};
+
+export default fakeReducer;
diff --git a/sapling/src/test/test_apps/test_3/reducers/index.js b/sapling/src/test/test_apps/test_3/reducers/index.js
new file mode 100644
index 0000000..1d5f311
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/reducers/index.js
@@ -0,0 +1,6 @@
+import { combineReducers } from 'redux';
+ import geekReducer from './geekReducer';
+
+ export default combineReducers({
+ fake: fakeReducer,
+ });
diff --git a/sapling/src/test/test_apps/test_3/store.js b/sapling/src/test/test_apps/test_3/store.js
new file mode 100644
index 0000000..73a5e20
--- /dev/null
+++ b/sapling/src/test/test_apps/test_3/store.js
@@ -0,0 +1,12 @@
+ import { createStore, applyMiddleware } from 'redux';
+ import { composeWithDevTools } from 'redux-devtools-extension';
+ import thunk from 'redux-thunk'; //this was important to use in order to implement async requests to our database in actions.js
+ import reducers from './reducers/index';
+ //import { loadMarkets } from './actions/actions'; //this might be used in the future to load data for the user ref. unit 12 test
+
+ const store = createStore(
+ reducers,
+ composeWithDevTools(applyMiddleware(thunk)),
+ );
+
+ export default store;
diff --git a/sapling/src/test/test_apps/test_8/components/App.jsx b/sapling/src/test/test_apps/test_8/components/App.jsx
index 2dd1ecf..a22503e 100644
--- a/sapling/src/test/test_apps/test_8/components/App.jsx
+++ b/sapling/src/test/test_apps/test_8/components/App.jsx
@@ -7,8 +7,7 @@ class App extends Component {
render () {
return (
-
-
+
)
}
diff --git a/sapling/src/test/test_apps/test_9/components/App.jsx b/sapling/src/test/test_apps/test_9/components/App.jsx
index f0bdb79..2dd1ecf 100644
--- a/sapling/src/test/test_apps/test_9/components/App.jsx
+++ b/sapling/src/test/test_apps/test_9/components/App.jsx
@@ -1,15 +1,14 @@
import React, { Component } from 'react';
import Main from './Main';
-const string = 'This is a variable string'
+
class App extends Component {
render () {
return (
-
-
-
+
+
)
}
diff --git a/sapling/src/test/test_apps/test_9/index.js b/sapling/src/test/test_apps/test_9/index.js
index ec8eb03..92a4677 100644
--- a/sapling/src/test/test_apps/test_9/index.js
+++ b/sapling/src/test/test_apps/test_9/index.js
@@ -5,7 +5,7 @@ import { render } from 'react-dom';
// Import React Components
import App from './components/App.jsx';
-// TEST 9 - Simple React App with multiple Main components and different props passed in
+// TEST 9 - Prop Detection, one App Component renders two Main Components, each with different props
render(
From 406b6169e8396c7da1e7c66cc71db2a79ad12622 Mon Sep 17 00:00:00 2001
From: Jordan Hisel
Date: Wed, 6 Oct 2021 20:20:08 -0700
Subject: [PATCH 2/2] fleshing out tests
Co-authored-by: Charles Gutwirth
Co-authored-by: Lindsay Baird
Co-authored-by: Paul Coster
---
sapling/src/test/suite/extension.test.ts | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/sapling/src/test/suite/extension.test.ts b/sapling/src/test/suite/extension.test.ts
index 6070477..a448d47 100644
--- a/sapling/src/test/suite/extension.test.ts
+++ b/sapling/src/test/suite/extension.test.ts
@@ -28,14 +28,17 @@ suite('Extension Test Suite', () => {
});
});
- describe('It registers saplings commands successfully', () => {
- let commandList;
- before( async () => {
- commandList = await vscode.commands.getCommands();
- });
-
- test('It registers the sapling.generateTree command', () => {
- expect(commandList).to.be.an('array').that.does.include('sapling.generateTree');
- });
- });
+ // describe('It registers saplings commands successfully', () => {
+ // let commandList;
+ // before( (done) => {
+ // vscode.commands.getCommands().then(commands => {
+ // commandList = commands;
+ // done();
+ // });
+ // });
+
+ // test('It registers the sapling.generateTree command', () => {
+ // expect(commandList).to.be.an('array').that.does.include('sapling.generateTree');
+ // });
+ // });
});