diff --git a/.all-contributorsrc b/.all-contributorsrc index b592af0..64806ba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -37,6 +37,24 @@ "code", "doc" ] + }, + { + "login": "senpl", + "name": "Michał Urbanek", + "avatar_url": "https://avatars.githubusercontent.com/u/5415941?v=4", + "profile": "https://github.com/senpl", + "contributions": [ + "bug" + ] + }, + { + "login": "willemlarsen", + "name": "Willem Larsen", + "avatar_url": "https://avatars.githubusercontent.com/u/3875136?v=4", + "profile": "http://thermodynamicsofemotion.com/", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/.reset-files/3_third-form.js b/.reset-files/3_third-form.js index 0aa7f65..637bee4 100644 --- a/.reset-files/3_third-form.js +++ b/.reset-files/3_third-form.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line const jsforms = (function () { 'use strict'; diff --git a/.reset-files/4_test-dummy-form.test.js b/.reset-files/4_test-dummy-form.test.js index 4b09fce..beb48e9 100644 --- a/.reset-files/4_test-dummy-form.test.js +++ b/.reset-files/4_test-dummy-form.test.js @@ -29,22 +29,22 @@ describe('Test Dummy Form - Costume Shop Sales', function () { let salesReporter; beforeEach(function () { - pointOfSaleDataUtilsFactory = pointOfSaleDataUtilsFactoryBuilder(); + pointOfSaleDataUtilsFactory = pointOfSaleDataUtilityFactoryBuilder(); }); describe('Point of Sale Data Utilities', function () { - describe('get product count by sale', function () { - - let pointOfSaleDataUtilities; - let transactionStatuses; - let testData; - - beforeEach(function(){ - testData = buildSimpleTestData(); - transactionStatuses = buildTransactionStatuses(); - pointOfSaleDataUtilities = pointOfSaleDataUtilsFactory(transactionStatuses); - }); + // File being tested can be found here: + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js + + let pointOfSaleDataUtilities; + let transactionStatuses; + + beforeEach(function () { + transactionStatuses = buildTransactionStatuses(); + pointOfSaleDataUtilities = pointOfSaleDataUtilsFactory(transactionStatuses); + }); + describe('get product count by sale', function () { it('returns an empty object for sale counts if no sale data exists'); it('returns an object with a single count of 1 when only one item, quantity 1 was purchased'); @@ -64,22 +64,24 @@ describe('Test Dummy Form - Costume Shop Sales', function () { }); }); - describe('sales report', function () { + describe('get report', function () { + // files being tested are: + // ../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js describe('get sales report', function () { - it('returns a sales report with no sales'); + it('returns a report of sales with no sales'); - it('returns a sales report with one sale'); + it('returns a report of sales with one sale'); - it('returns a sales report with two sales of different products'); + it('returns a report of sales with two sales of different products'); - it('returns a sales report with two sales of the same product'); + it('returns a report of sales with two sales of the same product'); - it('returns a sales report with no "returns" data'); + it('returns a report of sales excluding any return transactions'); }); - }); - describe('returns report', function () { - it('returns a "returns" report with no "sales" data'); + describe('get returns report', function () { + it('returns a report of return transactions that excludes sales transactions'); + }); }); - }); diff --git a/.reset-files/6_async-test-dummy-form.test.js b/.reset-files/6_async-test-dummy-form.test.js index a2ea074..9968543 100644 --- a/.reset-files/6_async-test-dummy-form.test.js +++ b/.reset-files/6_async-test-dummy-form.test.js @@ -1,17 +1,27 @@ -/* global httpService, pluginApi, asyncContacts */ +/* +global + +asyncContacts, +chai, +httpService, +pluginApi +*/ 'use strict'; -describe('Test Dummy Form', function () { +describe('Async Test Dummy Form', function () { let contactService; + let responseData; beforeEach(function () { + responseData = {}; + const httpInstance = httpService(); const contactServiceInstance = contactService(httpInstance); const pluginApiInstance = pluginApi(); - - return asyncContacts(contactServiceInstance, pluginApiInstance); + + asyncContacts(contactServiceInstance, pluginApiInstance); }); // For this first suite of tests, we are going to work with comparing strings @@ -23,7 +33,7 @@ describe('Test Dummy Form', function () { it('should return 0 when two values are equal'); // Equality checking is one of the most common ways to test - // the results of code, so it's important to get comnfortable with it + // the results of code, so it's important to get comfortable with it it('should return -1 when name1 comes before name2 alphabetically'); // It's important to test all cases. The function, compareNames, has @@ -31,7 +41,6 @@ describe('Test Dummy Form', function () { // is to test until you're bored. Ideally, being bored will come at // about the same time you've tested all cases. it('should return 1 when name1 comes after name2 alphabetically'); - }); // Our second suite of tests will validate the behavior of a record comparison @@ -60,7 +69,6 @@ describe('Test Dummy Form', function () { // We could use the same record from the previous test to run this test case as well // If this generates duplicate code, how would we resolve that? it('should return 1 when last names are equal and record1.firstName comes after record3.firstName alphabetically'); - }); describe('sortByContactName', function () { @@ -75,7 +83,6 @@ describe('Test Dummy Form', function () { // sortByContactName always returns an array, so a calling function // doesn't fail on a type error it('should return an empty array if passed argument is not an array'); - }); describe('getContactNames', function () { @@ -83,7 +90,7 @@ describe('Test Dummy Form', function () { // To fix this issue you will need to understand how the Mockery // library works. The beforeEach at the very top of this test will // give you a place to start. - // Assert has a method "doesNothThrow." This would be quite useful here + // Assert has a method "doesNotThrow." This would be quite useful here it('should not throw error immediately when called'); // Sinon is a library built for handling cases where you want to get a view diff --git a/FORMS.md b/FORMS.md index 8900c60..b33100b 100644 --- a/FORMS.md +++ b/FORMS.md @@ -13,8 +13,9 @@ 1. [First Form](./docs/FIRST-FORM.md) 2. [Second Form](./docs/SECOND-FORM.md) 3. [Third Form](./docs/THIRD-FORM.md) -3. [Test Dummy Form](./docs/TEST-DUMMY-FORM.md) - +4. [Test Dummy Form](./docs/TEST-DUMMY-FORM.md) +5. Async Form _TBD_ +6. Async Test Dummy Form _TBD_ diff --git a/README.md b/README.md index d25d55d..a6cf0c5 100644 --- a/README.md +++ b/README.md @@ -79,15 +79,15 @@ For a video walkthrough of the setup process, check out the following video: ### Solving Each Form ### -1. [Documentation For all Forms](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/FORMS.md) +1. [Documentation For all Forms](https://github.com/cmstead/jsLearnerForms/blob/documentation/FORMS.md) 2. First Form -- Write code to pass each test - 1. [First Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/FIRST-FORM.md) + 1. [First Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/FIRST-FORM.md) 3. Second Form -- Update code to pass new tests, keep old tests green - 1. [Second Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/SECOND-FORM.md) + 1. [Second Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/SECOND-FORM.md) 4. Third Form -- Update code to pass new tests, keep tests old green - 1. [Third Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/THIRD-FORM.md) + 1. [Third Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/THIRD-FORM.md) 5. Test Dummy Form (Fourth Form) -- Write tests matching each description and get all of the code under test (modify ONLY the test code) - 1. [Test Dummy Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/TEST-DUMMY-FORM.md) **Incomplete** + 1. [Test Dummy Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/TEST-DUMMY-FORM.md) 6. Async Form -- Write code to pass each test; don't forget the refactoring steps! 1. Documentation TBD 7. Async Test Dummy Form (Sixth Form) -- Write tests matching each description and get all of the code under test (modify ONLY the test code) @@ -174,6 +174,8 @@ This section will be updated as forms are completed and ready for use. hunterinderstries
hunterinderstries

💵 EDF Renewables
EDF Renewables

💵 Jason Kerney
Jason Kerney

💻 📖 + Michał Urbanek
Michał Urbanek

🐛 + Willem Larsen
Willem Larsen

📖 diff --git a/docs-source/forms-source/form1-doc/_main.md b/docs-source/forms-source/form1-doc/_main.md index 676a4d1..5765090 100644 --- a/docs-source/forms-source/form1-doc/_main.md +++ b/docs-source/forms-source/form1-doc/_main.md @@ -9,16 +9,15 @@ You can also look at [JS Learner Forms documentation](../FORMS.md) for other forms. You will be working in then [jsforms-source/1_first-form.js](..\jsforms-source\1_first-form.js) file. - \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/arrays/_main.md b/docs-source/forms-source/form1-doc/arrays/_main.md new file mode 100644 index 0000000..36d35d7 --- /dev/null +++ b/docs-source/forms-source/form1-doc/arrays/_main.md @@ -0,0 +1,11 @@ + + +You will use functions to work with arrays and loops. + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/arrays/square.md b/docs-source/forms-source/form1-doc/arrays/square.md new file mode 100644 index 0000000..c1ba9d3 --- /dev/null +++ b/docs-source/forms-source/form1-doc/arrays/square.md @@ -0,0 +1,69 @@ + + +Create a function that squares each number in an array. + +The steps you will take to building the `squareAll` function are: + +1. Add a `squareAll` function that returns a constant value. +2. Chang the `squareAll` function to perform square computation on array value + +#### It should square all numbers in a single-value array #### + +Create a function called `squareAll` that takes an array and returns the square of the first element. + +
Hints + +Create a function that only squares the first value of an array and returns that value as an array. + +
Code + +**Example** + +```javascript + function squareAll (values) { + let result = square(_array_[_number_]); + return [_something_]; + } + + return { + squareAll, + }; +``` + +
+ +
+ +#### It should square multiple numbers #### + +Modify the `squareAll` function so that it now squares each number in the array. + +
Hints + +Add logic to square all numbers in array (How did you solve sum?) + +
Code + +**Example** + +```javascript + function squareAll (values) { + for(let index = _number_; _number_ < _number_; index += 1) { + result[index] = square(_something_[index]); + } + + return ?; + } + + return { + squareAll, + }; +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/arrays.md b/docs-source/forms-source/form1-doc/arrays/sum.md similarity index 52% rename from docs-source/forms-source/form1-doc/arrays.md rename to docs-source/forms-source/form1-doc/arrays/sum.md index 0acc25b..82f0c72 100644 --- a/docs-source/forms-source/form1-doc/arrays.md +++ b/docs-source/forms-source/form1-doc/arrays/sum.md @@ -1,15 +1,12 @@ -You will use functions to work with arrays and loops. - -### \*\*sum function\*\* You are going to create a function called `sum` that adds numbers together. -#### It should take the sum of one number +#### It should take the sum of one number #### Create a `sum` function that accepts an array and returns 1. @@ -35,7 +32,7 @@ Create a function that returns a simple number instead of worrying about actuall -#### It should add two numbers +#### It should add two numbers #### Modify the `sum` function so that it adds the first two numbers in an array. @@ -65,7 +62,7 @@ Add logic to sum 1 or two numbers (An `if` structure might help here) -#### It should add multiple numbers +#### It should add multiple numbers #### Modify the `sum` function to add all numbers in an array. @@ -113,70 +110,4 @@ Add logic to sum an arbitrary length array of numbers (A for loop might help to - - -### \*\*squareAll function\*\* - -Create a function that squares each number in an array. - -The steps you will take to building the `squareAll` function are: - -1. Add a `squareAll` function that returns a constant value. -2. Chang the `squareAll` function to perform square computation on array value - -#### It should square all numbers in a single-value array - -Create a function called `squareAll` that takes an array and returns the square of the first element. - -
Hints - -Create a function that only squares the first value of an array and returns that value as an array. - -
Code - -**Example** - -```javascript - function squareAll (values) { - let result = square(_array_[_number_]); - return [_something_]; - } - - return { - squareAll, - }; -``` - -
- -
- -#### It should square multiple numbers - -Modify the `squareAll` function so that it now squares each number in the array. - -
Hints - -Add logic to square all numbers in array (How did you solve sum?) - -
Code - -**Example** - -```javascript - function squareAll (values) { - for(let index = _number_; _number_ < _number_; index += 1) { - result[index] = square(_something_[index]); - } - - return ?; - } - - return { - squareAll, - }; -``` - -
-
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/combining/_main.md b/docs-source/forms-source/form1-doc/combining/_main.md new file mode 100644 index 0000000..8c47383 --- /dev/null +++ b/docs-source/forms-source/form1-doc/combining/_main.md @@ -0,0 +1,10 @@ + + +You will now take code you wrote and use it define more complex behaviors + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/combining.md b/docs-source/forms-source/form1-doc/combining/magnitude.md similarity index 91% rename from docs-source/forms-source/form1-doc/combining.md rename to docs-source/forms-source/form1-doc/combining/magnitude.md index a490d29..0169805 100644 --- a/docs-source/forms-source/form1-doc/combining.md +++ b/docs-source/forms-source/form1-doc/combining/magnitude.md @@ -1,11 +1,8 @@ -You will now take code you wrote and use it define more complex behaviors - -### \*\*magnitude function\*\* You will create a function called `magnitude` that will calculate the magnitude of all given numbers. @@ -37,7 +34,7 @@ or > > d = 3 -#### It returns the magnitude of a vector with only one number +#### It returns the magnitude of a vector with only one number #### Create a function called `magnitude` that returns the first item in an array that is given to it. @@ -63,7 +60,7 @@ Can you just return a value from the array? -#### It returns only positive numbers -- all magnitudes are positive +#### It returns only positive numbers -- all magnitudes are positive #### Modify the `magnitude` function that returns the positive value of the first item in an array that is given to it. @@ -96,7 +93,7 @@ Currently the magnitude of a vector is computed by: -#### It should return the magnitude of a vector with two values +#### It should return the magnitude of a vector with two values #### Modify the `magnitude` function so that it returns the magnitude of the first 2 items in an array given to it. @@ -134,7 +131,7 @@ Currently the magnitude of a vector is computed by: -#### It should return the magnitude of a vector with multiple values +#### It should return the magnitude of a vector with multiple values #### Modify the `magnitude` function so that it returns the magnitude of all the values in the array. @@ -166,4 +163,4 @@ The magnitude of a vector is computed by: - + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/complex/_main.md b/docs-source/forms-source/form1-doc/complex/_main.md new file mode 100644 index 0000000..59eb8cb --- /dev/null +++ b/docs-source/forms-source/form1-doc/complex/_main.md @@ -0,0 +1,10 @@ + + +You will use previous functions chained to gether to give us new results. + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/complex.md b/docs-source/forms-source/form1-doc/complex/sumOfSquares.md similarity index 79% rename from docs-source/forms-source/form1-doc/complex.md rename to docs-source/forms-source/form1-doc/complex/sumOfSquares.md index 4f66e6e..d438f60 100644 --- a/docs-source/forms-source/form1-doc/complex.md +++ b/docs-source/forms-source/form1-doc/complex/sumOfSquares.md @@ -1,15 +1,12 @@ -You will use previous functions chained to gether to give us new results. - -### \*\*sumOfSquares function\*\* Create a function that takes an array of numbers, squares each number and then returns the sum of those squares. -#### It should square number in a 1-length array and return it +#### It should square number in a 1-length array and return it #### Create a function called `sumOfSquares` that takes an array and returns the square of the first element. @@ -38,7 +35,7 @@ Try to do the following: -#### It should take the sum of squares of multiple numbers +#### It should take the sum of squares of multiple numbers #### Modify the `sumOfSquares` function so that it squares all numbers in the array. @@ -62,4 +59,4 @@ Add logic to square all numbers and return the sum (squareAll and sum might be u - + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/copying-arrays/_main.md b/docs-source/forms-source/form1-doc/copying-arrays/_main.md new file mode 100644 index 0000000..7304aad --- /dev/null +++ b/docs-source/forms-source/form1-doc/copying-arrays/_main.md @@ -0,0 +1,10 @@ + + +You are going to use functions to explore the `Array.prototype.slice` method. + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/copying-arrays.md b/docs-source/forms-source/form1-doc/copying-arrays/buildVector.md similarity index 84% rename from docs-source/forms-source/form1-doc/copying-arrays.md rename to docs-source/forms-source/form1-doc/copying-arrays/buildVector.md index 4d6c0ed..fe31a8b 100644 --- a/docs-source/forms-source/form1-doc/copying-arrays.md +++ b/docs-source/forms-source/form1-doc/copying-arrays/buildVector.md @@ -1,18 +1,14 @@ -You are going to use functions to explore the `Array.prototype.slice` method. - -### \*\*buildVector function\*\* You will now create a function called `buildVector` that returns a copy of the array as it was passed. > A vector is an ordered set of points which describes a "directed line segment," in other words, a vector is a line segment with an arrow -#### It returns a vector (array) containing the same numbers as the original -- try returning the array you get in your function +#### It returns a vector (array) containing the same numbers as the original -- try returning the array you get in your function #### Create a function called `buildVector` that returns the same array passed to it. @@ -38,7 +34,7 @@ Add buildVector function (Would it be possible to just return something?) -#### It returns a copy of the original vector +#### It returns a copy of the original vector #### Modify the `buildVector` function so that it returns a copy of the array passed to it. (note: use the `slice` method on array.) @@ -63,4 +59,4 @@ Add logic to return a copy of vector array (Slice will create a new array just l - + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/functions/_main.md b/docs-source/forms-source/form1-doc/functions/_main.md new file mode 100644 index 0000000..b245d8c --- /dev/null +++ b/docs-source/forms-source/form1-doc/functions/_main.md @@ -0,0 +1,11 @@ + + +Time to create functions and have them return a value. + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/functions.md b/docs-source/forms-source/form1-doc/functions/functionCalls.md similarity index 55% rename from docs-source/forms-source/form1-doc/functions.md rename to docs-source/forms-source/form1-doc/functions/functionCalls.md index 2584b3a..1a15a19 100644 --- a/docs-source/forms-source/form1-doc/functions.md +++ b/docs-source/forms-source/form1-doc/functions/functionCalls.md @@ -1,79 +1,14 @@ -Time to create functions and have them return a value. -### \*\*greeter function\*\* - -##### It should say "Hello!" by default - -Write a function called `greet` that returns the value "Hello!". (note: don't forget the "!") - -
Hints - -Functions start with the keyword `function` followed by the name of the function and then a set of parenthesis `()`. All the logic of a function is contained an open curly brace `{` and a closed curly brace `}`. What the function returns follows the key word `return`. - -
Code - -**Example** - -```javascript - function greet() { - return _string_; - } - - return { - greet, - }; -``` - -
- -
- -#### conditional logic [if/else] - -##### It should say "Salutations!" when Salutations is passed - -Modify the greet function to take a greeting and return the greeting if it was passed. - -
Hints - -Add condition to greet to handle custom greeting case. -(Try using an "if/else" structure. "If" is a control structure) - -
Code - -**Example** - -```javascript - function greet (greeting) { - if (_something_ === undefined) { - return _string_; - } else { - return _something_ + '!'; - } - } - - return { - greet, - }; -``` - -
- -
- -### function calls and mathematical operations [Math library] - -#### \*\*square function\*\* +#### Square Function #### Create a function that takes a number and returns its square. -##### It should square 1 +##### It should square 1 ##### The function called `square` will be passed 1 and should return 1. @@ -99,7 +34,7 @@ Add square function that returns a simple value rather then worrying about actua -##### It should square 3 +##### It should square 3 ##### Modify the `square` function such that it returns the square of the value passed in. @@ -139,11 +74,11 @@ Modify the `square` function such that it returns the square of the value passed -#### \*\*squareRoot function\*\* +#### Square Root Function #### Create a function that takes a number and returns the square root of that number. (note: use the Math library). -##### It should take the square root of 1 +##### It should take the square root of 1 ##### Create a function called `squareRoot` that will be passed 1 and return 1. @@ -169,7 +104,7 @@ Create a function that returns a simple value rather then worrying about actuall -##### It should take the square root of 4 +##### It should take the square root of 4 ##### Modify the `squareRoot` function to return the square root of the value passed. diff --git a/docs-source/forms-source/form1-doc/functions/greeterFunction.md b/docs-source/forms-source/form1-doc/functions/greeterFunction.md new file mode 100644 index 0000000..1b34239 --- /dev/null +++ b/docs-source/forms-source/form1-doc/functions/greeterFunction.md @@ -0,0 +1,64 @@ + + +#### It should say `"Hello!"` by default #### + +Write a function called `greet` that returns the value "Hello!". (note: don't forget the "!") + +
Hints + +Functions start with the keyword `function` followed by the name of the function and then a set of parenthesis `()`. All the logic of a function is contained an open curly brace `{` and a closed curly brace `}`. What the function returns follows the key word `return`. + +
Code + +**Example** + +```javascript + function greet() { + return _string_; + } + + return { + greet, + }; +``` + +
+ +
+ +#### Conditional Logic [If / Else] #### + +##### It should say `"Salutations!"` when salutations is passed ##### + +Modify the greet function to take a greeting and return the greeting if it was passed. + +
Hints + +Add condition to greet to handle custom greeting case. +(Try using an "if/else" structure. "If" is a control structure) + +
Code + +**Example** + +```javascript + function greet (greeting) { + if (_something_ === undefined) { + return _string_; + } else { + return _something_ + '!'; + } + } + + return { + greet, + }; +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/looping/_main.md b/docs-source/forms-source/form1-doc/looping/_main.md new file mode 100644 index 0000000..f6addad --- /dev/null +++ b/docs-source/forms-source/form1-doc/looping/_main.md @@ -0,0 +1,10 @@ + + +Now it is time to use functions to examine looping and comparisons. + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/looping.md b/docs-source/forms-source/form1-doc/looping/vectorsShorterThan.md similarity index 93% rename from docs-source/forms-source/form1-doc/looping.md rename to docs-source/forms-source/form1-doc/looping/vectorsShorterThan.md index f2bf7b1..d07f350 100644 --- a/docs-source/forms-source/form1-doc/looping.md +++ b/docs-source/forms-source/form1-doc/looping/vectorsShorterThan.md @@ -1,11 +1,8 @@ -Now it is time to use functions to examine looping and comparisons. - -### \*\*getVectorsShorterThan\*\* You will now create a function called `getVectorsShorterThan` that will take an array of arrays. It will compare each array based on its magnitude and return all arrays that have a magnitude smaller then the number provided. @@ -17,7 +14,7 @@ getVectorsShorterThan(length, arrayOfVectors) Such that `length` is the number for which You will compare magnitudes against, and `arrayOfVectors` is the array of arrays, where then inner arrays are to contain numbers. -#### It returns an array of one vector when the vector is shorter than 5 -- arguments are: length, arrayOfVectors +#### It returns an array of one vector when the vector is shorter than 5 #### Create a the function `getVectorsShorterThan` where the first parameter is `length` and the second parameter is `arrayOfVectors` that returns all vectors where the magnitude is less then 5. There is only one vector at this point and its length is less then 5. @@ -43,7 +40,7 @@ Can you just return the first value of the array? -#### It returns an empty array when all vectors are too long -- tests one vector +#### It returns an empty array when all vectors are too long -- tests one vector #### Modify the `getVectorsShorterThan` function so that it will return an empty array if the first vector has a magnitude longer then `length`. @@ -93,7 +90,7 @@ Add logic to handle the case where a vector is too long (How might you compare t -#### It returns an array of more than one vector when all are short enough +#### It returns an array of more than one vector when all are short enough #### Modify the `getVectorsShorterThan` function so that it returns all vectors if the first one has a magnitude less then the length. @@ -143,7 +140,7 @@ Add logic to handle 0, 1 or 2 vector cases -### It returns only vectors which are not too long +#### It returns only vectors which are not too long ### Modify the `getVectorsShorterThan` function so that it now returns only those vectors with a magnitude less then the length. diff --git a/docs-source/forms-source/form1-doc/variables.md b/docs-source/forms-source/form1-doc/variables.md deleted file mode 100644 index 093e07a..0000000 --- a/docs-source/forms-source/form1-doc/variables.md +++ /dev/null @@ -1,218 +0,0 @@ - -You will explore the creation and use of variables. - -### declaration and initialization - -Here you will declare and initialize variables. - -#### It should have a variable called "a" - -Create a variable at the top of the block called "a". You will need to use `let` or `var`. - -
Hints - -Be sure you use "var" or "let" to declare your variable - -
Code - -**Example 1** - -```javascript -const jsforms = (function () { - 'use strict'; - let ?; - - return { - }; -})(); -``` - -**Example 2** - -```javascript -const jsforms = (function () { - 'use strict'; - var ?; - - return { - }; -})(); -``` - -
- -
- -#### It should initialize "a" with the value 5 - -Set the initial value of a to 5. - -
Hints - -Initialize a variable with equals: `var a = ...` - -
Code - -**Example 1** - -```javascript -const jsforms = (function () { - 'use strict'; - let a = ?; - - return { - }; -})(); -``` - -**Example 2** - -```javascript -const jsforms = (function () { - 'use strict'; - var a = ?; - - return { - }; -})(); -``` - -
- -
- -### assignment and operators - -Now that you have a variable you will assign it a value different then what it was initialized with. - -#### It should assign the sum of 3 and 7 (3 + 7) to "a" - -Now assign variable `a` with the value of `3 + 7`. - -
Hints - -Add two numbers using the plus (+) operator - -
Code - -**Example 1** - -```javascript - let a = 5; - a = ? + ?; - - return { - }; -``` - -**Example 2** - -```javascript - var a = 5; - a = ? + ?; - - return { - }; -``` - -
- -
- -#### It should have a variable "b" initialized to "Hello, World!" - -Create a variable called `b` and initialize it with the value `"Hello, World!" - -
Hints - -Initialize a variable with equals: `var b = ...` - -
Code - -**Example 1** - -```javascript - let b = ?; - - return { - }; -``` - -**Example 2** - -```javascript - var b = ?; - - return { - }; -``` - -
- -
- -### method call - -YOu will make a call to a method on an object. - -#### It should log variable "b" to the console - -Use the `console.log` method to log the value contained in variable `b` to the console. - -
Hints - -Console.log might be just the ticket... - -
Code - -**Example 1** - -```javascript - console.log(?); - - return { - }; -``` - -**Example 2** - -```javascript - console.log(?); - - return { - }; -``` - -
- -
- -### exposing values - -You well now expose values to the outside world. - -#### It should expose variable "b" to be read outside of the module - -Expose the variable `b` to the outside world, by adding it the the object being exported. - -
Hints - -Find `return {};` add a "b" -> `return {b};` - -
Code - -**Example** - -```javascript - return { - ?, - }; -``` - -
- -
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/variables/_main.md b/docs-source/forms-source/form1-doc/variables/_main.md new file mode 100644 index 0000000..e912672 --- /dev/null +++ b/docs-source/forms-source/form1-doc/variables/_main.md @@ -0,0 +1,13 @@ + + +You will explore the creation and use of variables. + \ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/variables/assignment.md b/docs-source/forms-source/form1-doc/variables/assignment.md new file mode 100644 index 0000000..5641692 --- /dev/null +++ b/docs-source/forms-source/form1-doc/variables/assignment.md @@ -0,0 +1,73 @@ + + +Now that you have a variable you will assign it a value different then what it was initialized with. + +#### It should assign the sum of 3 and 7 (3 + 7) to `a` #### + +Now assign variable `a` with the value of `3 + 7`. + +
Hints + +Add two numbers using the plus (+) operator + +
Code + +**Example 1** + +```javascript + let a = 5; + a = ? + ?; + + return { + }; +``` + +**Example 2** + +```javascript + var a = 5; + a = ? + ?; + + return { + }; +``` + +
+ +
+ +#### It should have a variable `b` initialized to `Hello, World!` #### + +Create a variable called `b` and initialize it with the value `"Hello, World!"` + +
Hints + +Initialize a variable with equals: `var b = ...` + +
Code + +**Example 1** + +```javascript + let b = ?; + + return { + }; +``` + +**Example 2** + +```javascript + var b = ?; + + return { + }; +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/variables/declaration.md b/docs-source/forms-source/form1-doc/variables/declaration.md new file mode 100644 index 0000000..c1b495c --- /dev/null +++ b/docs-source/forms-source/form1-doc/variables/declaration.md @@ -0,0 +1,83 @@ + + +Here you will declare and initialize variables. + +#### It should have a variable called `a` #### + +Create a variable at the top of the block called "a". You will need to use `let` or `var`. + +
Hints + +Be sure you use "var" or "let" to declare your variable + +
Code + +**Example 1** + +```javascript +const jsforms = (function () { + 'use strict'; + let ?; + + return { + }; +})(); +``` + +**Example 2** + +```javascript +const jsforms = (function () { + 'use strict'; + var ?; + + return { + }; +})(); +``` + +
+ +
+ +#### It should initialize `a` with the value 5 #### + +Set the initial value of a to 5. + +
Hints + +Initialize a variable with equals: `var a = ...` + +
Code + +**Example 1** + +```javascript +const jsforms = (function () { + 'use strict'; + let a = ?; + + return { + }; +})(); +``` + +**Example 2** + +```javascript +const jsforms = (function () { + 'use strict'; + var a = ?; + + return { + }; +})(); +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/variables/exposingValues.md b/docs-source/forms-source/form1-doc/variables/exposingValues.md new file mode 100644 index 0000000..815f4e7 --- /dev/null +++ b/docs-source/forms-source/form1-doc/variables/exposingValues.md @@ -0,0 +1,29 @@ + + +You well now expose values to the outside world. + +#### It should expose variable `b` to be read outside of the module #### + +Expose the variable `b` to the outside world, by adding it the the object being exported. + +
Hints + +Find `return {};` add a "b" -> `return {b};` + +
Code + +**Example** + +```javascript + return { + ?, + }; +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form1-doc/variables/methodCall.md b/docs-source/forms-source/form1-doc/variables/methodCall.md new file mode 100644 index 0000000..f665d8a --- /dev/null +++ b/docs-source/forms-source/form1-doc/variables/methodCall.md @@ -0,0 +1,38 @@ + +You will make a call to a method on an object. + +#### It should log variable `b` to the console #### + +Use the `console.log` method to log the value contained in variable `b` to the console. + +
Hints + +Console.log might be just the ticket... + +
Code + +**Example 1** + +```javascript + console.log(?); + + return { + }; +``` + +**Example 2** + +```javascript + console.log(?); + + return { + }; +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form2-doc/buildVector.md b/docs-source/forms-source/form2-doc/buildVector.md index 3ca7eb4..00d3317 100644 --- a/docs-source/forms-source/form2-doc/buildVector.md +++ b/docs-source/forms-source/form2-doc/buildVector.md @@ -3,13 +3,14 @@ (title "Build Vector") ) /bl--> + Now you will refactor the `buildVector` function changing its shape. -### Refactoring steps +### Refactoring steps ### These are the steps you will use to change the shape of the `buildVector` function without changing its behavior. -#### It has a refactoring in magnitude function to replace vector value with `vector.valueOf()` +#### It has a refactoring in magnitude function to replace vector value with `vector.valueOf()` #### Now modify the `magnitude` function by not passing the vector directly but passing the result of the `valueOf` method on vector. Currently the `valueOf` function just returns the original array. However this will make space for later changes that will happen to the `buildVector` function. @@ -32,7 +33,7 @@ Just add a `.valueOf()` call after the vector in the call to `sumOfSquares`. -#### It contains a constructor for an object called Vector +#### It contains a constructor for an object called Vector #### Now you will create a constructor for an object called `Vector`. You are not yet exporting that constructor. This constructor can just be an empty function. @@ -53,7 +54,7 @@ You will not be using JavaScripts class objects. Instead work from the original -#### It accepts a parameter "points" into Vector constructor +#### It accepts a parameter `points` into Vector constructor #### Modify the `Vector` function to take a parameter called points. There is no need to do anything with this parameter yet. @@ -74,7 +75,7 @@ The `Vector` constructor is just a function. All functions can have a name repre -#### It assigns `points` variable to "this.points" in `Vector` constructor +#### It assigns `points` variable to `this.points` in `Vector` constructor #### Modify the `Vector` constructor to save the `points` parameter. @@ -96,7 +97,7 @@ Remember in JavaScript, you do not have to predefine member variables before you -#### It overrides the valueOf function on the Vector prototype +#### It overrides the `valueOf` function on the Vector prototype #### Now you will need to override the internal `valueOf` function on `Vector`. Remember that `valueOf` comes from object and by default just returns the object. You will now change the behavior of this function to return a copy of its internal points. @@ -118,7 +119,7 @@ The way to override an internal function in JavaScript without the use of the `c -#### It overrides the `toString` function on the `Vector` prototype +#### It overrides the `toString` function on the `Vector` prototype #### Now you will need to override the internal `toString` function on `Vector`. Remember what you learned above. @@ -139,7 +140,7 @@ The way to override an internal function in JavaScript without the use of the `c -#### It should return a vector where toString returns a vector string +#### It should return a vector where `toString` returns a vector string #### You will modify the overridden `toString` method on `Vector` such that: @@ -187,7 +188,7 @@ You can use the [`Array.prototype.forEach`](https://developer.mozilla.org/en-US/ -#### It returns a new Vector object instead of an array +#### It returns a new Vector object instead of an array #### You will now modify the `buildVector` function to return a new `Vector` instead of an array of values. diff --git a/docs-source/forms-source/form2-doc/getVectorsShorterThan.md b/docs-source/forms-source/form2-doc/getVectorsShorterThan.md index 6c25fd0..6b71230 100644 --- a/docs-source/forms-source/form2-doc/getVectorsShorterThan.md +++ b/docs-source/forms-source/form2-doc/getVectorsShorterThan.md @@ -6,7 +6,7 @@ You will now modify the `getVectorsShorterThan` function changing its shape without changing its behavior. -### Refactoring steps +### Refactoring steps ### This is how you will modify the `getVectorsShorterThan` function such that it ensures you do not change its external behavior. @@ -16,7 +16,7 @@ This is how you will modify the `getVectorsShorterThan` function such that it en _**KEEP THE TESTS PASSING!**_ -#### It has a function called `isMagnitudeShorterThanLength` +#### It has a function called `isMagnitudeShorterThanLength` #### Create a function called `isMagnitudeShorterThanLength`. This can be an empty function right now. You are also _not_ exporting that function. @@ -37,7 +37,7 @@ Create a function that calculates the magnitude and then just return the value o -#### It has `vector` and `length` as parameters of `isMagnitudeShorterThanLength` +#### It has `vector` and `length` as parameters of `isMagnitudeShorterThanLength` #### You will modify the `isMagnitudeShorterThanLength` function to take the two parameters `vector` and `length`. You will also modify the function to return a [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) `true` if the vector's magnitude is less then the provided length and false if it is equal to or greater. @@ -60,7 +60,7 @@ You will need to calculate the magnitude (there is a function to help with this) -#### It is refactored to use `vectors.filter()` instead of for loop +#### It is refactored to use `vectors.filter()` instead of for loop #### You will modify the `getVectorsShorterThan` function to use the internal [`Array.prototype.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) instead of recreating the functionality in a for loop. @@ -84,7 +84,7 @@ The filter method takes a function as a parameter that returns a Boolean. If th -#### It does not assign filter to results, it just returns directly +#### It does not assign filter to results, it just returns directly #### Now modify the `getVectorsShorterThan` not to use the unnecessary variable `result`. diff --git a/docs-source/forms-source/form2-doc/greeter.md b/docs-source/forms-source/form2-doc/greeter.md index 17a5775..eb5354b 100644 --- a/docs-source/forms-source/form2-doc/greeter.md +++ b/docs-source/forms-source/form2-doc/greeter.md @@ -3,13 +3,14 @@ (title "Greeter") ) /bl--> + Let us change the `greet` function. -### Refactoring steps +### Refactoring steps ### Lets look at the steps in refactoring the `greet` function. -#### It is refactored to remove the unnecessary else +#### It is refactored to remove the unnecessary else #### Modify the `greet` function to remove the else statement. @@ -35,7 +36,7 @@ Because of the `return greeting + '!';` in the first part of the `if` statement -#### It is refactored to remove if and replace with a ternary expression +#### It is refactored to remove if and replace with a ternary expression #### Because both paths of the function return a value, you can change the shape of the code from an `if` `return` to a [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator). @@ -61,7 +62,7 @@ A ternary operator has the following form -#### It is refactored to use typeof comparison to "string" +#### It is refactored to use `typeof` comparison to `string` #### You will now modify the `greet` function to remove the `greeting === undefined` comparison and instead use the [typeof](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) operator to prove whether or not what was passed in was a string. @@ -81,4 +82,4 @@ The `typeof` operator returns a string with the name of the type. Maybe you can - + \ No newline at end of file diff --git a/docs-source/forms-source/form2-doc/squareAll.md b/docs-source/forms-source/form2-doc/squareAll.md index a8bb27c..e3987f1 100644 --- a/docs-source/forms-source/form2-doc/squareAll.md +++ b/docs-source/forms-source/form2-doc/squareAll.md @@ -3,13 +3,14 @@ (title "Square All") ) /bl--> + You will now refactor and change the shape of the `squareAll` method. -### Refactoring steps +### Refactoring steps ### These are the steps you will take in changing the shape of the `squareAll` method, to ensure you do not change its behavior. -#### It is refactored to replace for loop with `nums.map` +#### It is refactored to replace for loop with `nums.map` #### The [`Array.prototype.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function allows you to perform a function on each member of an array and capture the result. Use this method instead of the given for loop. @@ -41,7 +42,7 @@ The `Array.prototype.map` allows you to transform all values in an array such th -#### It is refactored to remove function wrapping `square` +#### It is refactored to remove function wrapping `square` #### Now modify the `squareAll` function to simplify the function expression or the arrow function expression. @@ -64,7 +65,7 @@ If you were to log all items in an array to the console, you don't need a functi -#### It is refactored to return result of map operation without assigning output to result +#### It is refactored to return result of map operation without assigning output to result #### Now modify the `squareAll` function to remove the unnecessary `result` variable. diff --git a/docs-source/forms-source/form2-doc/sum.md b/docs-source/forms-source/form2-doc/sum.md index ae8e066..0cf1cc1 100644 --- a/docs-source/forms-source/form2-doc/sum.md +++ b/docs-source/forms-source/form2-doc/sum.md @@ -3,13 +3,14 @@ (title "Sum") ) /bl--> + You are going to refactor and change the shape of the `sum` method. -### Refactoring steps +### Refactoring steps ### These are the steps you will use to change the shape of the `sum` method, thereby changing how it does its work, while not changing the work it does. -#### It has an add function +#### It has an add function #### Now create a function called `add` that takes two number and adds them. You are _not_ exporting this function, it is part of your refactoring of the `sum` function. @@ -29,7 +30,7 @@ Return the values after using the `+` operator. -#### It is refactored to replace += with a call to the add function +#### It is refactored to replace += with a call to the add function #### Modify the `sum` method to use the new `add` method above instead of the `+=` operator. @@ -57,7 +58,7 @@ The `+=` operator is equivalent to setting a value to itself plus the other valu -#### It is refactored to replace for loop with `nums.forEach` +#### It is refactored to replace for loop with `nums.forEach` #### Now modify the `sum` method to remove the `for` loop, and use the [`Array.prototype.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) method provided on nums. @@ -83,7 +84,7 @@ Now modify the `sum` method to remove the `for` loop, and use the [`Array.protot -#### It is refactored to replace the function expression with an arrow function +#### It is refactored to replace the function expression with an arrow function #### Now modify the `sum` function to replace the function expression with an [arrow function expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). diff --git a/docs-source/forms-source/form3-doc/buildVector.md b/docs-source/forms-source/form3-doc/buildVector.md index fbf4fe6..1a43ac1 100644 --- a/docs-source/forms-source/form3-doc/buildVector.md +++ b/docs-source/forms-source/form3-doc/buildVector.md @@ -3,13 +3,14 @@ (title "Build Vector") ) /bl--> + You will refactor the `buildVector` function. -### Getter properties and value immutability +### Getter properties and value immutability ### You will learn how to add readonly properties to an object. You will be modifying the `Vector` object. -#### It should have access to read, but not write, vector.points +#### It should have access to read, but not write, vector.points #### The `Vector` object's internal `points` array should be read only. This is accomplished by using a [property getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get). @@ -39,7 +40,7 @@ function Vector(points) { -#### It should not change `Vector` object when the original array is modified +#### It should not change `Vector` object when the original array is modified #### Now you will modify the `Vector` function to return a copy of the array passed into it. This will isolate the `Vector` object from changes that happen outside of the object. @@ -64,7 +65,7 @@ Maybe the `Array.prototype.slice` method might be useful. -#### It should not be possible to modify `vector.points` +#### It should not be possible to modify `vector.points` #### Modify the `Vector` method to make the copy of the `points` array read only. @@ -89,11 +90,11 @@ It might help to use the [Object.freeze](https://developer.mozilla.org/en-US/doc -#### Constructor type check +#### Constructor type check #### You will be modifying the `Vector` function to have better type checking. This will include type validation and throwing of errors. -#### It throws an error if constructor is called with a value which is not an array +#### It throws an error if constructor is called with a value which is not an array #### Modify the `Vector` function to throw an error if the `points` parameter is not a type of an array. @@ -122,7 +123,7 @@ To test that something is an array or not, you cannot use the `typeOf` function -#### It throws an error if constructor is called with an array of one value which is not a number +#### It throws an error if constructor is called with an array of one value which is not a number #### Modify the `Vector` function to check the type of the first element in the array to ensure it is a number. Then `throw` a new `Error` if it isn't. @@ -155,7 +156,7 @@ You might be able to use the `isTypeOf` function here. -#### It throws an error if constructor is called with an array which contains values other than numbers +#### It throws an error if constructor is called with an array which contains values other than numbers #### Modify the `Vector` function to check the type of all elements in the array to ensure that they are all numbers. Then `throw` a new `Error` if any of them are not. @@ -210,14 +211,14 @@ You might be able to use the `Array.prototype.filter` method or the `Array.proto -#### Refactoring steps +#### Refactoring steps #### Now you will modify the `Vector` method such that you will change the shape of it without changing the behavior. 1. You will create methods that handle the type checking. 2. You will then utilize these methods instead of having the error checking embedded in the `Vector` constructor. -##### It has a function called `assertArray` with parameter `values` +##### It has a function called `assertArray` with parameter `values` ##### Create a function called `assertArray` which will look at the type of the parameter `values` and throw an exception if `values` is not an array. @@ -241,7 +242,7 @@ You already have the code, you will just add it into a new function. -##### It has a function called `assertArrayOfType` with a parameters `type` and `values`' +##### It has a function called `assertArrayOfType` with a parameters `type` and `values` ##### Now create a function called `assertArrayOfType` that compares all items in `values` with the given `type` and throws an exception if any of the values are not the correct type. @@ -278,7 +279,7 @@ Again you already have this code. You just need to add it in the new function. -##### It has a call in `assertArrayOfType` function to `assertArray` with `values` as an argument' +##### It has a call in `assertArrayOfType` function to `assertArray` with `values` as an argument ##### Modify the `assertArrayOfType` function to call the `assertArray` function before it checks the values in the array. @@ -312,7 +313,7 @@ Modify the `assertArrayOfType` function to call the `assertArray` function befor -##### It has a call in `Vector` constructor to `assertArrayOfType` +##### It has a call in `Vector` constructor to `assertArrayOfType` ##### Now modify the `Vector` function to call the `assertArrayOfType` instead of the logic to check the type. diff --git a/docs-source/forms-source/form3-doc/greeter.md b/docs-source/forms-source/form3-doc/greeter.md index 7c15f99..80382e6 100644 --- a/docs-source/forms-source/form3-doc/greeter.md +++ b/docs-source/forms-source/form3-doc/greeter.md @@ -3,9 +3,10 @@ (title "Greeter") ) /bl--> + You are going to start by refactoring the `greet` function. -### Refactoring steps +### Refactoring steps ### Here are the steps you will take to refactor the `greet` function to ensure you change the shape without changing the behavior. @@ -14,7 +15,7 @@ Here are the steps you will take to refactor the `greet` function to ensure you 3. Create function called `eitherOnType` 4. Replace ternary in greet function with `eitherOnType` -#### It has a function called `isTypeOf` which takes parameters `type` and `value` +#### It has a function called `isTypeOf` which takes parameters `type` and `value` #### Create a function called `isTypeOf` with the two parameters of `type` and `value`. You are _not_ exporting this function. This function checks the type of the `value` and returns a Boolean true if the `value` is of the given `type`. @@ -36,7 +37,7 @@ This will use `typeOf` to do the check. -#### It calls isTypeOf from greet +#### It calls `isTypeOf` from greet #### Now you will modify the `greet` function to use the `isTypeOf` function instead of the `typeOf` function. @@ -58,7 +59,7 @@ You will need to replace not only the call to `typeOf` but also the comparison t -#### It has a function called `eitherOnType` with parameters `type`, `testValue`, `defaultValue` -- return `testValue` if it matches `type`, otherwise return `defaultValue` +#### It has a function called `eitherOnType` with parameters `type`, `testValue`, `defaultValue` -- return `testValue` if it matches `type`, otherwise return `defaultValue` #### Create a the function `eitherOnType`, you will _not_ export this function. The `eitherOnType` function takes two parameters `testValue` and `type`. It then compares the `testValue`'s type. If the `testValue` has the same type as the one given, it returns the `testValue`. If the `testValue` has a different type then it returns the `defaultValue`. @@ -92,7 +93,7 @@ You will want to use the new `isTypeOf` function. -#### It calls eitherOnType from greet +#### It calls `eitherOnType` from greet #### Modify the `greet` function so that you replace the trinary operator with the `eitherOnType` function. diff --git a/docs-source/forms-source/form3-doc/sum.md b/docs-source/forms-source/form3-doc/sum.md index 05c2077..ef06cb5 100644 --- a/docs-source/forms-source/form3-doc/sum.md +++ b/docs-source/forms-source/form3-doc/sum.md @@ -3,9 +3,10 @@ (title "Sum") ) /bl--> + You will refactor the `sum` function. -### Refactoring steps +### Refactoring steps ### Here are the steps you will take to refactor the `sum` method so that you can change its shape without changing its behavior. @@ -15,7 +16,7 @@ Here are the steps you will take to refactor the `sum` method so that you can ch _**KEEP THE TESTS PASSING!**_ -#### It has been refactored to use `reduce` in the place of `forEach`, assigning the output to result +#### It has been refactored to use `reduce` in the place of `forEach`, assigning the output to result #### Modify the `sum` function to use the [`Array.prototype.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) method in place of the [`Array.prototype.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) method. @@ -52,7 +53,7 @@ In short you can use this similarly to the `forEach` method but without the need -#### It has been refactored to pass the add function directly to reduce +#### It has been refactored to pass the add function directly to reduce #### Modify the `sum` function to no longer use a function expression and instead just directly use the `add` function. @@ -76,7 +77,7 @@ The `reduce` method takes a function with two parameters, `add` takes two parame -#### It has been refactored to not assign the sum before returning it +#### It has been refactored to not assign the sum before returning it #### Modify the `sum` function to just return the result instead of assigning it to a variable. diff --git a/docs-source/forms-source/form4-doc/_main.md b/docs-source/forms-source/form4-doc/_main.md index 2d56ed2..04a36ae 100644 --- a/docs-source/forms-source/form4-doc/_main.md +++ b/docs-source/forms-source/form4-doc/_main.md @@ -14,9 +14,11 @@ You will be working in the [test/4_test-dummy-form.test.js](../test/4_test-dummy \ No newline at end of file +/bl--> +## TDB ## \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/app/_main.md b/docs-source/forms-source/form4-doc/app/_main.md new file mode 100644 index 0000000..ab9028d --- /dev/null +++ b/docs-source/forms-source/form4-doc/app/_main.md @@ -0,0 +1,13 @@ + + +The application under test is a Point of Sale reporting utility. It will report on all sales or all returns. + \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/app/importantFiles.md b/docs-source/forms-source/form4-doc/app/importantFiles.md new file mode 100644 index 0000000..a493062 --- /dev/null +++ b/docs-source/forms-source/form4-doc/app/importantFiles.md @@ -0,0 +1,8 @@ + + +> jsforms-source/4_test-dummy-form/sales-reporter/[salesReporterFactory.js](../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js) +> jsforms-source/4_test-dummy-form/pos-transaction-services/[reportDataBuilder.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js) \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/app.md b/docs-source/forms-source/form4-doc/app/pointOfSaleDataUtilityFactoryBuilder.md similarity index 89% rename from docs-source/forms-source/form4-doc/app.md rename to docs-source/forms-source/form4-doc/app/pointOfSaleDataUtilityFactoryBuilder.md index f0d7160..497320b 100644 --- a/docs-source/forms-source/form4-doc/app.md +++ b/docs-source/forms-source/form4-doc/app/pointOfSaleDataUtilityFactoryBuilder.md @@ -1,13 +1,9 @@ -The application under test is a Point of Sale reporting utility. It will report on all sales or all returns. - -### Point Of Sale Data Utility Factory Builder - File: [/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js) This will build the utility that calculates counts for items based on their transaction status. @@ -16,7 +12,7 @@ This function takes a single parameter `transactionStatuses` that allow the stat `Sale` which is a constant number that maps to transactions caused by the sale of product. For our tests we will configure this to have the value `1`. -and +and `Return` which is a constant number that maps to transactions caused by the return of product. For our tests we will configure this to have the value `2`. @@ -24,7 +20,7 @@ These values are already set up for you. This function returns an object with two methods. -#### `getProductCountBySale` +#### Get Product Count by Sale #### This method takes the parameter `transactionRecords` which is an array of transaction records. Each record is expected to have the following shape: @@ -73,7 +69,7 @@ The result should look like the following: Because there is a total of 5 items sold of Product ID 3, and only 4 items sold of Product ID 6. -### `getProductCountByReturn` +#### Get Product Count by Return #### This method takes the parameter `transactionRecords` which is an array of transaction records. Each record is expected to have the following shape: @@ -120,8 +116,4 @@ The result should look like the following: } ``` -Because there is a total of 3 items returned of Product ID 3, and 5 items returned of Product ID 6. - -### Report Data Builder Factory - -TBD \ No newline at end of file +Because there is a total of 3 items returned of Product ID 3, and 5 items returned of Product ID 6. \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/app/reportDataBuilderFactory.md b/docs-source/forms-source/form4-doc/app/reportDataBuilderFactory.md new file mode 100644 index 0000000..8be4c15 --- /dev/null +++ b/docs-source/forms-source/form4-doc/app/reportDataBuilderFactory.md @@ -0,0 +1,80 @@ + + +The function `reportDataBuilderFactory` has the following signature: + +```javascript +function reportDataBuilderFactory(transactionStatuses) +``` + +#### Report Data Builder Factory Parameter #### + +It takes an object with the following shape: + +```javascript +{ + Sale = X, // where X is an integer number + Return = Y // where Y is an integer number +} +``` + +#### Report Data Builder Factory Return Value #### + +It then returns an object with the following structure: + +```javascript +{ + buildReportData +} +``` + +##### Build Report Data Parameters ##### + +The `buildReportData` is a function that has the following signature: + +```javascript +buildReportData( + transactionStatus /*integer number*/, + transactionData /*object array*/, + productData /*object array*/ +) +``` + +The `transactionStatus` parameter maps to one of the integers in the `transactionStatuses` object. + +The `transactionData` parameter is an array of objects with the following structure: + +```javascript +{ + productId, // integer number -- id from a product datum + transactionStatus, // integer number -- sale or return, must match the transactionStatuses object + quantity // integer number -- count sold or returned +} +``` + +The `productData` parameter is an array of objects that have the following structure: + +```javascript +{ + id, // integer number -- id uniquely identifies this product + name, // string -- Name of product + price // number -- the sales price for a single item of this product +} +``` + +##### Build Report Data Return Value ##### + +The `buildReportData` function returns an array of objects that have the following structure: + +```javascript +{ + productName, // string -- Name of product, from productDatum.Name + quantity, // integer number -- count sold or returned, total of transactionData.quantity + total // number -- the sales price for a single item of this product quantity * productDatum.price +} +``` + +Each item in the array will represent the results for a different product. \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/app/salesReporterFactory.md b/docs-source/forms-source/form4-doc/app/salesReporterFactory.md new file mode 100644 index 0000000..24fcc70 --- /dev/null +++ b/docs-source/forms-source/form4-doc/app/salesReporterFactory.md @@ -0,0 +1,120 @@ + + +The `salesReporterFactory` function has the following signature + +```javascript +function salesReporterFactory( + dataLoader, + pointOfSaleDataUtilsFactory, + reportDataBuilderFactory +) +``` + +#### Sales Reporter Factory Parameters #### + +The `dataLoader` parameter is an object with following shape: + +```javascript +{ + getProductData, + getTransactionData, + getTransactionStatuses +} +``` + +##### Get Product Data Function ##### + +The getProductData function has the following signature: + +```javascript +getProductData() +``` + +###### Get Product Data Return Value ###### + +The `getProductData` function returns an array of objects that have then following structure: + +```javascript +{ + id, // integer number -- id uniquely identifies this product + name, // string -- Name of product + price // number -- the sales price for a single item of this product +} +``` + +##### Get Transaction Data Function ##### + +The `getTransactionData` function has the following signature: + +```javascript +getTransactionData() +``` + +###### Get Transaction Data Return Value ###### + +The `getTransactionData` function returns an array of objects that have the following structure: + +```javascript +{ + productId, // integer number -- id from a product datum + transactionStatus, // integer number -- sale or return, must match the transactionStatuses object + quantity // integer number -- count sold or returned +} +``` + +##### Get Transaction Types Function ##### + +The `getTransactionStatuses` function has the following signature: + +```javascript +getTransactionStatuses() +``` + +###### Get Transaction Types Return Value ###### + +The `getTransactionStatuses` function returns an object with the following structure: + +```javascript +{ + Sale = X, // where X is an integer number + Return = Y // where Y is an integer number +} +``` + +#### Sales Reporter Factory Return Value #### + +The `` function returns an object with the following structure: + +```javascript +{ + getReport +} +``` + +##### Get Report Function ##### + +The `getReport` function has the following signature: + +```javascript +function getReport(transactionStatus) +``` + +The `transactionStatus` parameter is an integer number that maps to Sale or Return as determined by the `transactionStatuses` returned from the `getTransactionStatuses` function. + +###### Get Report Return Value ###### + +The `getReport` function returns an array of objects with the following structure: + +```javascript +{ + productName, // string -- Name of product, from productDatum.Name + quantity, // integer number -- count sold or returned, total of transactionData.quantity + total // number -- the sales price for a single item of this product quantity * productDatum.price +} +``` + +Each item in the array will represent the results for a different product. \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/getReport/_main.md b/docs-source/forms-source/form4-doc/getReport/_main.md new file mode 100644 index 0000000..71055e6 --- /dev/null +++ b/docs-source/forms-source/form4-doc/getReport/_main.md @@ -0,0 +1,14 @@ + + +In testing the `getReport` function, you will be required to do a lot more of the initial work. Fortunately you have the code from the "get product count by sale" test suite you just finished. + +The `getReport` function can either create a Sales report or a Returns report. + \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/getReport/getReturnsReport.md b/docs-source/forms-source/form4-doc/getReport/getReturnsReport.md new file mode 100644 index 0000000..ef3f20e --- /dev/null +++ b/docs-source/forms-source/form4-doc/getReport/getReturnsReport.md @@ -0,0 +1,68 @@ + + +There is little to do in testing the "Returns" report because if you look at the code, it is almost entirely the same code as what creates the "Sales" report. So the only thing we have to do is test that it correctly filters when we ask for a report of the "Returns". + +#### It returns a report of return transactions that excludes sales transactions #### + +You will now create a test that will verify that the report is correct when you ask for it to give you a report of the returns. + +You will want at least three different transactions records that are composed of at least two different product IDs. You will want one of those records to be a Sale and the rest to be Returns. + +You will then verify that the resulting object has the correct products, quantities, and prices. + +Remember to pass `transactionStatuses.Return` to the `getReport` function. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +This will look very much like the last test but the transaction statuses are swapped. + +
Code + +**Example** + +```javascript +describe('get returns report', function () { + it('returns a report of return transactions that excludes sales transactions', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Return, ?)); + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); // This is the record that is not going to be counted + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Return, ?)); + + let result = reportBuilder(transactionStatuses.Return); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the first product ID + quantity: ?, // The quantity of the first transaction record + total: ? // the price from the first product multiplied by te quantity + }, + { + productName: ?, // The name that maps to the third product ID + quantity: ?, // The quantity of the third transaction record + total: ? // the price from the third product multiplied by the quantity + }, + ]); + + }); +}); +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/getReport/getSalesReport.md b/docs-source/forms-source/form4-doc/getReport/getSalesReport.md new file mode 100644 index 0000000..124765d --- /dev/null +++ b/docs-source/forms-source/form4-doc/getReport/getSalesReport.md @@ -0,0 +1,515 @@ + + +You will be focusing on testing that a sales report is created correctly. In creating these tests you will follow the basic steps listed bellow. + +1. Write the first test. +2. Write the second test. +3. Refactor tests to remove repetitive code into a `beforeEach` block. +4. Finish writing tests, stopping periodically to refactor as needed. + +Now when you write each test, you will follow the process you did before with one additional step. + +1. Enable the test +2. Add guide comments +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +#### It returns a report of sales with no sales #### + +Starting with a base case of there were no sales, you will write the test that proves that it returns a report with nothing in it. + +To test the `getReport` function you will need to first call the `salesReporterFactory` function. The `salesReporterFactory` has the following signature: + +```javascript +function salesReporterFactory( + dataLoader, + pointOfSaleDataUtilsFactory, + reportDataBuilderFactory +) +``` + +You will have to create a fake `dataLoader`. You will also use the `pointOfSaleDataUtilsFactory` and the `reportDataBuilderFactory` that are already available to the test. + +This will return an empty array. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +
Data Loader Hints + +The `dataLoader` has 3 functions and the following structure: + +```javascript +{ + getProductData, + getTransactionData, + getTransactionStatuses +} +``` + +The `getProductData` will be set to the `buildProductData` helper function. The `getTransactionStatuses` will be set to the `buildTransactionStatuses` helper function. + +The real odd ball here is the `getTransactionData` which is expected to return an array of transaction records. You will have to create this function, and have it return an empty array. + +
Code + +**Example** + +```javascript + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [], + getTransactionStatuses: buildTransactionStatuses + }; +``` + +
+ +
+ +
Hints + +You just have to pass the values to the function, and capture the returned function. You will then have to call that function with a "Sale" transactionStatus. + +
Code + +```javascript +it('returns an empty object for sale counts if no sale data exists', () => { + // Arrange + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [], + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + // Act + let result = getReport(transactionStatuses.Sale); + + // Assert + assert.deepEqual(result, []); +}); +``` + +
+ +
+ +#### It returns a report of sales with one sale #### + +Okay, the last test did a lot of heavy lifting for you. Now you will test the `getReport` function for a sales report with only one item sold. + +The biggest change between this test and the previous one is that the `getTransactionData` needs to return a single transaction record that has a `quantity` of `1`. + +The `getReport` function will return an array containing a single object with the following structure: + +```javascript +{ + productName, // string -- Name of product, from productDatum.Name + quantity, // integer number -- count sold or returned, total of transactionData.quantity + total // number -- the sales price for a single item of this product quantity * productDatum.price +} +``` + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +
Arrange Hints + +You are going to setup the `dataLoader` the same way as you did before. But again the odd item out is the `getTransactionData` function because this needs to return an array with a single transaction record for a sale. + +The key here is that the transaction record `productId` needs to match one of the products returned from `getProductData`. The `transactionStatus` needs to match the `Sale` property on the `transactionStatuses` object. You will need to use the `buildTransactionRecord` function to create this record. + +
Code + +**Example** + +```javascript +// Arrange +let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [ + buildTransactionRecord(?, transactionStatuses.Sale, 1) + ], + getTransactionStatuses: buildTransactionStatuses +}; + +let { getReport } = salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); +``` + +
+ +
+ +
Hints + +Once you have the `dataLoader` created, you will need to only change the Assert part of the code. Remember the `total` in the result is the product's `price`. + +
Code + +**Example** + +```javascript +it('returns a report of sales with one sale', () => { + // Arrange + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [ + buildTransactionRecord(?, transactionStatuses.Sale, 1) + ], + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + // Act + let result = getReport(transactionStatuses.Sale); + + // Assert + assert.deepEqual(result, [{ + productName: ?, + quantity: ?, + total: ? + }]); +}); +``` + +
+ +
+ +#### Refactor Sales Report Tests #### + +You have introduced a lot of duplication. And moreover the duplication in the "Arrange" part of your tests is most likely needed for the rest of the tests. As such, it is time you simplify your tests. + +A lot of JavaScript test frameworks use a construct called `beforeEach` that creates a function that is run just before each test. This allows you to setup common variables. These variables will be test suite scoped variables. + +> **
WARNING
** +> +>
You must be careful when using a test suite scoped variables as you can accidentally cause one test to effect another. To prevent this, you must reset all such variables to an initial value in the beforeEach.
+ +##### Refactor Sales Report Tests Create the Before Each ##### + +You need to create the `getReport` function in the `beforeEach` section. However, in order for this to work you will also need to create and assign a variable to hold the transaction records. This way you can add an item to it in the second test. + +
Hints + +You will need to create two variables before the "get sales report" section. One to hold the `getReport` function and the other to hold the transaction records. + +Bellow those, but still before the "get sales report" section, you will need to create the `beforeEach` section. + +
Code + +**Example** + +```javascript + describe('get report', function () { + // files being tested are: + // ../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js + + let reportBuilder; + let transactionRecords; + + beforeEach(() => { + transactionRecords = []; + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => transactionRecords, + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = + salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + reportBuilder = getReport; + }); + + describe('get sales report', function () { +``` + +
+ +
+ +##### Refactor Sales Report Tests Modify the First Test ##### + +You need to change the first test, "returns a report of sales with no sales", so that it uses the new suite level variables. + +
Hints + +The whole arrange is now being done in the `beforeEach`. So delete that and use the variable that is holding the `getReport` function. + +
Code + +**Example** + +```javascript + describe('get report', function () { + // files being tested are: + // ../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js + + let reportBuilder; + let transactionRecords; + + beforeEach(() => { + transactionRecords = []; + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => transactionRecords, + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = + salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + reportBuilder = getReport; + }); + + describe('get sales report', function () { + it('returns an empty object for sale counts if no sale data exists', () => { + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, []); + }); +``` + +
+ +
+ +##### Refactor Sales Report Tests Modify the Second Test ##### + +The second test has more to it. You still have an arrange that is specific to the test. You need to add the transaction record to the variable used to store the transaction records. You might be able to use the [`Array.prototype.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) method. + +
Hints + +Most of the arrange in this test can be deleted. You will just need to add the sales transaction record to the array before calling the `getReport` function. + +
Code + +**Example** + +```javascript + let reportBuilder; + let transactionRecords; + + beforeEach(() => { + transactionRecords = []; + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => transactionRecords, + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = + salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + reportBuilder = getReport; + }); + + describe('get sales report', function () { + + // ... + + it('returns a report of sales with one sale', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, 1)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [{ + productName: ?, + quantity: ?, + total: ? + }]); + }); +``` + +
+ +
+ +#### It returns a report of sales with two sales of different products #### + +Now you will test that the `getReport` can return a report with two different products. + +This will look very similar to the above test, but you will need to add two products, with different quantities to the transaction records. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +Add the two different products to the transaction records. Make sure that the `productId` of each maps to a product that is returned by the `buildProductData` function. You will also want each product to have a different non-one `quantity` value. + +You will also have two objects in the result to test for. + +
Code + +**Example** + +```javascript +it('returns a report of sales with two sales of different products', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the first product ID + quantity: ?, // The quantity of the first transaction record + total: ? // the price from the first product multiplied by te quantity + }, + { + productName: ?, // The name that maps to the second product ID + quantity: ?, // The quantity of the second transaction record + total: ? // the price from the second product multiplied by the quantity + }, + ]); +}); +``` + +
+ +
+ +#### It returns a report of sales with two sales of the same product #### + +You will test what happens if the transaction records have two different transactions for the sale of the same product. The result should represent the total of the quantity. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +This test will look very similar to the above with the difference that the two transaction records will share the same `productId`. + +There will only be a single object in the result. + +
Code + +**Example** + +```javascript +it('returns a report of sales with two sales of the same product', () => { + let productId = ?; + transactionRecords.push(buildTransactionRecord(productId, transactionStatuses.Sale, ?)); + transactionRecords.push(buildTransactionRecord(productId, transactionStatuses.Sale, ?)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the product ID + quantity: ?, // The total quantity of the transaction records + total: ? // the price from the product multiplied by the total quantity + }, + ]); +}); +``` + +
+ +
+ +#### It returns a report of sales excluding any return transactions #### + +Now, you will verify that the `getReport` function filters according to the Sale transaction status. + +You will want to create a number of sale transactions, at least 3 across at least two products, with one or more return transactions mixed into the bunch. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +You are going to create the test very similarly to two tests ago, but you will add a new transaction record that has the `transactionStatus` equal to Return. + +
Code + +**Example** + +```javascript +it('returns a report of sales excluding any return transactions', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Return, ?)); // This is the record that is not going to be counted + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the first product ID + quantity: ?, // The quantity of the first transaction record + total: ? // the price from the first product multiplied by te quantity + }, + { + productName: ?, // The name that maps to the third product ID + quantity: ?, // The quantity of the third transaction record + total: ? // the price from the third product multiplied by the quantity + }, + ]); +}); +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/getReport/importantFiles.md b/docs-source/forms-source/form4-doc/getReport/importantFiles.md new file mode 100644 index 0000000..a918a49 --- /dev/null +++ b/docs-source/forms-source/form4-doc/getReport/importantFiles.md @@ -0,0 +1,18 @@ + + +Test File: + +> test/[4_test-dummy-form.test.js](../test/4_test-dummy-form.test.js) + +Files Under Test: + +> jsforms-source/4_test-dummy-form/sales-reporter/[salesReporterFactory.js](../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js) +> jsforms-source/4_test-dummy-form/pos-transaction-services/[reportDataBuilder.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js) + +Helpers File: + +> test/form-helpers/[4_test-dummy-helpers.js](../test/form-helpers/4_test-dummy-helpers.js) \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/pointOfSaleDataUtils.md b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils.md deleted file mode 100644 index a784e09..0000000 --- a/docs-source/forms-source/form4-doc/pointOfSaleDataUtils.md +++ /dev/null @@ -1,474 +0,0 @@ - - -### Important Files - -Test File: - -> test/[4_test-dummy-form.test.js](../test/4_test-dummy-form.test.js) - -File Under Test: - -> jsforms-source/4_test-dummy-form/pos-transaction-services/[pointOfSaleDataUtilsFactory.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js) - -Helpers File: - -> test/form-helpers/[4_test-dummy-helpers.js](../test/form-helpers/4_test-dummy-helpers.js) - -### Get product count by sale - -You will be testing that the `getProductCountBySale` works correctly. (Don't worry it does, but you have to prove it.) - -There are a series of tests already layed out for you. We will approach each one individually. - -#### It returns an empty object for sale counts if no sale data exists - -This first test ensures that the `getProductCountBySale` function works properly if you give it nothing to do. So when you give it an empty array, it should return an empty object. - -The process you will follow is: - -1. Enable the test -2. Add guide comments - 1. Act - 2. Assert -3. Implement the act -4. Implement the assert -5. Remove Guide comments - -##### Enable the test - -Each test case is defined by an `it` block. The format for an it block is as follows - -```javascript - it('has a description here', testFunction); -``` - -The description is the name of the test. The test function, can be a function name, a function expression, or an arrow function expression. For this exorcise use the arrow function expression like bellow. - -```javascript - it('does some thing', () => {}); -``` - -This step will cause the test to pass. However it is a false positive as this test does nothing. - -
Hints - -The `it` already exists on line 51, all you need to do is add the arrow function expression. The description is the name of the parent section without then "It": - -> returns an empty object for sale counts if no sale data exists - -
Code - -**Example** - -```javascript - it('returns an empty object for sale counts if no sale data exists', () => {}); -``` - -
- -
- -##### Add Guiding Comments - -To the arrow function expression, you will add the following comments - -```javascript -// Act -// Assert -``` - -These represent the logical steps of testing such a simple thing. We will then use the comments to implement the test. - -
Hints - -You will need to add two line brakes to the arrow function expression between the curly braces. - -
Code - -**Example** - -```javascript - it('returns an empty object for sale counts if no sale data exists', () => { - // Act - // Assert - }); -``` - -
- -
- -##### Implement the act - -The "Act" refers to the action under test. You will need to do the thing the test is trying to test. So with this test you are trying to test what will happen when `getProductCountBySale` method on the `pointOfSaleDataUtilities` object is called with an empty array. - -
Hints - -You need to make a call the the `getProductCountBySale` method with an empty array and set a variable to that result. - -
Code - -**Example** - -```javascript - it('returns an empty object for sale counts if no sale data exists', () => { - // Act - let result = pointOfSaleDataUtilities.getProductCountBySale([]); - // Assert - }); -``` - -
- -
- -##### Implement the Assert - -Assert refers to the need to validate that the code does what we expect it to do. It often uses a keyword `assert`. For our tests they will. - -Now you need to validate that the result to the call of `getProductCountBySale` returns an empty object. - -> Note: an empty object in JavaScript is an object with no properties or methods. i.e `{}` - -You will use the `assert.deepEqual` method to prove this. This method has the following signature: - -```javascript -assert.deepEqual(actualResult, expectedResult) -``` - -
Hints - -The expected result is `{}`. - -
Code - -**Example** - -```javascript - it('returns an empty object for sale counts if no sale data exists', () => { - // Act - let ? = pointOfSaleDataUtilities.getProductCountBySale([]); - // Assert - assert.deepEqual(?, {}); - }); -``` - -
- -
- -##### Remove Guide comments - -Now delete then comments as they provide no extra value. - -
Hints - -Delete the comment lines - -
Code - -**Example 1 (`let`)** - -```javascript - it('returns an empty object for sale counts if no sale data exists', () => { - let ? = pointOfSaleDataUtilities.getProductCountBySale([]); - - assert.deepEqual(?, {}); - }); -``` - -**Example 2 (`var`)** - -```javascript - it('returns an empty object for sale counts if no sale data exists', () => { - var ? = pointOfSaleDataUtilities.getProductCountBySale([]); - - assert.deepEqual(?, {}); - }); -``` - -
- -
- -### It returns an object with a single count of 1 when only one item, quantity 1 was purchased - -The next test is to test what happens when a only one item is passed to the `getProductCountBySale` method and it is a sale with only one item sold of that product. - -It will then return an item with a property equal to the product ID with an integer value equal to that item's quantity. So if `productId: 42` was passed you should get an item that looks like: - -```javascript -{ - [42]: 1 -} -``` - -The process you will follow is: - -1. Enable the test -2. Add guide comments - 1. Arrange - 2. Act - 3. Assert -3. Implement the arrange -4. Implement the act -5. Implement the assert -6. Remove Guide comments - -This will be the last test where we dive into each of these steps in detail. - -##### Enable the test - -Each test case is defined by an `it` block. Enabling the test will cause the test to pass. However it is a false positive as this test does nothing. - -
Hints - -You did this once already in the last test. - -The `it` already exists just below the last test, all you need to do is add the arrow function expression. The description is the name of the parent section without then "It": - -> returns an object with a single count of 1 when only one item, quantity 1 was purchased - -
Code - -**Example** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => {}); -``` - -
- -
- -##### Add guide comments - -You will add the following three comments to the arrow function expression. - -```javascript -// Arrange -// Act -// Assert -``` - -> Note: these comments are often referred to as "The Triple A" comments. - -
Hints - -You will need to add two line brakes to the arrow function expression between the curly braces. - -
Code - -**Example** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - // Act - // Assert - }); -``` - -
- -
- -##### Implement the arrange - -Arrange refers to the need to do some setup before we act. - -In this test we need to create a transaction record with the transaction status of Sale, and a quantity of 1. Write the code beneath the comment. - -You will use the helper function `buildTransactionRecord` which has the following signature. - -> `buildTransactionRecord(productId, transactionStatus, quantity)` - -The `productId` is a integer number intended to identify then product. In this test it can be any valid integer, though probably should keep it positive. - -The `transactionStatus` is a integer number that represents Sale or Return. You have a helper `transactionStatuses`. In this test you will use the value `transactionStatuses.Sale`. - -The `quantity` is a positive integer number that represents the amount sold. - -
Hints - -You will create a variable and assign it to the value returned from the `buildTransactionRecord` function call. - -
Code - -**Example 1 (`let`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - let ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); - // Act - // Assert - }); -``` - -**Example 2 (`var`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - var ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); - // Act - // Assert - }); -``` - -
- -
- -##### Implement the act - -The "Act" refers to the action under test. You will need to do the thing the test is trying to test. So with this test you are trying to test what will happen when `getProductCountBySale` method on the `pointOfSaleDataUtilities` object is called with an empty that has the variable created during the arrange. - -
Hints - -You need to make a call the the `getProductCountBySale` method with an empty array and set a variable to that result. - -
Code - -**Example 1 (`let`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - let ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); - - // Act - let result = getProductCountBySale([?]); - // Assert - }); -``` - -**Example 2 (`var`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - var ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); - - // Act - var result = getProductCountBySale([?]); - // Assert - }); -``` - -
- -
- -##### Implement the assert - -Assert refers to the need to validate that the code does what we expect it to do. - -Now you need to validate that the result to the call of `getProductCountBySale` returns an object with a single count. - -The object is expected to have the following shape. - -```javascript - { - [productId]: 1 - } -``` - -The productId in this case is the value given to the first parameter of the `buildTransactionRecord` function call. - -You will use the `assert.deepEqual` method to prove this. This method has the following signature: - -```javascript -assert.deepEqual(actualResult, expectedResult) -``` - -
Hints - -You can just copy the provided object above into the assert for the expected value, and replace `productId` with the correct number. - -
Code - -**Example 1 (`let`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); - - // Act - let result = getProductCountBySale([transactionRecord]); - - // Assert - assert.deepEqual(result, { - [?]: 1 - }); - }); -``` - -**Example 2 (`var`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - // Arrange - var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); - - // Act - var result = getProductCountBySale([transactionRecord]); - - // Assert - assert.deepEqual(result, { - [?]: 1 - }); - }); -``` - -
- -
- -##### Remove Guide comments - -Now remove the comments as they serve no further purpose. - -
Hints - -Just delete them. - -
Code - -
- -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); - - let result = getProductCountBySale([transactionRecord]); - - assert.deepEqual(result, { - [?]: 1 - }); - }); -``` - -**Example 2 (`var`)** - -```javascript - it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { - var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); - - var result = getProductCountBySale([transactionRecord]); - - assert.deepEqual(result, { - [?]: 1 - }); - }); -``` - -
- -### TBD \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/_main.md b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/_main.md new file mode 100644 index 0000000..fa94d81 --- /dev/null +++ b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/_main.md @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/getProductCountByReturn.md b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/getProductCountByReturn.md new file mode 100644 index 0000000..e62ecfb --- /dev/null +++ b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/getProductCountByReturn.md @@ -0,0 +1,157 @@ + + +#### It returns with counts only for return transactions #### + +There is only one test to this section. The reason is if you look at the file [pointOfSaleDataUtilsFactory.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js) you will see that the only difference between `getProductCountBySale` and `getProductCountByReturn` is a value passed to a second parameter of a method called underneath. So in regard to returns we just need to prove that the function can count them. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +You will want to create 2 returns, and a third for a sale. + +
Hints + +In the "Arrange" you will be creating 3 different transaction reports. Two will be returns and the third will be for a sale. You can choose, if you want any of these to share IDs. + +
Code + +**Example (explicit, diff ids)** + +```javascript + it('returns with counts only for return transactions', () => { + let saleTransaction = buildTransactionRecord(?, transactionStatuses.Sale, ?); + let return1 = buildTransactionRecord(?, transactionStatuses.Return, ?); + let return2 = buildTransactionRecord(?, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [?]: ?, + [?]: ?, + }); + }); +``` + +**Example (explicit, returns share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let returnProduct = ?; + let saleTransaction = buildTransactionRecord(?, transactionStatuses.Sale, ?); + let return1 = buildTransactionRecord(returnProduct, transactionStatuses.Return, ?); + let return2 = buildTransactionRecord(returnProduct, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [returnProduct]: ?, + }); + }); +``` + +**Example (explict, all share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let productId = ?; + let saleTransaction = buildTransactionRecord(productId, transactionStatuses.Sale, ?); + let return1 = buildTransactionRecord(productId, transactionStatuses.Return, ?); + let return2 = buildTransactionRecord(productId, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [productId]: ?, + }); + }); +``` + +**Example (implicit, diff ids)** + +```javascript + it('returns with counts only for return transactions', () => { + let transactions = [ + buildTransactionRecord(?, transactionStatuses.Return, ?), + buildTransactionRecord(?, transactionStatuses.Sale, ?), + buildTransactionRecord(?, transactionStatuses.Return, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [?]: ?, + [?]: ?, + }); + }); +``` + +**Example (implicit, returns share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let returnProduct = ?; + let transactions = [ + buildTransactionRecord(returnProduct, transactionStatuses.Return, ?), + buildTransactionRecord(?, transactionStatuses.Sale, ?), + buildTransactionRecord(returnProduct, transactionStatuses.Return, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [returnProduct]: ?, + }); + }); +``` + +**Example (implicit, all share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let productId = ?; + let transactions = [ + buildTransactionRecord(productId, transactionStatuses.Return, ?), + buildTransactionRecord(productId, transactionStatuses.Sale, ?), + buildTransactionRecord(productId, transactionStatuses.Return, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [productId]: ?, + }); + }); +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/getProductCountBySale.md b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/getProductCountBySale.md new file mode 100644 index 0000000..57467c3 --- /dev/null +++ b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/getProductCountBySale.md @@ -0,0 +1,826 @@ + +You will be testing that the `getProductCountBySale` works correctly. (Don't worry it does, but you have to prove it.) + +There are a series of tests already layed out for you. We will approach each one individually. + +#### It returns an empty object for sale counts if no sale data exists #### + +This first test ensures that the `getProductCountBySale` function works properly if you give it nothing to do. So when you give it an empty array, it should return an empty object. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Act + 2. Assert +3. Implement the act +4. Implement the assert +5. Remove Guide comments + +##### Enable the test ##### + +Each test case is defined by an `it` block. The format for an it block is as follows + +```javascript + it('has a description here', testFunction); +``` + +The description is the name of the test. The test function, can be a function name, a function expression, or an arrow function expression. For this exorcise use the arrow function expression like bellow. + +```javascript + it('does some thing', () => {}); +``` + +This step will cause the test to pass. However it is a false positive as this test does nothing. + +
Hints + +The `it` already exists on line 51, all you need to do is add the arrow function expression. The description is the name of the parent section without then "It": + +> returns an empty object for sale counts if no sale data exists + +
Code + +**Example** + +```javascript + it('returns an empty object for sale counts if no sale data exists', () => {}); +``` + +
+ +
+ +##### Add Guiding Comments ##### + +To the arrow function expression, you will add the following comments + +```javascript +// Act +// Assert +``` + +These represent the logical steps of testing such a simple thing. We will then use the comments to implement the test. + +
Hints + +You will need to add two line brakes to the arrow function expression between the curly braces. + +
Code + +**Example** + +```javascript + it('returns an empty object for sale counts if no sale data exists', () => { + // Act + // Assert + }); +``` + +
+ +
+ +##### Implement the Act ##### + +The "Act" refers to the action under test. You will need to do the thing the test is trying to test. So with this test you are trying to test what will happen when `getProductCountBySale` method on the `pointOfSaleDataUtilities` object is called with an empty array. + +
Hints + +You need to make a call the the `getProductCountBySale` method with an empty array and set a variable to that result. + +
Code + +**Example** + +```javascript + it('returns an empty object for sale counts if no sale data exists', () => { + // Act + let result = pointOfSaleDataUtilities.getProductCountBySale([]); + // Assert + }); +``` + +
+ +
+ +##### Implement the Assert ##### + +Assert refers to the need to validate that the code does what we expect it to do. It often uses a keyword `assert`. For our tests they will. + +Now you need to validate that the result to the call of `getProductCountBySale` returns an empty object. + +> Note: an empty object in JavaScript is an object with no properties or methods. i.e `{}` + +You will use the `assert.deepEqual` method to prove this. This method has the following signature: + +```javascript +assert.deepEqual(actualResult, expectedResult) +``` + +
Hints + +The expected result is `{}`. + +
Code + +**Example** + +```javascript + it('returns an empty object for sale counts if no sale data exists', () => { + // Act + let ? = pointOfSaleDataUtilities.getProductCountBySale([]); + // Assert + assert.deepEqual(?, {}); + }); +``` + +
+ +
+ +##### Remove guide comments ##### + +Now delete then comments as they provide no extra value. + +
Hints + +Delete the comment lines + +
Code + +**Example 1 (`let`)** + +```javascript + it('returns an empty object for sale counts if no sale data exists', () => { + let ? = pointOfSaleDataUtilities.getProductCountBySale([]); + + assert.deepEqual(?, {}); + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an empty object for sale counts if no sale data exists', () => { + var ? = pointOfSaleDataUtilities.getProductCountBySale([]); + + assert.deepEqual(?, {}); + }); +``` + +
+ +
+ +#### It returns an object with a single count of 1 when only one item, quantity 1 was purchased #### + +The next test is to test what happens when a only one item is passed to the `getProductCountBySale` method and it is a sale with only one item sold of that product. + +It will then return an item with a property equal to the product ID with an integer value equal to that item's quantity. So if `productId: 42` was passed you should get an item that looks like: + +```javascript +{ + [42]: 1 +} +``` + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +This will be the last test where we dive into each of these steps in detail. + +##### Enable the test test 2 ##### + +Each test case is defined by an `it` block. Enabling the test will cause the test to pass. However it is a false positive as this test does nothing. + +
Hints + +You did this once already in the last test. + +The `it` already exists just below the last test, all you need to do is add the arrow function expression. The description is the name of the parent section without then "It": + +> returns an object with a single count of 1 when only one item, quantity 1 was purchased + +
Code + +**Example** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => {}); +``` + +
+ +
+ +##### Add guide comments test 2 ##### + +You will add the following three comments to the arrow function expression. + +```javascript +// Arrange +// Act +// Assert +``` + +> Note: these comments are often referred to as "The Triple A" comments. + +
Hints + +You will need to add two line brakes to the arrow function expression between the curly braces. + +
Code + +**Example** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + // Act + // Assert + }); +``` + +
+ +
+ +##### Implement the Arrange test 2 ##### + +Arrange refers to the need to do some setup before we act. + +In this test we need to create a transaction record with the transaction status of Sale, and a quantity of 1. Write the code beneath the comment. + +You will use the helper function `buildTransactionRecord` which has the following signature. + +> `buildTransactionRecord(productId, transactionStatus, quantity)` + +The `productId` is a integer number intended to identify then product. In this test it can be any valid integer, though probably should keep it positive. + +The `transactionStatus` is a integer number that represents Sale or Return. You have a helper `transactionStatuses`. In this test you will use the value `transactionStatuses.Sale`. + +The `quantity` is a positive integer number that represents the amount sold. + +
Hints + +You will create a variable and assign it to the value returned from the `buildTransactionRecord` function call. + +
Code + +**Example 1 (`let`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + let ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); + // Act + // Assert + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + var ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); + // Act + // Assert + }); +``` + +
+ +
+ +##### Implement the Act test 2 ##### + +The "Act" refers to the action under test. You will need to do the thing the test is trying to test. So with this test you are trying to test what will happen when `getProductCountBySale` method on the `pointOfSaleDataUtilities` object is called with an empty that has the variable created during the arrange. + +
Hints + +You need to make a call the the `getProductCountBySale` method with an empty array and set a variable to that result. + +
Code + +**Example 1 (`let`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + let ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + // Act + let result = pointOfSaleDataUtilities.getProductCountBySale([?]); + // Assert + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + var ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + // Act + var result = pointOfSaleDataUtilities.getProductCountBySale([?]); + // Assert + }); +``` + +
+ +
+ +##### Implement the Assert test 2 ##### + +Assert refers to the need to validate that the code does what we expect it to do. + +Now you need to validate that the result to the call of `getProductCountBySale` returns an object with a single count. + +The object is expected to have the following shape. + +```javascript + { + [productId]: 1 + } +``` + +The productId in this case is the value given to the first parameter of the `buildTransactionRecord` function call. + +You will use the `assert.deepEqual` method to prove this. This method has the following signature: + +```javascript +assert.deepEqual(actualResult, expectedResult) +``` + +
Hints + +You can just copy the provided object above into the assert for the expected value, and replace `productId` with the correct number. + +
Code + +**Example 1 (`let`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + // Act + let result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + // Assert + assert.deepEqual(result, { + [?]: 1 + }); + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + // Arrange + var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + // Act + var result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + // Assert + assert.deepEqual(result, { + [?]: 1 + }); + }); +``` + +
+ +
+ +##### Remove Guide comments ##### + +Now remove the comments as they serve no further purpose. + +
Hints + +Just delete them. + +
Code + +
+ +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + let result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 1 + }); + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { + var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + var result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 1 + }); + }); +``` + +
+ +#### It returns an object with a single count of 2 when only one item, quantity 2 was purchased #### + +The intent of this test is to verify that the `quantity` field of the transaction record is actually used. By writing almost the same test, but differing only in quantity, you can verify that the `quantity` is used in the result. + +So now you will create a test that looks very similar to the previous one but will use a quantity of 2. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +However, then only steps this guide will cover for this test are the "Implement" step 3, and then the rest of the code. + +##### Implement the Arrange test 3 ##### + +After enabling the tests and writing the guide comments, you need to use the `buildTransactionRecord` function just like above. The only difference is the last parameter will be a `2` instead of a `1`. + +
Hints + +Remember then signature for the `buildTransactionRecord` is `buildTransactionRecord(productId, transactionStatus, quantity)`. + +You will simply capture the result as a variable. + +
Code + +**Example 1 (`let`)** + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + // Arrange + let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + // Act + // Assert + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + // Arrange + var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + // Act + // Assert + }); +``` + +
+ +
+ +##### Finish the Test ##### + +Now you have done the rest before. Fill in the "Act", the "Assert" and then delete the comments. Remember that you are verifying the value of the result object is `2`. + +
Hints + +The last two lines of this test should look almost exactly like the test above except with a `2` instead of a 1 for the object value. + +
Code + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + let result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 2 + }); + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + var result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 2 + }); + }); +``` + +
+ +
+ +#### It returns an object with a two counts of 1 when two transactions of 1 qty each are passed #### + +Now you will be seeing what happens when you pass 2 different transaction records to the `getProductCountBySale` each one with a different product IDs. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +From this point on we will not cover any of the individual steps, but focus on the outcome of following those steps. Also for simplicity, this guide will only show examples for `let` variable statements as they are slightly more dependable. + +What you are going to want to do, is to modify the the test such that you create 2 different transactions records using the `buildTransactionRecord` function. + +> Make sure these have different product IDs. + +So given: + +Product ID 314 +and +Product ID 42 + +then the result should look like: + +```javascript +{ + [314]: 1 + [42]: 1 +} +``` + +
Hints + +All three parts of the test that change. In the "Arrange" you will want to create the two transactions records. + +In the "Act" you will pass both of the transaction records to the `getProductCountBySale` method. + +In the "Assert" you want to ensure the resulting object has those record quantities. + +
Code + +**Example 1 (explicit variables)** + +```javascript + it('returns an object with a two counts of 1 when two transactions of 1 qty each are passed', () => { + let transactionP1 = buildTransactionRecord(?, transactionStatuses.Sale, 1); + let transactionP2 = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + transactionP1, + transactionP2 + ]); + + assert.deepEqual(result, { + [?]: 1 + [?]: 1 + }); + }); +``` + +**Example 2 (implicit variables)** + +```javascript + it('returns an object with a two counts of 1 when two transactions of 1 qty each are passed', () => { + let transactions = [ + buildTransactionRecord(?, transactionStatuses.Sale, 1) + buildTransactionRecord(?, transactionStatuses.Sale, 1) + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [?]: 1 + [?]: 1 + }); + }); +``` + +
+ +
+ +#### It returns an object with a two counts when 4 transactions of two different items are passed #### + +The intent of this test is to see if the `getProductCountBySale` method will sum quantities across two different products. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +You will need to create 2 different products, each with two transaction records. The test does not specify what the quantities are, so you will have to determine that. + +> **NOTE:** Make sure that the totals of the quantities across both products are different, or else you do not know if the function is summing one and duplicating it. + +> **GUIDE:** It would be helpful to create a variable that holds each product ID as you will need that in at least three different places. Also this variable will help make your code more readable. + +
Hints + +Again all the portions of the test have changed. + +In the "Arrange" you will need to create four different transaction records across two different product IDs. You will need to ensure that the totals of the `quantities` across the products are different. + +In the "Act", you will be passing all four transaction records to the `getProductCountBySale` method. + +In the "Assert" you will verify that then resulting object has only the two product IDs passed and it has the correct summation of their quantities. + +
Code + +**Example 1 (explicit variables)** + +```javascript + it('returns an object with a two counts when 4 transactions of two different items are passed', () => { + let product1 = ?; // ID for product 1 + let product2 = ?; // ID for product 2 + + let transaction1A = buildTransactionRecord(product1, transactionStatuses.Sale, ?); + let transaction1B = buildTransactionRecord(product1, transactionStatuses.Sale, ?); + let transaction2A = buildTransactionRecord(product2, transactionStatuses.Sale, ?); + let transaction2B = buildTransactionRecord(product2, transactionStatuses.Sale, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + transaction1A, + transaction2A, + transaction1B, + transaction2B + ]); + + expect.deepEqual(result, { + [product1]: ? + [product2]: ? + }); + }); +``` + +**Example 1 (implicit variables)** + +```javascript + it('returns an object with a two counts when 4 transactions of two different items are passed', () => { + let product1 = ?; // ID for product 1 + let product2 = ?; // ID for product 2 + + let transactions = [ + buildTransactionRecord(product1, transactionStatuses.Sale, ?), + buildTransactionRecord(product2, transactionStatuses.Sale, ?), + buildTransactionRecord(product1, transactionStatuses.Sale, ?), + buildTransactionRecord(product2, transactionStatuses.Sale, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + expect.deepEqual(result, { + [product1]: ? + [product2]: ? + }); + }); +``` + +
+ +
+ +#### It returns counts only for sales, ignoring returns #### + +The last test of the `getProductCountBySale` method is to ensure that it does not count returns. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +You will need at least 2 transaction records. One that is a Sale and one that is a Return, they can have the same product ID or different ones. + +You will need to use `transactionStatuses.Return` to set the type for the return transaction. + +
Hints + +In the "Arrange" you will need to create both a Sale and a Return. + +
Code + +**Example 1 (explicit, diff IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let saleTransaction = buildTransactionRecord(?, transactionStatuses.Sale, ?); + let returnTransaction = buildTransactionRecord(?, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([returnTransaction, saleTransaction]); + + assert.deepEqual(result, { + [?]: ? + }); + }); +``` + +**Example 2 (explicit, same IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let productId = ?; + let saleTransaction = buildTransactionRecord(productId, transactionStatuses.Sale, ?); + let returnTransaction = buildTransactionRecord(productId, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([returnTransaction, saleTransaction]); + + assert.deepEqual(result, { + [productId]: ? + }); + }); +``` + +**Example 3 (implicit, diff IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let transactions = [ + buildTransactionRecord(?, transactionStatuses.Return, ?), + buildTransactionRecord(?, transactionStatuses.Sale, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [?]: ? + }); + }); +``` + +**Example 4 (implicit, same IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let productId = ?; + let transactions = [ + buildTransactionRecord(productId, transactionStatuses.Return, ?), + buildTransactionRecord(productId, transactionStatuses.Sale, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale([returnTransaction, saleTransaction]); + + assert.deepEqual(result, { + [productId]: ? + }); + }); +``` + +
+ +
\ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/importantFiles.md b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/importantFiles.md new file mode 100644 index 0000000..c88827c --- /dev/null +++ b/docs-source/forms-source/form4-doc/pointOfSaleDataUtils/importantFiles.md @@ -0,0 +1,17 @@ + + +Test File: + +> test/[4_test-dummy-form.test.js](../test/4_test-dummy-form.test.js) + +File Under Test: + +> jsforms-source/4_test-dummy-form/pos-transaction-services/[pointOfSaleDataUtilsFactory.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js) + +Helpers File: + +> test/form-helpers/[4_test-dummy-helpers.js](../test/form-helpers/4_test-dummy-helpers.js) \ No newline at end of file diff --git a/docs-source/forms-source/form4-doc/why.md b/docs-source/forms-source/form4-doc/why/_main.md similarity index 100% rename from docs-source/forms-source/form4-doc/why.md rename to docs-source/forms-source/form4-doc/why/_main.md diff --git a/docs-source/forms-source/form4-doc/why1.md b/docs-source/forms-source/form4-doc/why/why1.md similarity index 100% rename from docs-source/forms-source/form4-doc/why1.md rename to docs-source/forms-source/form4-doc/why/why1.md diff --git a/docs-source/forms-source/form4-doc/why2.md b/docs-source/forms-source/form4-doc/why/why2.md similarity index 84% rename from docs-source/forms-source/form4-doc/why2.md rename to docs-source/forms-source/form4-doc/why/why2.md index ebe2390..23dddfc 100644 --- a/docs-source/forms-source/form4-doc/why2.md +++ b/docs-source/forms-source/form4-doc/why/why2.md @@ -4,4 +4,4 @@ ) /bl--> -The biggest reason to test a known working code base is to ensure that it stays working. You will see by testing this code base that coming into a code base you do not understand and gaining that understanding is hard work. Having tests around that code ensures that someone unfamiliar with, or has been away to long from, the code base does not accidently break existing functionality. \ No newline at end of file +The biggest reason to test a known working code base is to ensure that it stays working. You will see by testing this code base that coming into a code base you do not understand and gaining that understanding is hard work. Having tests around that code ensures that someone unfamiliar with, or has been away to long from, the code base does not accidentally break existing functionality. \ No newline at end of file diff --git a/docs-source/forms-source/forms.md b/docs-source/forms-source/forms.md index da22a5d..779940e 100644 --- a/docs-source/forms-source/forms.md +++ b/docs-source/forms-source/forms.md @@ -7,4 +7,6 @@ 1. [First Form](./docs/FIRST-FORM.md) 2. [Second Form](./docs/SECOND-FORM.md) 3. [Third Form](./docs/THIRD-FORM.md) -3. [Test Dummy Form](./docs/TEST-DUMMY-FORM.md) +4. [Test Dummy Form](./docs/TEST-DUMMY-FORM.md) +5. Async Form _TBD_ +6. Async Test Dummy Form _TBD_ \ No newline at end of file diff --git a/docs-source/readme-source/main-sections/subsections/using-jsl/solving-each-form.md b/docs-source/readme-source/main-sections/subsections/using-jsl/solving-each-form.md index 24bde24..1555b08 100644 --- a/docs-source/readme-source/main-sections/subsections/using-jsl/solving-each-form.md +++ b/docs-source/readme-source/main-sections/subsections/using-jsl/solving-each-form.md @@ -3,15 +3,15 @@ (title "Solving Each Form") ) /bl--> -1. [Documentation For all Forms](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/FORMS.md) +1. [Documentation For all Forms](https://github.com/cmstead/jsLearnerForms/blob/documentation/FORMS.md) 2. First Form -- Write code to pass each test - 1. [First Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/FIRST-FORM.md) + 1. [First Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/FIRST-FORM.md) 3. Second Form -- Update code to pass new tests, keep old tests green - 1. [Second Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/SECOND-FORM.md) + 1. [Second Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/SECOND-FORM.md) 4. Third Form -- Update code to pass new tests, keep tests old green - 1. [Third Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/THIRD-FORM.md) + 1. [Third Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/THIRD-FORM.md) 5. Test Dummy Form (Fourth Form) -- Write tests matching each description and get all of the code under test (modify ONLY the test code) - 1. [Test Dummy Form Documentation](https://github.com/jason-kerney/jsLearnerForms/blob/documentation/docs/TEST-DUMMY-FORM.md) **Incomplete** + 1. [Test Dummy Form Documentation](https://github.com/cmstead/jsLearnerForms/blob/documentation/docs/TEST-DUMMY-FORM.md) 6. Async Form -- Write code to pass each test; don't forget the refactoring steps! 1. Documentation TBD 7. Async Test Dummy Form (Sixth Form) -- Write tests matching each description and get all of the code under test (modify ONLY the test code) diff --git a/docs-source/readme-source/main-sections/thanks.md b/docs-source/readme-source/main-sections/thanks.md index c0b1424..daa8398 100644 --- a/docs-source/readme-source/main-sections/thanks.md +++ b/docs-source/readme-source/main-sections/thanks.md @@ -15,6 +15,8 @@ hunterinderstries
hunterinderstries

💵 EDF Renewables
EDF Renewables

💵 Jason Kerney
Jason Kerney

💻 📖 + Michał Urbanek
Michał Urbanek

🐛 + Willem Larsen
Willem Larsen

📖 diff --git a/docs/FIRST-FORM.md b/docs/FIRST-FORM.md index b090956..c1159bb 100644 --- a/docs/FIRST-FORM.md +++ b/docs/FIRST-FORM.md @@ -7,26 +7,26 @@ You can also look at [JS Learner Forms documentation](../FORMS.md) for other for You will be working in then [jsforms-source/1_first-form.js](..\jsforms-source\1_first-form.js) file. - ## Table Of Contents ## - [Section 1: Variables and Operations](#user-content-variables-and-operations) -- [Section 2: Function Creation](#user-content-function-creation) +- [Section 2: Function Creation, Function Declaration, and the Return Statement](#user-content-function-creation,-function-declaration,-and-the-return-statement) - [Section 3: Arrays, Loops, and Function Calls](#user-content-arrays,-loops,-and-function-calls) - [Section 4: Combining Complex Functions](#user-content-combining-complex-functions) -- [Section 5: Copying Arrays](#user-content-copying-arrays) +- [Section 5: Copying Arrays Using `Array.slice`](#user-content-copying-arrays-using-`array.slice`) - [Section 6: Combining existing code to solve new problems](#user-content-combining-existing-code-to-solve-new-problems) - [Section 7: Looping and inequality comparison](#user-content-looping-and-inequality-comparison) - [Section 8: The Other JS Learner Forms](#user-content-the-other-js-learner-forms) ## Variables and Operations ## + You will explore the creation and use of variables. -### declaration and initialization +### Declaration and Initialization ### Here you will declare and initialize variables. -#### It should have a variable called "a" +#### It should have a variable called `a` #### Create a variable at the top of the block called "a". You will need to use `let` or `var`. @@ -64,7 +64,7 @@ const jsforms = (function () { -#### It should initialize "a" with the value 5 +#### It should initialize `a` with the value 5 #### Set the initial value of a to 5. @@ -101,12 +101,13 @@ const jsforms = (function () { + -### assignment and operators +### Assignment and Operators ### Now that you have a variable you will assign it a value different then what it was initialized with. -#### It should assign the sum of 3 and 7 (3 + 7) to "a" +#### It should assign the sum of 3 and 7 (3 + 7) to `a` #### Now assign variable `a` with the value of `3 + 7`. @@ -140,9 +141,9 @@ Add two numbers using the plus (+) operator -#### It should have a variable "b" initialized to "Hello, World!" +#### It should have a variable `b` initialized to `Hello, World!` #### -Create a variable called `b` and initialize it with the value `"Hello, World!" +Create a variable called `b` and initialize it with the value `"Hello, World!"`
Hints @@ -171,12 +172,12 @@ Initialize a variable with equals: `var b = ...`
+ -### method call - -YOu will make a call to a method on an object. +### Method Call ### +You will make a call to a method on an object. -#### It should log variable "b" to the console +#### It should log variable `b` to the console #### Use the `console.log` method to log the value contained in variable `b` to the console. @@ -207,12 +208,13 @@ Console.log might be just the ticket... + -### exposing values +### Exposing Values ### You well now expose values to the outside world. -#### It should expose variable "b" to be read outside of the module +#### It should expose variable `b` to be read outside of the module #### Expose the variable `b` to the outside world, by adding it the the object being exported. @@ -234,14 +236,15 @@ Find `return {};` add a "b" -> `return {b};` + + +## Function Creation, Function Declaration, and the Return Statement ## -## Function Creation ## -#### [function declaration, return statement] #### Time to create functions and have them return a value. -### \*\*greeter function\*\* +### Greeter Function ### -##### It should say "Hello!" by default +#### It should say `"Hello!"` by default #### Write a function called `greet` that returns the value "Hello!". (note: don't forget the "!") @@ -267,9 +270,9 @@ Functions start with the keyword `function` followed by the name of the function -#### conditional logic [if/else] +#### Conditional Logic [If / Else] #### -##### It should say "Salutations!" when Salutations is passed +##### It should say `"Salutations!"` when salutations is passed ##### Modify the greet function to take a greeting and return the greeting if it was passed. @@ -299,14 +302,15 @@ Add condition to greet to handle custom greeting case. + -### function calls and mathematical operations [Math library] +### Function Calls and Mathematical Operations [Math Library] ### -#### \*\*square function\*\* +#### Square Function #### Create a function that takes a number and returns its square. -##### It should square 1 +##### It should square 1 ##### The function called `square` will be passed 1 and should return 1. @@ -332,7 +336,7 @@ Add square function that returns a simple value rather then worrying about actua -##### It should square 3 +##### It should square 3 ##### Modify the `square` function such that it returns the square of the value passed in. @@ -372,11 +376,11 @@ Modify the `square` function such that it returns the square of the value passed -#### \*\*squareRoot function\*\* +#### Square Root Function #### Create a function that takes a number and returns the square root of that number. (note: use the Math library). -##### It should take the square root of 1 +##### It should take the square root of 1 ##### Create a function called `squareRoot` that will be passed 1 and return 1. @@ -402,7 +406,7 @@ Create a function that returns a simple value rather then worrying about actuall -##### It should take the square root of 4 +##### It should take the square root of 4 ##### Modify the `squareRoot` function to return the square root of the value passed. @@ -429,15 +433,17 @@ Add logic to properly take square root + ## Arrays, Loops, and Function Calls ## + You will use functions to work with arrays and loops. -### \*\*sum function\*\* +### Sum Function ### You are going to create a function called `sum` that adds numbers together. -#### It should take the sum of one number +#### It should take the sum of one number #### Create a `sum` function that accepts an array and returns 1. @@ -463,7 +469,7 @@ Create a function that returns a simple number instead of worrying about actuall -#### It should add two numbers +#### It should add two numbers #### Modify the `sum` function so that it adds the first two numbers in an array. @@ -493,7 +499,7 @@ Add logic to sum 1 or two numbers (An `if` structure might help here) -#### It should add multiple numbers +#### It should add multiple numbers #### Modify the `sum` function to add all numbers in an array. @@ -542,8 +548,9 @@ Add logic to sum an arbitrary length array of numbers (A for loop might help to + -### \*\*squareAll function\*\* +### Square All Function ### Create a function that squares each number in an array. @@ -552,7 +559,7 @@ The steps you will take to building the `squareAll` function are: 1. Add a `squareAll` function that returns a constant value. 2. Chang the `squareAll` function to perform square computation on array value -#### It should square all numbers in a single-value array +#### It should square all numbers in a single-value array #### Create a function called `squareAll` that takes an array and returns the square of the first element. @@ -579,7 +586,7 @@ Create a function that only squares the first value of an array and returns that -#### It should square multiple numbers +#### It should square multiple numbers #### Modify the `squareAll` function so that it now squares each number in the array. @@ -609,15 +616,17 @@ Add logic to square all numbers in array (How did you solve sum?) + ## Combining Complex Functions ## + You will use previous functions chained to gether to give us new results. -### \*\*sumOfSquares function\*\* +### Sum Of Squares Function ### Create a function that takes an array of numbers, squares each number and then returns the sum of those squares. -#### It should square number in a 1-length array and return it +#### It should square number in a 1-length array and return it #### Create a function called `sumOfSquares` that takes an array and returns the square of the first element. @@ -646,7 +655,7 @@ Try to do the following: -#### It should take the sum of squares of multiple numbers +#### It should take the sum of squares of multiple numbers #### Modify the `sumOfSquares` function so that it squares all numbers in the array. @@ -671,20 +680,20 @@ Add logic to square all numbers and return the sum (squareAll and sum might be u - + + +## Copying Arrays Using `Array.slice` ## -## Copying Arrays ## -#### Using Array.slice #### You are going to use functions to explore the `Array.prototype.slice` method. -### \*\*buildVector function\*\* +### Build Vector Function ### You will now create a function called `buildVector` that returns a copy of the array as it was passed. > A vector is an ordered set of points which describes a "directed line segment," in other words, a vector is a line segment with an arrow -#### It returns a vector (array) containing the same numbers as the original -- try returning the array you get in your function +#### It returns a vector (array) containing the same numbers as the original -- try returning the array you get in your function #### Create a function called `buildVector` that returns the same array passed to it. @@ -710,7 +719,7 @@ Add buildVector function (Would it be possible to just return something?) -#### It returns a copy of the original vector +#### It returns a copy of the original vector #### Modify the `buildVector` function so that it returns a copy of the array passed to it. (note: use the `slice` method on array.) @@ -736,13 +745,14 @@ Add logic to return a copy of vector array (Slice will create a new array just l - + ## Combining existing code to solve new problems ## + You will now take code you wrote and use it define more complex behaviors -### \*\*magnitude function\*\* +### Magnitude Function ### You will create a function called `magnitude` that will calculate the magnitude of all given numbers. @@ -774,7 +784,7 @@ or > > d = 3 -#### It returns the magnitude of a vector with only one number +#### It returns the magnitude of a vector with only one number #### Create a function called `magnitude` that returns the first item in an array that is given to it. @@ -800,7 +810,7 @@ Can you just return a value from the array? -#### It returns only positive numbers -- all magnitudes are positive +#### It returns only positive numbers -- all magnitudes are positive #### Modify the `magnitude` function that returns the positive value of the first item in an array that is given to it. @@ -833,7 +843,7 @@ Currently the magnitude of a vector is computed by: -#### It should return the magnitude of a vector with two values +#### It should return the magnitude of a vector with two values #### Modify the `magnitude` function so that it returns the magnitude of the first 2 items in an array given to it. @@ -871,7 +881,7 @@ Currently the magnitude of a vector is computed by: -#### It should return the magnitude of a vector with multiple values +#### It should return the magnitude of a vector with multiple values #### Modify the `magnitude` function so that it returns the magnitude of all the values in the array. @@ -904,13 +914,14 @@ The magnitude of a vector is computed by: - + ## Looping and inequality comparison ## + Now it is time to use functions to examine looping and comparisons. -### \*\*getVectorsShorterThan\*\* +### Get Vectors Shorter Than ### You will now create a function called `getVectorsShorterThan` that will take an array of arrays. It will compare each array based on its magnitude and return all arrays that have a magnitude smaller then the number provided. @@ -922,7 +933,7 @@ getVectorsShorterThan(length, arrayOfVectors) Such that `length` is the number for which You will compare magnitudes against, and `arrayOfVectors` is the array of arrays, where then inner arrays are to contain numbers. -#### It returns an array of one vector when the vector is shorter than 5 -- arguments are: length, arrayOfVectors +#### It returns an array of one vector when the vector is shorter than 5 #### Create a the function `getVectorsShorterThan` where the first parameter is `length` and the second parameter is `arrayOfVectors` that returns all vectors where the magnitude is less then 5. There is only one vector at this point and its length is less then 5. @@ -948,7 +959,7 @@ Can you just return the first value of the array? -#### It returns an empty array when all vectors are too long -- tests one vector +#### It returns an empty array when all vectors are too long -- tests one vector #### Modify the `getVectorsShorterThan` function so that it will return an empty array if the first vector has a magnitude longer then `length`. @@ -998,7 +1009,7 @@ Add logic to handle the case where a vector is too long (How might you compare t -#### It returns an array of more than one vector when all are short enough +#### It returns an array of more than one vector when all are short enough #### Modify the `getVectorsShorterThan` function so that it returns all vectors if the first one has a magnitude less then the length. @@ -1048,7 +1059,7 @@ Add logic to handle 0, 1 or 2 vector cases -### It returns only vectors which are not too long +#### It returns only vectors which are not too long ### Modify the `getVectorsShorterThan` function so that it now returns only those vectors with a magnitude less then the length. @@ -1104,6 +1115,7 @@ Move to general code for filtering vecctors (Is there a way you can use a known + ## The Other JS Learner Forms ## diff --git a/docs/SECOND-FORM.md b/docs/SECOND-FORM.md index 9675b41..1f71049 100644 --- a/docs/SECOND-FORM.md +++ b/docs/SECOND-FORM.md @@ -20,13 +20,14 @@ You will be working in the [jsforms-source/2_second-form.js](../jsforms-source/2 - [Section 6: The Other JS Learner Forms](#user-content-the-other-js-learner-forms) ## Greeter ## + Let us change the `greet` function. -### Refactoring steps +### Refactoring steps ### Lets look at the steps in refactoring the `greet` function. -#### It is refactored to remove the unnecessary else +#### It is refactored to remove the unnecessary else #### Modify the `greet` function to remove the else statement. @@ -52,7 +53,7 @@ Because of the `return greeting + '!';` in the first part of the `if` statement -#### It is refactored to remove if and replace with a ternary expression +#### It is refactored to remove if and replace with a ternary expression #### Because both paths of the function return a value, you can change the shape of the code from an `if` `return` to a [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator). @@ -78,7 +79,7 @@ A ternary operator has the following form -#### It is refactored to use typeof comparison to "string" +#### It is refactored to use `typeof` comparison to `string` #### You will now modify the `greet` function to remove the `greeting === undefined` comparison and instead use the [typeof](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) operator to prove whether or not what was passed in was a string. @@ -99,17 +100,17 @@ The `typeof` operator returns a string with the name of the type. Maybe you can - ## Sum ## + You are going to refactor and change the shape of the `sum` method. -### Refactoring steps +### Refactoring steps ### These are the steps you will use to change the shape of the `sum` method, thereby changing how it does its work, while not changing the work it does. -#### It has an add function +#### It has an add function #### Now create a function called `add` that takes two number and adds them. You are _not_ exporting this function, it is part of your refactoring of the `sum` function. @@ -129,7 +130,7 @@ Return the values after using the `+` operator. -#### It is refactored to replace += with a call to the add function +#### It is refactored to replace += with a call to the add function #### Modify the `sum` method to use the new `add` method above instead of the `+=` operator. @@ -157,7 +158,7 @@ The `+=` operator is equivalent to setting a value to itself plus the other valu -#### It is refactored to replace for loop with `nums.forEach` +#### It is refactored to replace for loop with `nums.forEach` #### Now modify the `sum` method to remove the `for` loop, and use the [`Array.prototype.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) method provided on nums. @@ -183,7 +184,7 @@ Now modify the `sum` method to remove the `for` loop, and use the [`Array.protot -#### It is refactored to replace the function expression with an arrow function +#### It is refactored to replace the function expression with an arrow function #### Now modify the `sum` function to replace the function expression with an [arrow function expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). @@ -209,13 +210,14 @@ An arrow function expression to log a value to the console looks like `value => ## Square All ## + You will now refactor and change the shape of the `squareAll` method. -### Refactoring steps +### Refactoring steps ### These are the steps you will take in changing the shape of the `squareAll` method, to ensure you do not change its behavior. -#### It is refactored to replace for loop with `nums.map` +#### It is refactored to replace for loop with `nums.map` #### The [`Array.prototype.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) function allows you to perform a function on each member of an array and capture the result. Use this method instead of the given for loop. @@ -247,7 +249,7 @@ The `Array.prototype.map` allows you to transform all values in an array such th -#### It is refactored to remove function wrapping `square` +#### It is refactored to remove function wrapping `square` #### Now modify the `squareAll` function to simplify the function expression or the arrow function expression. @@ -270,7 +272,7 @@ If you were to log all items in an array to the console, you don't need a functi -#### It is refactored to return result of map operation without assigning output to result +#### It is refactored to return result of map operation without assigning output to result #### Now modify the `squareAll` function to remove the unnecessary `result` variable. @@ -292,13 +294,14 @@ Instead of an assignment, maybe just return the result of map. ## Build Vector ## + Now you will refactor the `buildVector` function changing its shape. -### Refactoring steps +### Refactoring steps ### These are the steps you will use to change the shape of the `buildVector` function without changing its behavior. -#### It has a refactoring in magnitude function to replace vector value with `vector.valueOf()` +#### It has a refactoring in magnitude function to replace vector value with `vector.valueOf()` #### Now modify the `magnitude` function by not passing the vector directly but passing the result of the `valueOf` method on vector. Currently the `valueOf` function just returns the original array. However this will make space for later changes that will happen to the `buildVector` function. @@ -321,7 +324,7 @@ Just add a `.valueOf()` call after the vector in the call to `sumOfSquares`. -#### It contains a constructor for an object called Vector +#### It contains a constructor for an object called Vector #### Now you will create a constructor for an object called `Vector`. You are not yet exporting that constructor. This constructor can just be an empty function. @@ -342,7 +345,7 @@ You will not be using JavaScripts class objects. Instead work from the original -#### It accepts a parameter "points" into Vector constructor +#### It accepts a parameter `points` into Vector constructor #### Modify the `Vector` function to take a parameter called points. There is no need to do anything with this parameter yet. @@ -363,7 +366,7 @@ The `Vector` constructor is just a function. All functions can have a name repre -#### It assigns `points` variable to "this.points" in `Vector` constructor +#### It assigns `points` variable to `this.points` in `Vector` constructor #### Modify the `Vector` constructor to save the `points` parameter. @@ -385,7 +388,7 @@ Remember in JavaScript, you do not have to predefine member variables before you -#### It overrides the valueOf function on the Vector prototype +#### It overrides the `valueOf` function on the Vector prototype #### Now you will need to override the internal `valueOf` function on `Vector`. Remember that `valueOf` comes from object and by default just returns the object. You will now change the behavior of this function to return a copy of its internal points. @@ -407,7 +410,7 @@ The way to override an internal function in JavaScript without the use of the `c -#### It overrides the `toString` function on the `Vector` prototype +#### It overrides the `toString` function on the `Vector` prototype #### Now you will need to override the internal `toString` function on `Vector`. Remember what you learned above. @@ -428,7 +431,7 @@ The way to override an internal function in JavaScript without the use of the `c -#### It should return a vector where toString returns a vector string +#### It should return a vector where `toString` returns a vector string #### You will modify the overridden `toString` method on `Vector` such that: @@ -476,7 +479,7 @@ You can use the [`Array.prototype.forEach`](https://developer.mozilla.org/en-US/ -#### It returns a new Vector object instead of an array +#### It returns a new Vector object instead of an array #### You will now modify the `buildVector` function to return a new `Vector` instead of an array of values. @@ -503,7 +506,7 @@ Remember to use the `new` keyword in your return value. You will now modify the `getVectorsShorterThan` function changing its shape without changing its behavior. -### Refactoring steps +### Refactoring steps ### This is how you will modify the `getVectorsShorterThan` function such that it ensures you do not change its external behavior. @@ -513,7 +516,7 @@ This is how you will modify the `getVectorsShorterThan` function such that it en _**KEEP THE TESTS PASSING!**_ -#### It has a function called `isMagnitudeShorterThanLength` +#### It has a function called `isMagnitudeShorterThanLength` #### Create a function called `isMagnitudeShorterThanLength`. This can be an empty function right now. You are also _not_ exporting that function. @@ -534,7 +537,7 @@ Create a function that calculates the magnitude and then just return the value o -#### It has `vector` and `length` as parameters of `isMagnitudeShorterThanLength` +#### It has `vector` and `length` as parameters of `isMagnitudeShorterThanLength` #### You will modify the `isMagnitudeShorterThanLength` function to take the two parameters `vector` and `length`. You will also modify the function to return a [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) `true` if the vector's magnitude is less then the provided length and false if it is equal to or greater. @@ -557,7 +560,7 @@ You will need to calculate the magnitude (there is a function to help with this) -#### It is refactored to use `vectors.filter()` instead of for loop +#### It is refactored to use `vectors.filter()` instead of for loop #### You will modify the `getVectorsShorterThan` function to use the internal [`Array.prototype.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) instead of recreating the functionality in a for loop. @@ -581,7 +584,7 @@ The filter method takes a function as a parameter that returns a Boolean. If th -#### It does not assign filter to results, it just returns directly +#### It does not assign filter to results, it just returns directly #### Now modify the `getVectorsShorterThan` not to use the unnecessary variable `result`. diff --git a/docs/TEST-DUMMY-FORM.md b/docs/TEST-DUMMY-FORM.md index 56198ca..0bae488 100644 --- a/docs/TEST-DUMMY-FORM.md +++ b/docs/TEST-DUMMY-FORM.md @@ -16,6 +16,7 @@ You will be working in the [test/4_test-dummy-form.test.js](../test/4_test-dummy - [Section 2: A word about hints](#user-content-a-word-about-hints) - [Section 3: The application under test](#user-content-the-application-under-test) - [Section 4: Point of Sale Data Utilities](#user-content-point-of-sale-data-utilities) +- [Section 5: Get Report](#user-content-get-report) ## Why would I write tests for code I know works? ## @@ -29,7 +30,7 @@ By writing tests for this code, you will gain understanding of _how_ to write te ### Regression ### -The biggest reason to test a known working code base is to ensure that it stays working. You will see by testing this code base that coming into a code base you do not understand and gaining that understanding is hard work. Having tests around that code ensures that someone unfamiliar with, or has been away to long from, the code base does not accidently break existing functionality. +The biggest reason to test a known working code base is to ensure that it stays working. You will see by testing this code base that coming into a code base you do not understand and gaining that understanding is hard work. Having tests around that code ensures that someone unfamiliar with, or has been away to long from, the code base does not accidentally break existing functionality. @@ -42,7 +43,13 @@ This section is doable without the hints. it is _hard_ but doable. However, the The application under test is a Point of Sale reporting utility. It will report on all sales or all returns. -### Point Of Sale Data Utility Factory Builder +### Sales Report App — Important Files ### + +> jsforms-source/4_test-dummy-form/sales-reporter/[salesReporterFactory.js](../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js) +> jsforms-source/4_test-dummy-form/pos-transaction-services/[reportDataBuilder.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js) + + +### Point Of Sale Data Utility Factory Builder ### File: [/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js) @@ -60,7 +67,7 @@ These values are already set up for you. This function returns an object with two methods. -#### `getProductCountBySale` +#### Get Product Count by Sale #### This method takes the parameter `transactionRecords` which is an array of transaction records. Each record is expected to have the following shape: @@ -109,7 +116,7 @@ The result should look like the following: Because there is a total of 5 items sold of Product ID 3, and only 4 items sold of Product ID 6. -### `getProductCountByReturn` +#### Get Product Count by Return #### This method takes the parameter `transactionRecords` which is an array of transaction records. Each record is expected to have the following shape: @@ -157,15 +164,208 @@ The result should look like the following: ``` Because there is a total of 3 items returned of Product ID 3, and 5 items returned of Product ID 6. + + +### Sales Reporter Factory ### + +The `salesReporterFactory` function has the following signature + +```javascript +function salesReporterFactory( + dataLoader, + pointOfSaleDataUtilsFactory, + reportDataBuilderFactory +) +``` + +#### Sales Reporter Factory Parameters #### + +The `dataLoader` parameter is an object with following shape: + +```javascript +{ + getProductData, + getTransactionData, + getTransactionStatuses +} +``` + +##### Get Product Data Function ##### + +The getProductData function has the following signature: + +```javascript +getProductData() +``` + +###### Get Product Data Return Value ###### + +The `getProductData` function returns an array of objects that have then following structure: + +```javascript +{ + id, // integer number -- id uniquely identifies this product + name, // string -- Name of product + price // number -- the sales price for a single item of this product +} +``` + +##### Get Transaction Data Function ##### + +The `getTransactionData` function has the following signature: + +```javascript +getTransactionData() +``` + +###### Get Transaction Data Return Value ###### + +The `getTransactionData` function returns an array of objects that have the following structure: + +```javascript +{ + productId, // integer number -- id from a product datum + transactionStatus, // integer number -- sale or return, must match the transactionStatuses object + quantity // integer number -- count sold or returned +} +``` + +##### Get Transaction Types Function ##### + +The `getTransactionStatuses` function has the following signature: + +```javascript +getTransactionStatuses() +``` + +###### Get Transaction Types Return Value ###### + +The `getTransactionStatuses` function returns an object with the following structure: + +```javascript +{ + Sale = X, // where X is an integer number + Return = Y // where Y is an integer number +} +``` + +#### Sales Reporter Factory Return Value #### + +The `` function returns an object with the following structure: + +```javascript +{ + getReport +} +``` + +##### Get Report Function ##### + +The `getReport` function has the following signature: + +```javascript +function getReport(transactionStatus) +``` -### Report Data Builder Factory +The `transactionStatus` parameter is an integer number that maps to Sale or Return as determined by the `transactionStatuses` returned from the `getTransactionStatuses` function. -TBD +###### Get Report Return Value ###### + +The `getReport` function returns an array of objects with the following structure: + +```javascript +{ + productName, // string -- Name of product, from productDatum.Name + quantity, // integer number -- count sold or returned, total of transactionData.quantity + total // number -- the sales price for a single item of this product quantity * productDatum.price +} +``` + +Each item in the array will represent the results for a different product. + + +### Report Data Builder Factory ### + +The function `reportDataBuilderFactory` has the following signature: + +```javascript +function reportDataBuilderFactory(transactionStatuses) +``` + +#### Report Data Builder Factory Parameter #### + +It takes an object with the following shape: + +```javascript +{ + Sale = X, // where X is an integer number + Return = Y // where Y is an integer number +} +``` + +#### Report Data Builder Factory Return Value #### + +It then returns an object with the following structure: + +```javascript +{ + buildReportData +} +``` + +##### Build Report Data Parameters ##### + +The `buildReportData` is a function that has the following signature: + +```javascript +buildReportData( + transactionStatus /*integer number*/, + transactionData /*object array*/, + productData /*object array*/ +) +``` + +The `transactionStatus` parameter maps to one of the integers in the `transactionStatuses` object. + +The `transactionData` parameter is an array of objects with the following structure: + +```javascript +{ + productId, // integer number -- id from a product datum + transactionStatus, // integer number -- sale or return, must match the transactionStatuses object + quantity // integer number -- count sold or returned +} +``` + +The `productData` parameter is an array of objects that have the following structure: + +```javascript +{ + id, // integer number -- id uniquely identifies this product + name, // string -- Name of product + price // number -- the sales price for a single item of this product +} +``` + +##### Build Report Data Return Value ##### + +The `buildReportData` function returns an array of objects that have the following structure: + +```javascript +{ + productName, // string -- Name of product, from productDatum.Name + quantity, // integer number -- count sold or returned, total of transactionData.quantity + total // number -- the sales price for a single item of this product quantity * productDatum.price +} +``` + +Each item in the array will represent the results for a different product. + ## Point of Sale Data Utilities ## -### Important Files +### Point of Sale Data Utilities — Important Files ### Test File: @@ -178,14 +378,14 @@ File Under Test: Helpers File: > test/form-helpers/[4_test-dummy-helpers.js](../test/form-helpers/4_test-dummy-helpers.js) + -### Get product count by sale - +### Get product count by sale ### You will be testing that the `getProductCountBySale` works correctly. (Don't worry it does, but you have to prove it.) There are a series of tests already layed out for you. We will approach each one individually. -#### It returns an empty object for sale counts if no sale data exists +#### It returns an empty object for sale counts if no sale data exists #### This first test ensures that the `getProductCountBySale` function works properly if you give it nothing to do. So when you give it an empty array, it should return an empty object. @@ -199,7 +399,7 @@ The process you will follow is: 4. Implement the assert 5. Remove Guide comments -##### Enable the test +##### Enable the test ##### Each test case is defined by an `it` block. The format for an it block is as follows @@ -233,7 +433,7 @@ The `it` already exists on line 51, all you need to do is add the arrow function -##### Add Guiding Comments +##### Add Guiding Comments ##### To the arrow function expression, you will add the following comments @@ -263,7 +463,7 @@ You will need to add two line brakes to the arrow function expression between th -##### Implement the act +##### Implement the Act ##### The "Act" refers to the action under test. You will need to do the thing the test is trying to test. So with this test you are trying to test what will happen when `getProductCountBySale` method on the `pointOfSaleDataUtilities` object is called with an empty array. @@ -287,7 +487,7 @@ You need to make a call the the `getProductCountBySale` method with an empty arr -##### Implement the Assert +##### Implement the Assert ##### Assert refers to the need to validate that the code does what we expect it to do. It often uses a keyword `assert`. For our tests they will. @@ -322,7 +522,7 @@ The expected result is `{}`. -##### Remove Guide comments +##### Remove guide comments ##### Now delete then comments as they provide no extra value. @@ -356,7 +556,7 @@ Delete the comment lines -### It returns an object with a single count of 1 when only one item, quantity 1 was purchased +#### It returns an object with a single count of 1 when only one item, quantity 1 was purchased #### The next test is to test what happens when a only one item is passed to the `getProductCountBySale` method and it is a sale with only one item sold of that product. @@ -382,7 +582,7 @@ The process you will follow is: This will be the last test where we dive into each of these steps in detail. -##### Enable the test +##### Enable the test test 2 ##### Each test case is defined by an `it` block. Enabling the test will cause the test to pass. However it is a false positive as this test does nothing. @@ -406,7 +606,7 @@ The `it` already exists just below the last test, all you need to do is add the -##### Add guide comments +##### Add guide comments test 2 ##### You will add the following three comments to the arrow function expression. @@ -438,7 +638,7 @@ You will need to add two line brakes to the arrow function expression between th -##### Implement the arrange +##### Implement the Arrange test 2 ##### Arrange refers to the need to do some setup before we act. @@ -486,7 +686,7 @@ You will create a variable and assign it to the value returned from the `buildTr -##### Implement the act +##### Implement the Act test 2 ##### The "Act" refers to the action under test. You will need to do the thing the test is trying to test. So with this test you are trying to test what will happen when `getProductCountBySale` method on the `pointOfSaleDataUtilities` object is called with an empty that has the variable created during the arrange. @@ -504,7 +704,7 @@ You need to make a call the the `getProductCountBySale` method with an empty arr let ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); // Act - let result = getProductCountBySale([?]); + let result = pointOfSaleDataUtilities.getProductCountBySale([?]); // Assert }); ``` @@ -517,7 +717,7 @@ You need to make a call the the `getProductCountBySale` method with an empty arr var ? = buildTransactionRecord(?, transactionStatuses.Sale, 1); // Act - var result = getProductCountBySale([?]); + var result = pointOfSaleDataUtilities.getProductCountBySale([?]); // Assert }); ``` @@ -526,7 +726,7 @@ You need to make a call the the `getProductCountBySale` method with an empty arr -##### Implement the assert +##### Implement the Assert test 2 ##### Assert refers to the need to validate that the code does what we expect it to do. @@ -562,7 +762,7 @@ You can just copy the provided object above into the assert for the expected val let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); // Act - let result = getProductCountBySale([transactionRecord]); + let result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); // Assert assert.deepEqual(result, { @@ -579,7 +779,7 @@ You can just copy the provided object above into the assert for the expected val var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); // Act - var result = getProductCountBySale([transactionRecord]); + var result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); // Assert assert.deepEqual(result, { @@ -592,7 +792,7 @@ You can just copy the provided object above into the assert for the expected val -##### Remove Guide comments +##### Remove Guide comments ##### Now remove the comments as they serve no further purpose. @@ -608,7 +808,7 @@ Just delete them. it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); - let result = getProductCountBySale([transactionRecord]); + let result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); assert.deepEqual(result, { [?]: 1 @@ -622,18 +822,1146 @@ Just delete them. it('returns an object with a single count of 1 when only one item, quantity 1 was purchased', () => { var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 1); - var result = getProductCountBySale([transactionRecord]); + var result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 1 + }); + }); +``` + + + +#### It returns an object with a single count of 2 when only one item, quantity 2 was purchased #### + +The intent of this test is to verify that the `quantity` field of the transaction record is actually used. By writing almost the same test, but differing only in quantity, you can verify that the `quantity` is used in the result. + +So now you will create a test that looks very similar to the previous one but will use a quantity of 2. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +However, then only steps this guide will cover for this test are the "Implement" step 3, and then the rest of the code. + +##### Implement the Arrange test 3 ##### + +After enabling the tests and writing the guide comments, you need to use the `buildTransactionRecord` function just like above. The only difference is the last parameter will be a `2` instead of a `1`. + +
Hints + +Remember then signature for the `buildTransactionRecord` is `buildTransactionRecord(productId, transactionStatus, quantity)`. + +You will simply capture the result as a variable. + +
Code + +**Example 1 (`let`)** + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + // Arrange + let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + // Act + // Assert + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + // Arrange + var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + // Act + // Assert + }); +``` + +
+ +
+ +##### Finish the Test ##### + +Now you have done the rest before. Fill in the "Act", the "Assert" and then delete the comments. Remember that you are verifying the value of the result object is `2`. + +
Hints + +The last two lines of this test should look almost exactly like the test above except with a `2` instead of a 1 for the object value. + +
Code + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + let transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + let result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 2 + }); + }); +``` + +**Example 2 (`var`)** + +```javascript + it('returns an object with a single count of 2 when only one item, quantity 2 was purchased', () => { + var transactionRecord = buildTransactionRecord(?, transactionStatuses.Sale, 2); + + var result = pointOfSaleDataUtilities.getProductCountBySale([transactionRecord]); + + assert.deepEqual(result, { + [?]: 2 + }); + }); +``` + +
+ +
+ +#### It returns an object with a two counts of 1 when two transactions of 1 qty each are passed #### + +Now you will be seeing what happens when you pass 2 different transaction records to the `getProductCountBySale` each one with a different product IDs. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +From this point on we will not cover any of the individual steps, but focus on the outcome of following those steps. Also for simplicity, this guide will only show examples for `let` variable statements as they are slightly more dependable. + +What you are going to want to do, is to modify the the test such that you create 2 different transactions records using the `buildTransactionRecord` function. + +> Make sure these have different product IDs. + +So given: + +Product ID 314 +and +Product ID 42 + +then the result should look like: + +```javascript +{ + [314]: 1 + [42]: 1 +} +``` + +
Hints + +All three parts of the test that change. In the "Arrange" you will want to create the two transactions records. + +In the "Act" you will pass both of the transaction records to the `getProductCountBySale` method. + +In the "Assert" you want to ensure the resulting object has those record quantities. + +
Code + +**Example 1 (explicit variables)** + +```javascript + it('returns an object with a two counts of 1 when two transactions of 1 qty each are passed', () => { + let transactionP1 = buildTransactionRecord(?, transactionStatuses.Sale, 1); + let transactionP2 = buildTransactionRecord(?, transactionStatuses.Sale, 1); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + transactionP1, + transactionP2 + ]); + + assert.deepEqual(result, { + [?]: 1 + [?]: 1 + }); + }); +``` + +**Example 2 (implicit variables)** + +```javascript + it('returns an object with a two counts of 1 when two transactions of 1 qty each are passed', () => { + let transactions = [ + buildTransactionRecord(?, transactionStatuses.Sale, 1) + buildTransactionRecord(?, transactionStatuses.Sale, 1) + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); assert.deepEqual(result, { [?]: 1 + [?]: 1 }); }); ```
-### TBD +
+ +#### It returns an object with a two counts when 4 transactions of two different items are passed #### + +The intent of this test is to see if the `getProductCountBySale` method will sum quantities across two different products. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +You will need to create 2 different products, each with two transaction records. The test does not specify what the quantities are, so you will have to determine that. + +> **NOTE:** Make sure that the totals of the quantities across both products are different, or else you do not know if the function is summing one and duplicating it. + +> **GUIDE:** It would be helpful to create a variable that holds each product ID as you will need that in at least three different places. Also this variable will help make your code more readable. + +
Hints + +Again all the portions of the test have changed. + +In the "Arrange" you will need to create four different transaction records across two different product IDs. You will need to ensure that the totals of the `quantities` across the products are different. + +In the "Act", you will be passing all four transaction records to the `getProductCountBySale` method. + +In the "Assert" you will verify that then resulting object has only the two product IDs passed and it has the correct summation of their quantities. + +
Code + +**Example 1 (explicit variables)** + +```javascript + it('returns an object with a two counts when 4 transactions of two different items are passed', () => { + let product1 = ?; // ID for product 1 + let product2 = ?; // ID for product 2 + + let transaction1A = buildTransactionRecord(product1, transactionStatuses.Sale, ?); + let transaction1B = buildTransactionRecord(product1, transactionStatuses.Sale, ?); + let transaction2A = buildTransactionRecord(product2, transactionStatuses.Sale, ?); + let transaction2B = buildTransactionRecord(product2, transactionStatuses.Sale, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + transaction1A, + transaction2A, + transaction1B, + transaction2B + ]); + + expect.deepEqual(result, { + [product1]: ? + [product2]: ? + }); + }); +``` + +**Example 1 (implicit variables)** + +```javascript + it('returns an object with a two counts when 4 transactions of two different items are passed', () => { + let product1 = ?; // ID for product 1 + let product2 = ?; // ID for product 2 + + let transactions = [ + buildTransactionRecord(product1, transactionStatuses.Sale, ?), + buildTransactionRecord(product2, transactionStatuses.Sale, ?), + buildTransactionRecord(product1, transactionStatuses.Sale, ?), + buildTransactionRecord(product2, transactionStatuses.Sale, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + expect.deepEqual(result, { + [product1]: ? + [product2]: ? + }); + }); +``` + +
+ +
+ +#### It returns counts only for sales, ignoring returns #### + +The last test of the `getProductCountBySale` method is to ensure that it does not count returns. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +You will need at least 2 transaction records. One that is a Sale and one that is a Return, they can have the same product ID or different ones. + +You will need to use `transactionStatuses.Return` to set the type for the return transaction. + +
Hints + +In the "Arrange" you will need to create both a Sale and a Return. + +
Code + +**Example 1 (explicit, diff IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let saleTransaction = buildTransactionRecord(?, transactionStatuses.Sale, ?); + let returnTransaction = buildTransactionRecord(?, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([returnTransaction, saleTransaction]); + + assert.deepEqual(result, { + [?]: ? + }); + }); +``` + +**Example 2 (explicit, same IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let productId = ?; + let saleTransaction = buildTransactionRecord(productId, transactionStatuses.Sale, ?); + let returnTransaction = buildTransactionRecord(productId, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([returnTransaction, saleTransaction]); + + assert.deepEqual(result, { + [productId]: ? + }); + }); +``` + +**Example 3 (implicit, diff IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let transactions = [ + buildTransactionRecord(?, transactionStatuses.Return, ?), + buildTransactionRecord(?, transactionStatuses.Sale, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [?]: ? + }); + }); +``` + +**Example 4 (implicit, same IDs)** + +```javascript + it('returns counts only for sales, ignoring returns', () => { + let productId = ?; + let transactions = [ + buildTransactionRecord(productId, transactionStatuses.Return, ?), + buildTransactionRecord(productId, transactionStatuses.Sale, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale([returnTransaction, saleTransaction]); + + assert.deepEqual(result, { + [productId]: ? + }); + }); +``` + +
+ +
+ + +### Get Product Count by Return Status ### + +#### It returns with counts only for return transactions #### + +There is only one test to this section. The reason is if you look at the file [pointOfSaleDataUtilsFactory.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js) you will see that the only difference between `getProductCountBySale` and `getProductCountByReturn` is a value passed to a second parameter of a method called underneath. So in regard to returns we just need to prove that the function can count them. + +The process you will follow is: + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +You will want to create 2 returns, and a third for a sale. + +
Hints + +In the "Arrange" you will be creating 3 different transaction reports. Two will be returns and the third will be for a sale. You can choose, if you want any of these to share IDs. + +
Code + +**Example (explicit, diff ids)** + +```javascript + it('returns with counts only for return transactions', () => { + let saleTransaction = buildTransactionRecord(?, transactionStatuses.Sale, ?); + let return1 = buildTransactionRecord(?, transactionStatuses.Return, ?); + let return2 = buildTransactionRecord(?, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [?]: ?, + [?]: ?, + }); + }); +``` + +**Example (explicit, returns share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let returnProduct = ?; + let saleTransaction = buildTransactionRecord(?, transactionStatuses.Sale, ?); + let return1 = buildTransactionRecord(returnProduct, transactionStatuses.Return, ?); + let return2 = buildTransactionRecord(returnProduct, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [returnProduct]: ?, + }); + }); +``` + +**Example (explict, all share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let productId = ?; + let saleTransaction = buildTransactionRecord(productId, transactionStatuses.Sale, ?); + let return1 = buildTransactionRecord(productId, transactionStatuses.Return, ?); + let return2 = buildTransactionRecord(productId, transactionStatuses.Return, ?); + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [productId]: ?, + }); + }); +``` + +**Example (implicit, diff ids)** + +```javascript + it('returns with counts only for return transactions', () => { + let transactions = [ + buildTransactionRecord(?, transactionStatuses.Return, ?), + buildTransactionRecord(?, transactionStatuses.Sale, ?), + buildTransactionRecord(?, transactionStatuses.Return, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [?]: ?, + [?]: ?, + }); + }); +``` + +**Example (implicit, returns share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let returnProduct = ?; + let transactions = [ + buildTransactionRecord(returnProduct, transactionStatuses.Return, ?), + buildTransactionRecord(?, transactionStatuses.Sale, ?), + buildTransactionRecord(returnProduct, transactionStatuses.Return, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale(transactions); + + assert.deepEqual(result, { + [returnProduct]: ?, + }); + }); +``` + +**Example (implicit, all share ID)** + +```javascript + it('returns with counts only for return transactions', () => { + let productId = ?; + let transactions = [ + buildTransactionRecord(productId, transactionStatuses.Return, ?), + buildTransactionRecord(productId, transactionStatuses.Sale, ?), + buildTransactionRecord(productId, transactionStatuses.Return, ?), + ]; + + let result = pointOfSaleDataUtilities.getProductCountBySale([ + return1, + saleTransaction, + return2, + ]); + + assert.deepEqual(result, { + [productId]: ?, + }); + }); +``` + +
+ +
+ + + +## Get Report ## + +In testing the `getReport` function, you will be required to do a lot more of the initial work. Fortunately you have the code from the "get product count by sale" test suite you just finished. + +The `getReport` function can either create a Sales report or a Returns report. + +### Sales Report — Important Files ### + +Test File: + +> test/[4_test-dummy-form.test.js](../test/4_test-dummy-form.test.js) + +Files Under Test: + +> jsforms-source/4_test-dummy-form/sales-reporter/[salesReporterFactory.js](../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js) +> jsforms-source/4_test-dummy-form/pos-transaction-services/[reportDataBuilder.js](../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js) + +Helpers File: + +> test/form-helpers/[4_test-dummy-helpers.js](../test/form-helpers/4_test-dummy-helpers.js) + + +### Get Sales Report ### + +You will be focusing on testing that a sales report is created correctly. In creating these tests you will follow the basic steps listed bellow. + +1. Write the first test. +2. Write the second test. +3. Refactor tests to remove repetitive code into a `beforeEach` block. +4. Finish writing tests, stopping periodically to refactor as needed. + +Now when you write each test, you will follow the process you did before with one additional step. + +1. Enable the test +2. Add guide comments +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +#### It returns a report of sales with no sales #### + +Starting with a base case of there were no sales, you will write the test that proves that it returns a report with nothing in it. + +To test the `getReport` function you will need to first call the `salesReporterFactory` function. The `salesReporterFactory` has the following signature: + +```javascript +function salesReporterFactory( + dataLoader, + pointOfSaleDataUtilsFactory, + reportDataBuilderFactory +) +``` + +You will have to create a fake `dataLoader`. You will also use the `pointOfSaleDataUtilsFactory` and the `reportDataBuilderFactory` that are already available to the test. + +This will return an empty array. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +
Data Loader Hints + +The `dataLoader` has 3 functions and the following structure: + +```javascript +{ + getProductData, + getTransactionData, + getTransactionStatuses +} +``` + +The `getProductData` will be set to the `buildProductData` helper function. The `getTransactionStatuses` will be set to the `buildTransactionStatuses` helper function. + +The real odd ball here is the `getTransactionData` which is expected to return an array of transaction records. You will have to create this function, and have it return an empty array. + +
Code + +**Example** + +```javascript + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [], + getTransactionStatuses: buildTransactionStatuses + }; +``` + +
+ +
+ +
Hints + +You just have to pass the values to the function, and capture the returned function. You will then have to call that function with a "Sale" transactionStatus. + +
Code + +```javascript +it('returns an empty object for sale counts if no sale data exists', () => { + // Arrange + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [], + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + // Act + let result = getReport(transactionStatuses.Sale); + + // Assert + assert.deepEqual(result, []); +}); +``` + +
+ +
+ +#### It returns a report of sales with one sale #### + +Okay, the last test did a lot of heavy lifting for you. Now you will test the `getReport` function for a sales report with only one item sold. + +The biggest change between this test and the previous one is that the `getTransactionData` needs to return a single transaction record that has a `quantity` of `1`. + +The `getReport` function will return an array containing a single object with the following structure: + +```javascript +{ + productName, // string -- Name of product, from productDatum.Name + quantity, // integer number -- count sold or returned, total of transactionData.quantity + total // number -- the sales price for a single item of this product quantity * productDatum.price +} +``` + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments + +
Arrange Hints + +You are going to setup the `dataLoader` the same way as you did before. But again the odd item out is the `getTransactionData` function because this needs to return an array with a single transaction record for a sale. + +The key here is that the transaction record `productId` needs to match one of the products returned from `getProductData`. The `transactionStatus` needs to match the `Sale` property on the `transactionStatuses` object. You will need to use the `buildTransactionRecord` function to create this record. + +
Code + +**Example** + +```javascript +// Arrange +let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [ + buildTransactionRecord(?, transactionStatuses.Sale, 1) + ], + getTransactionStatuses: buildTransactionStatuses +}; + +let { getReport } = salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); +``` + +
+ +
+ +
Hints + +Once you have the `dataLoader` created, you will need to only change the Assert part of the code. Remember the `total` in the result is the product's `price`. + +
Code + +**Example** + +```javascript +it('returns a report of sales with one sale', () => { + // Arrange + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => [ + buildTransactionRecord(?, transactionStatuses.Sale, 1) + ], + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + // Act + let result = getReport(transactionStatuses.Sale); + + // Assert + assert.deepEqual(result, [{ + productName: ?, + quantity: ?, + total: ? + }]); +}); +``` + +
+ +
+ +#### Refactor Sales Report Tests #### + +You have introduced a lot of duplication. And moreover the duplication in the "Arrange" part of your tests is most likely needed for the rest of the tests. As such, it is time you simplify your tests. + +A lot of JavaScript test frameworks use a construct called `beforeEach` that creates a function that is run just before each test. This allows you to setup common variables. These variables will be test suite scoped variables. + +> **
WARNING
** +> +>
You must be careful when using a test suite scoped variables as you can accidentally cause one test to effect another. To prevent this, you must reset all such variables to an initial value in the beforeEach.
+ +##### Refactor Sales Report Tests Create the Before Each ##### + +You need to create the `getReport` function in the `beforeEach` section. However, in order for this to work you will also need to create and assign a variable to hold the transaction records. This way you can add an item to it in the second test. + +
Hints + +You will need to create two variables before the "get sales report" section. One to hold the `getReport` function and the other to hold the transaction records. + +Bellow those, but still before the "get sales report" section, you will need to create the `beforeEach` section. + +
Code + +**Example** + +```javascript + describe('get report', function () { + // files being tested are: + // ../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js + + let reportBuilder; + let transactionRecords; + + beforeEach(() => { + transactionRecords = []; + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => transactionRecords, + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = + salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + reportBuilder = getReport; + }); + + describe('get sales report', function () { +``` + +
+ +
+ +##### Refactor Sales Report Tests Modify the First Test ##### + +You need to change the first test, "returns a report of sales with no sales", so that it uses the new suite level variables. + +
Hints + +The whole arrange is now being done in the `beforeEach`. So delete that and use the variable that is holding the `getReport` function. + +
Code + +**Example** + +```javascript + describe('get report', function () { + // files being tested are: + // ../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js + + let reportBuilder; + let transactionRecords; + + beforeEach(() => { + transactionRecords = []; + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => transactionRecords, + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = + salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + reportBuilder = getReport; + }); + + describe('get sales report', function () { + it('returns an empty object for sale counts if no sale data exists', () => { + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, []); + }); +``` + +
+ +
+ +##### Refactor Sales Report Tests Modify the Second Test ##### + +The second test has more to it. You still have an arrange that is specific to the test. You need to add the transaction record to the variable used to store the transaction records. You might be able to use the [`Array.prototype.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) method. + +
Hints + +Most of the arrange in this test can be deleted. You will just need to add the sales transaction record to the array before calling the `getReport` function. + +
Code + +**Example** + +```javascript + let reportBuilder; + let transactionRecords; + + beforeEach(() => { + transactionRecords = []; + let dataLoader = { + getProductData: buildProductData, + getTransactionData: () => transactionRecords, + getTransactionStatuses: buildTransactionStatuses + }; + + let { getReport } = + salesReporterFactory(dataLoader, pointOfSaleDataUtilsFactory, reportDataBuilderFactory); + + reportBuilder = getReport; + }); + + describe('get sales report', function () { + + // ... + + it('returns a report of sales with one sale', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, 1)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [{ + productName: ?, + quantity: ?, + total: ? + }]); + }); +``` + +
+ +
+ +#### It returns a report of sales with two sales of different products #### + +Now you will test that the `getReport` can return a report with two different products. + +This will look very similar to the above test, but you will need to add two products, with different quantities to the transaction records. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +Add the two different products to the transaction records. Make sure that the `productId` of each maps to a product that is returned by the `buildProductData` function. You will also want each product to have a different non-one `quantity` value. + +You will also have two objects in the result to test for. + +
Code + +**Example** + +```javascript +it('returns a report of sales with two sales of different products', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the first product ID + quantity: ?, // The quantity of the first transaction record + total: ? // the price from the first product multiplied by te quantity + }, + { + productName: ?, // The name that maps to the second product ID + quantity: ?, // The quantity of the second transaction record + total: ? // the price from the second product multiplied by the quantity + }, + ]); +}); +``` + +
+ +
+ +#### It returns a report of sales with two sales of the same product #### + +You will test what happens if the transaction records have two different transactions for the sale of the same product. The result should represent the total of the quantity. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +This test will look very similar to the above with the difference that the two transaction records will share the same `productId`. + +There will only be a single object in the result. + +
Code + +**Example** + +```javascript +it('returns a report of sales with two sales of the same product', () => { + let productId = ?; + transactionRecords.push(buildTransactionRecord(productId, transactionStatuses.Sale, ?)); + transactionRecords.push(buildTransactionRecord(productId, transactionStatuses.Sale, ?)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the product ID + quantity: ?, // The total quantity of the transaction records + total: ? // the price from the product multiplied by the total quantity + }, + ]); +}); +``` + +
+ +
+ +#### It returns a report of sales excluding any return transactions #### + +Now, you will verify that the `getReport` function filters according to the Sale transaction status. + +You will want to create a number of sale transactions, at least 3 across at least two products, with one or more return transactions mixed into the bunch. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +You are going to create the test very similarly to two tests ago, but you will add a new transaction record that has the `transactionStatus` equal to Return. + +
Code + +**Example** + +```javascript +it('returns a report of sales excluding any return transactions', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Return, ?)); // This is the record that is not going to be counted + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); + + let result = reportBuilder(transactionStatuses.Sale); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the first product ID + quantity: ?, // The quantity of the first transaction record + total: ? // the price from the first product multiplied by te quantity + }, + { + productName: ?, // The name that maps to the third product ID + quantity: ?, // The quantity of the third transaction record + total: ? // the price from the third product multiplied by the quantity + }, + ]); +}); +``` + +
+ +
+ + +### Get Returns Report ### + +There is little to do in testing the "Returns" report because if you look at the code, it is almost entirely the same code as what creates the "Sales" report. So the only thing we have to do is test that it correctly filters when we ask for a report of the "Returns". + +#### It returns a report of return transactions that excludes sales transactions #### + +You will now create a test that will verify that the report is correct when you ask for it to give you a report of the returns. + +You will want at least three different transactions records that are composed of at least two different product IDs. You will want one of those records to be a Sale and the rest to be Returns. + +You will then verify that the resulting object has the correct products, quantities, and prices. + +Remember to pass `transactionStatuses.Return` to the `getReport` function. + +To write this test follow these steps. + +1. Enable the test +2. Add guide comments + 1. Arrange + 2. Act + 3. Assert +3. Implement the arrange +4. Implement the act +5. Implement the assert +6. Remove Guide comments +7. Refactor code if possible + +
Hints + +This will look very much like the last test but the transaction statuses are swapped. + +
Code + +**Example** + +```javascript +describe('get returns report', function () { + it('returns a report of return transactions that excludes sales transactions', () => { + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Return, ?)); + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Sale, ?)); // This is the record that is not going to be counted + transactionRecords.push(buildTransactionRecord(?, transactionStatuses.Return, ?)); + + let result = reportBuilder(transactionStatuses.Return); + + assert.deepEqual(result, [ + { + productName: ?, // The name that maps to the first product ID + quantity: ?, // The quantity of the first transaction record + total: ? // the price from the first product multiplied by te quantity + }, + { + productName: ?, // The name that maps to the third product ID + quantity: ?, // The quantity of the third transaction record + total: ? // the price from the third product multiplied by the quantity + }, + ]); + + }); +}); +``` + +
+ +
+ +## TDB ## \ No newline at end of file diff --git a/docs/THIRD-FORM.md b/docs/THIRD-FORM.md index c8ea6a8..1aac781 100644 --- a/docs/THIRD-FORM.md +++ b/docs/THIRD-FORM.md @@ -18,9 +18,10 @@ You will be working in the [jsforms-source/3_third-form.js](../jsforms-source/3_ - [Section 4: The Other JS Learner Forms](#user-content-the-other-js-learner-forms) ## Greeter ## + You are going to start by refactoring the `greet` function. -### Refactoring steps +### Refactoring steps ### Here are the steps you will take to refactor the `greet` function to ensure you change the shape without changing the behavior. @@ -29,7 +30,7 @@ Here are the steps you will take to refactor the `greet` function to ensure you 3. Create function called `eitherOnType` 4. Replace ternary in greet function with `eitherOnType` -#### It has a function called `isTypeOf` which takes parameters `type` and `value` +#### It has a function called `isTypeOf` which takes parameters `type` and `value` #### Create a function called `isTypeOf` with the two parameters of `type` and `value`. You are _not_ exporting this function. This function checks the type of the `value` and returns a Boolean true if the `value` is of the given `type`. @@ -51,7 +52,7 @@ This will use `typeOf` to do the check. -#### It calls isTypeOf from greet +#### It calls `isTypeOf` from greet #### Now you will modify the `greet` function to use the `isTypeOf` function instead of the `typeOf` function. @@ -73,7 +74,7 @@ You will need to replace not only the call to `typeOf` but also the comparison t -#### It has a function called `eitherOnType` with parameters `type`, `testValue`, `defaultValue` -- return `testValue` if it matches `type`, otherwise return `defaultValue` +#### It has a function called `eitherOnType` with parameters `type`, `testValue`, `defaultValue` -- return `testValue` if it matches `type`, otherwise return `defaultValue` #### Create a the function `eitherOnType`, you will _not_ export this function. The `eitherOnType` function takes two parameters `testValue` and `type`. It then compares the `testValue`'s type. If the `testValue` has the same type as the one given, it returns the `testValue`. If the `testValue` has a different type then it returns the `defaultValue`. @@ -107,7 +108,7 @@ You will want to use the new `isTypeOf` function. -#### It calls eitherOnType from greet +#### It calls `eitherOnType` from greet #### Modify the `greet` function so that you replace the trinary operator with the `eitherOnType` function. @@ -131,9 +132,10 @@ The trinary operator has effectively moved to the `eitherOnType` method. The one ## Sum ## + You will refactor the `sum` function. -### Refactoring steps +### Refactoring steps ### Here are the steps you will take to refactor the `sum` method so that you can change its shape without changing its behavior. @@ -143,7 +145,7 @@ Here are the steps you will take to refactor the `sum` method so that you can ch _**KEEP THE TESTS PASSING!**_ -#### It has been refactored to use `reduce` in the place of `forEach`, assigning the output to result +#### It has been refactored to use `reduce` in the place of `forEach`, assigning the output to result #### Modify the `sum` function to use the [`Array.prototype.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) method in place of the [`Array.prototype.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) method. @@ -180,7 +182,7 @@ In short you can use this similarly to the `forEach` method but without the need -#### It has been refactored to pass the add function directly to reduce +#### It has been refactored to pass the add function directly to reduce #### Modify the `sum` function to no longer use a function expression and instead just directly use the `add` function. @@ -204,7 +206,7 @@ The `reduce` method takes a function with two parameters, `add` takes two parame -#### It has been refactored to not assign the sum before returning it +#### It has been refactored to not assign the sum before returning it #### Modify the `sum` function to just return the result instead of assigning it to a variable. @@ -228,13 +230,14 @@ Get rid of the `result` variable and just return the result of the call to reduc ## Build Vector ## + You will refactor the `buildVector` function. -### Getter properties and value immutability +### Getter properties and value immutability ### You will learn how to add readonly properties to an object. You will be modifying the `Vector` object. -#### It should have access to read, but not write, vector.points +#### It should have access to read, but not write, vector.points #### The `Vector` object's internal `points` array should be read only. This is accomplished by using a [property getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get). @@ -264,7 +267,7 @@ function Vector(points) { -#### It should not change `Vector` object when the original array is modified +#### It should not change `Vector` object when the original array is modified #### Now you will modify the `Vector` function to return a copy of the array passed into it. This will isolate the `Vector` object from changes that happen outside of the object. @@ -289,7 +292,7 @@ Maybe the `Array.prototype.slice` method might be useful. -#### It should not be possible to modify `vector.points` +#### It should not be possible to modify `vector.points` #### Modify the `Vector` method to make the copy of the `points` array read only. @@ -314,11 +317,11 @@ It might help to use the [Object.freeze](https://developer.mozilla.org/en-US/doc -#### Constructor type check +#### Constructor type check #### You will be modifying the `Vector` function to have better type checking. This will include type validation and throwing of errors. -#### It throws an error if constructor is called with a value which is not an array +#### It throws an error if constructor is called with a value which is not an array #### Modify the `Vector` function to throw an error if the `points` parameter is not a type of an array. @@ -347,7 +350,7 @@ To test that something is an array or not, you cannot use the `typeOf` function -#### It throws an error if constructor is called with an array of one value which is not a number +#### It throws an error if constructor is called with an array of one value which is not a number #### Modify the `Vector` function to check the type of the first element in the array to ensure it is a number. Then `throw` a new `Error` if it isn't. @@ -380,7 +383,7 @@ You might be able to use the `isTypeOf` function here. -#### It throws an error if constructor is called with an array which contains values other than numbers +#### It throws an error if constructor is called with an array which contains values other than numbers #### Modify the `Vector` function to check the type of all elements in the array to ensure that they are all numbers. Then `throw` a new `Error` if any of them are not. @@ -435,14 +438,14 @@ You might be able to use the `Array.prototype.filter` method or the `Array.proto -#### Refactoring steps +#### Refactoring steps #### Now you will modify the `Vector` method such that you will change the shape of it without changing the behavior. 1. You will create methods that handle the type checking. 2. You will then utilize these methods instead of having the error checking embedded in the `Vector` constructor. -##### It has a function called `assertArray` with parameter `values` +##### It has a function called `assertArray` with parameter `values` ##### Create a function called `assertArray` which will look at the type of the parameter `values` and throw an exception if `values` is not an array. @@ -466,7 +469,7 @@ You already have the code, you will just add it into a new function. -##### It has a function called `assertArrayOfType` with a parameters `type` and `values`' +##### It has a function called `assertArrayOfType` with a parameters `type` and `values` ##### Now create a function called `assertArrayOfType` that compares all items in `values` with the given `type` and throws an exception if any of the values are not the correct type. @@ -503,7 +506,7 @@ Again you already have this code. You just need to add it in the new function. -##### It has a call in `assertArrayOfType` function to `assertArray` with `values` as an argument' +##### It has a call in `assertArrayOfType` function to `assertArray` with `values` as an argument ##### Modify the `assertArrayOfType` function to call the `assertArray` function before it checks the values in the array. @@ -537,7 +540,7 @@ Modify the `assertArrayOfType` function to call the `assertArray` function befor -##### It has a call in `Vector` constructor to `assertArrayOfType` +##### It has a call in `Vector` constructor to `assertArrayOfType` ##### Now modify the `Vector` function to call the `assertArrayOfType` instead of the logic to check the type. diff --git a/jsforms-source/4_test-dummy-form/data-access/dataLoaderFactory.js b/jsforms-source/4_test-dummy-form/data-access/dataLoaderFactory.js index d3bfcb7..a270a1b 100644 --- a/jsforms-source/4_test-dummy-form/data-access/dataLoaderFactory.js +++ b/jsforms-source/4_test-dummy-form/data-access/dataLoaderFactory.js @@ -8,13 +8,13 @@ function dataLoaderFactory(dataSourceAccess) { return dataSourceAccess.loadTransactionData() } - function getTransactionTypes() { - return dataSourceAccess.loadTransactionTypes(); + function getTransactionStatuses() { + return dataSourceAccess.loadTransactionStatuses(); } return { getProductData: getProductData, getTransactionData: getTransactionData, - getTransactionTypes: getTransactionTypes + getTransactionStatuses: getTransactionStatuses }; } diff --git a/jsforms-source/4_test-dummy-form/data-access/dataSourceAccessFactory.js b/jsforms-source/4_test-dummy-form/data-access/dataSourceAccessFactory.js index f30f3b4..0efe440 100644 --- a/jsforms-source/4_test-dummy-form/data-access/dataSourceAccessFactory.js +++ b/jsforms-source/4_test-dummy-form/data-access/dataSourceAccessFactory.js @@ -6,7 +6,7 @@ function dataSourceAccessFactory() { return { loadTransactionData: throwOnLoad, - loadTransactionTypes: throwOnLoad, + loadTransactionStatuses: throwOnLoad, loadProductTypes: throwOnLoad }; } diff --git a/jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js b/jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js index 13baad2..89f37ec 100644 --- a/jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js +++ b/jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js @@ -1,23 +1,23 @@ // eslint-disable-next-line -function reportDataBuilderFactory() { +function reportDataBuilderFactory(transactionStatuses) { function getObjectElements(dataObject) { return Object.keys(dataObject) .map(key => dataObject[key]); } - function isSaleType(transactionType) { - return transactionType === 'Sale'; + function isSaleType(transactionStatus) { + return transactionStatus === transactionStatuses.Sale; } - function getTotalSignMultiplier(transactionType) { - return isSaleType(transactionType) ? 1 : -1; + function getTotalSignMultiplier(transactionStatus) { + return isSaleType(transactionStatus) ? 1 : -1; } - function buildProductTransactionRecord(productCounts, transactionType) { + function buildProductTransactionRecord(productCounts, transactionStatus) { return function (product) { const quantity = productCounts[product.id]; - const signMultiplier = getTotalSignMultiplier(transactionType); + const signMultiplier = getTotalSignMultiplier(transactionStatus); return { productName: product.name, @@ -34,19 +34,19 @@ function reportDataBuilderFactory() { } return function (pointOfSaleDataUtils) { - function pickProductCountAction(transactionType) { - return isSaleType(transactionType) + function pickProductCountAction(transactionStatus) { + return isSaleType(transactionStatus) ? pointOfSaleDataUtils.getProductCountBySale : pointOfSaleDataUtils.getProductCountByReturn; } - function buildReportData(transactionType, transactionData, productData) { - const getProductCounts = pickProductCountAction(transactionType); + function buildReportData(transactionStatus, transactionData, productData) { + const getProductCounts = pickProductCountAction(transactionStatus); const productCounts = getProductCounts(transactionData); return getObjectElements(productData) .filter(isProductInCountData(productCounts)) - .map(buildProductTransactionRecord(productCounts, transactionType)) + .map(buildProductTransactionRecord(productCounts, transactionStatus)) } return { diff --git a/jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js b/jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js index c65ef71..e2b1b23 100644 --- a/jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js +++ b/jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js @@ -5,15 +5,15 @@ function salesReporterFactory( reportDataBuilderFactory ) { - function getReport(transactionType) { + function getReport(transactionStatus) { const productData = dataLoader.getProductData(); const transactionData = dataLoader.getTransactionData(); - const transactionTypes = dataLoader.getTransactionTypes(); + const transactionStatuses = dataLoader.getTransactionStatuses(); - const pointOfSaleDataUtils = pointOfSaleDataUtilsFactory(transactionTypes); - const reportDataBuilder = reportDataBuilderFactory(pointOfSaleDataUtils); + const pointOfSaleDataUtils = pointOfSaleDataUtilsFactory(transactionStatuses); + const reportDataBuilder = reportDataBuilderFactory(transactionStatuses)(pointOfSaleDataUtils); - return reportDataBuilder.buildReportData(transactionType, transactionData, productData); + return reportDataBuilder.buildReportData(transactionStatus, transactionData, productData); } return { diff --git a/test/4_test-dummy-form.test.js b/test/4_test-dummy-form.test.js index d367b47..beb48e9 100644 --- a/test/4_test-dummy-form.test.js +++ b/test/4_test-dummy-form.test.js @@ -35,19 +35,16 @@ describe('Test Dummy Form - Costume Shop Sales', function () { describe('Point of Sale Data Utilities', function () { // File being tested can be found here: // ../jsforms-source/4_test-dummy-form/pos-transaction-services/pointOfSaleDataUtilsFactory.js + + let pointOfSaleDataUtilities; + let transactionStatuses; - describe('get product count by sale', function () { - - let pointOfSaleDataUtilities; - let transactionStatuses; - let testData; - - beforeEach(function(){ - testData = buildSimpleTestData(); - transactionStatuses = buildTransactionStatuses(); - pointOfSaleDataUtilities = pointOfSaleDataUtilsFactory(transactionStatuses); - }); + beforeEach(function () { + transactionStatuses = buildTransactionStatuses(); + pointOfSaleDataUtilities = pointOfSaleDataUtilsFactory(transactionStatuses); + }); + describe('get product count by sale', function () { it('returns an empty object for sale counts if no sale data exists'); it('returns an object with a single count of 1 when only one item, quantity 1 was purchased'); @@ -67,22 +64,24 @@ describe('Test Dummy Form - Costume Shop Sales', function () { }); }); - describe('sales report', function () { + describe('get report', function () { + // files being tested are: + // ../jsforms-source/4_test-dummy-form/sales-reporter/salesReporterFactory.js + // ../jsforms-source/4_test-dummy-form/pos-transaction-services/reportDataBuilder.js describe('get sales report', function () { - it('returns a sales report with no sales'); + it('returns a report of sales with no sales'); - it('returns a sales report with one sale'); + it('returns a report of sales with one sale'); - it('returns a sales report with two sales of different products'); + it('returns a report of sales with two sales of different products'); - it('returns a sales report with two sales of the same product'); + it('returns a report of sales with two sales of the same product'); - it('returns a sales report with no "returns" data'); + it('returns a report of sales excluding any return transactions'); }); - }); - describe('returns report', function () { - it('returns a "returns" report with no "sales" data'); + describe('get returns report', function () { + it('returns a report of return transactions that excludes sales transactions'); + }); }); - }); diff --git a/test/6_async-test-dummy-form.test.js b/test/6_async-test-dummy-form.test.js index dec2fdf..9968543 100644 --- a/test/6_async-test-dummy-form.test.js +++ b/test/6_async-test-dummy-form.test.js @@ -24,46 +24,91 @@ describe('Async Test Dummy Form', function () { asyncContacts(contactServiceInstance, pluginApiInstance); }); + // For this first suite of tests, we are going to work with comparing strings + // The goal is to test that our string compare function works as expected describe('compareNames', function () { + // Checking if two values are equal can be done with assert.equal. + // Assert is part of the Chai testing package. it('should return 0 when two values are equal'); + // Equality checking is one of the most common ways to test + // the results of code, so it's important to get comfortable with it it('should return -1 when name1 comes before name2 alphabetically'); + // It's important to test all cases. The function, compareNames, has + // three distinct outcomes. One of the core ideas in testing your code + // is to test until you're bored. Ideally, being bored will come at + // about the same time you've tested all cases. it('should return 1 when name1 comes after name2 alphabetically'); - }); + // Our second suite of tests will validate the behavior of a record comparison + // function. We will need to create records which look like the following: + // { firstName: 'first name', lastName: 'last name' } describe('compareContactRecords', function () { + // Typically it's not necessary to test an extracted function, but it is useful to see + // tests written in small steps at times. Let's write some tests like we would + // normally do. it('should return 0 when first and last name are equal between two records'); + // Let's just get the next couple tests out of the way. They're like the first ones we wrote, + // but comparing records. it('should return -1 when record1.lastName comes before record2.lastName alphabetically'); + // After completing this test, we will have repeated code. Let's do this in two parts: + // - complete the test + // - lift the duplicated records into a beforeEach block it('should return 1 when record1.lastName comes after record2.lastName alphabetically'); + // We will need to introduce another record to test this next behavior. + // By reading the description, what does this new record need to contain? it('should return -1 when last names are equal and record1.firstName comes before record3.firstName alphabetically'); + // We could use the same record from the previous test to run this test case as well + // If this generates duplicate code, how would we resolve that? it('should return 1 when last names are equal and record1.firstName comes after record3.firstName alphabetically'); - }); describe('sortByContactName', function () { + // In this test we want to approve the output from the sort method. + // the verify method available globally. Try the following to see how + // to use it: + // console.log(exploreFunction(verify)); it('should return an array of records sorted by name'); + // We want to make sure that, even in the worst case scenario, + // sortByContactName always returns an array, so a calling function + // doesn't fail on a type error it('should return an empty array if passed argument is not an array'); - }); describe('getContactNames', function () { + // To fix this issue you will need to understand how the Mockery + // library works. The beforeEach at the very top of this test will + // give you a place to start. + // Assert has a method "doesNotThrow." This would be quite useful here it('should not throw error immediately when called'); + // Sinon is a library built for handling cases where you want to get a view + // of how functions are called within your tests. Let's spy on something and + // approve the results. it('should correctly request contact names from a remote service'); + // We will need to modify our setup a little more to ensure we + // get an error. It might be useful to know when an error occurs, + // promises typically call the reject method. + // - First get the test working + // - Second remove the asynchronicity from the test it('should call callback with error and a null value on failure'); + // Be careful with this one, approvals within promises produces some really + // strange output! This test will start almost the same as the error test. + // - First set promiseState.error to true, then see what happens + // - Add records to the promise state and verify on the full result it('should call callback with a null error and an array of sorted names on success'); }); diff --git a/test/form-helpers/4_test-dummy-helpers.js b/test/form-helpers/4_test-dummy-helpers.js index c9d9a40..bb4364e 100644 --- a/test/form-helpers/4_test-dummy-helpers.js +++ b/test/form-helpers/4_test-dummy-helpers.js @@ -19,6 +19,16 @@ const fourthFormHelpers = (function () { id: 2, name: 'Robot Costume', price: 59.99 + }, + { + id: 3, + name: 'Cow Costume', + price: 49.99 + }, + { + id: 3, + name: 'Doctor Costume', + price: 35.99 } ]; } @@ -45,7 +55,7 @@ const fourthFormHelpers = (function () { function buildTestData(productData, transactionStatuses, transactionData = []) { return { productData: productData, - transactionTypes: transactionStatuses, + transactionStatuses: transactionStatuses, transactionData: transactionData }; }