From de3f2f7b64be61cf31662bce7ea623c917f7eb3c Mon Sep 17 00:00:00 2001 From: colevandersWands <18554853+colevandersWands@users.noreply.github.com> Date: Wed, 30 Oct 2019 13:36:30 +0100 Subject: [PATCH 01/12] week-2-project-readme --- week-2-project/README.md | 79 ++++++++++++++++++++------- week-2-project/app.js | 11 ++-- week-2-project/tests/add-entry.js | 4 +- week-2-project/tests/find-by-key.js | 4 +- week-2-project/tests/find-by-value.js | 14 ++++- week-2-project/tests/remove-entry.js | 4 +- week-2-project/tests/update-entry.js | 4 +- 7 files changed, 86 insertions(+), 34 deletions(-) diff --git a/week-2-project/README.md b/week-2-project/README.md index 4591553..abad0a2 100644 --- a/week-2-project/README.md +++ b/week-2-project/README.md @@ -1,19 +1,60 @@ -practice problems -- -- -- -- - -app object -- -- -- -- -- - -user interface -- -- -- -- -- + +## Week 2 Project + + + +The weekly projects in JS 2 will be making an even stronger distinction between your core application and the user interface. To help you with this transition there will be two assignment tables, one for the core app object and another for the user interface. + + + +What you should notice and think about is that there is not a perfect 1-1 pairing between user stories (what is seen on the screen) and the core object (the software that makes the UI possible). Some User Stories are all about the UI/UX and don't require any changes in the core object, while some methods in the core object have no direct representation in the UI. + + + +--- + + + +### Core Object + + + +> this table is written like documentation + + + + +| __it should ...__ | __syntax__ | __parameters__ | __return value__ | __description__ | +| --- | --- | --- | --- | --- | +| _... determines if values are primitive or not_ | ```obj.isPrimitive(value)``` | _value_: any JS value | Boolean | It returns ```true``` if the argument is a primitive, otherwise it returns ```false```. | +| _... determines if an object has a given key_ | ```obj.hasKey(obj, key)``` | _obj_: an object
_key_: a string | Boolean | It returns ```true``` if the object has the given key, otherwise it returns ```false```. | +| _... determines if an object has a given value_ | ```obj.hasValue(obj, value)``` | _obj_: an object
_value_: any JS type | Boolean | It returns ```true``` if any key in the object stores this value, otherwise it returns ```false```. | +| _... adds key/value pairs to ```this.entries```_ | ```obj.addEntry(key, value)``` | _key_: a string
_value_: any primitive value | ```true``` or an error | It returns ```true``` if the key/value pair was successfully added, otherwise it returns helpful error describing what went wrong. | +| _... removes a key/value pair from ```this.entries```_ | ```obj.removeEntry(key)``` | _key_: a string | ```true``` or an error | It returns ```true``` if the key/value pair was successfully removed, otherwise it returns helpful error describing what went wrong. | +| _... updates a key/value pair in ```this.entries```_ | ```obj.updateEntry(key, value)``` | _key_: a string
_value_: any primitive type | ```true``` or an error | It returns ```true``` if the key/value pair was successfully updated, otherwise it returns helpful error describing what went wrong. | +| _... returns all key/value pairs in ```this.entries```_ | ```obj.readAll()``` | (no parameters) | an object | a new object with the same key/value pairs as ```this.entries``` | +| _... finds an entry by key_ | ```obj.findByKey(key)``` | _key_: a string | an object or an error | It returns an object with the given key, and it's value in ```this.entries```. Or a helpful error | +| _... finds an entry by value | ```obj.findByValue(value)``` | _value_: a primitive | an object or an error | It returns an object with all key/value pairs in ```this.entries``` containing the given value. Or a helpful error | + + + +--- + + + +### User Interface + + + +> this table is written as user stories + + + +| __As a/n__ ... | __I can__ ... | __so that__ ... | +| --- | --- | --- | +| _... enthusiastic JS student_ | ... know what this site does and how to use it | ... I can use it to organize my favorite primitive values | +| _... enthusiastic JS student_ | ... set input new keys and primitive values | ... I can practice always being aware of what types _and_ values my application stores | +| _... enthusiastic JS student_ | ... select a method to call with my inputs | ... modify the values stored in this app, and search for particular entries | +| _... enthusiastic JS student_ | ... see the values stored in ```this.entries``` rendered to the DOM | ... I can easily know what is stored in the app without console.logging | +| _... HYF coach_ | ... resize the browser window | ... I can test your responsive design | +| _... HYF coach_ | ... inspect the web page | ... I can see if you correctly used HTML5 semantic elements, CSS classes, and generally wrote clean code | diff --git a/week-2-project/app.js b/week-2-project/app.js index 81aeeae..1eec39e 100644 --- a/week-2-project/app.js +++ b/week-2-project/app.js @@ -8,6 +8,9 @@ - and users can access & modify that data */ + + + const object = { entries: {}, isPrimitive: function (value) { @@ -27,7 +30,7 @@ const object = { return new TypeError('addEntry: value should be a primitive'); } if (null) { // write me! (using this.hasKey) - return { [key]: new Error(`addEntry: key "${key}" already exists`) }; + return new Error(`addEntry: key "${key}" already exists`); } // write me! @@ -37,7 +40,7 @@ const object = { return new TypeError('removeEntry: key should be a string'); } if (null) { // write me! (using this.hasKey) - return { [key]: new ReferenceError(`removeEntry: no property "${key}" in this.entries`) }; + return new ReferenceError(`removeEntry: no property "${key}" in this.entries`); } // write me! @@ -50,7 +53,7 @@ const object = { return new TypeError('updateEntry: value should be a primitive'); } if (null) { // write me! (using this.hasKey) - return { [key]: new ReferenceError(`updateEntry: no property "${key}" in this.entries`) }; + return new ReferenceError(`updateEntry: no property "${key}" in this.entries`); } // write me! @@ -63,7 +66,7 @@ const object = { return new TypeError('findByKey: key should be a string'); } if (null) { // write me! (using this.hasKey) - return { [key]: new ReferenceError(`findByKey: no property "${key}" in this.entries`) }; + return new ReferenceError(`findByKey: no property "${key}" in this.entries`); } // write me! diff --git a/week-2-project/tests/add-entry.js b/week-2-project/tests/add-entry.js index 47914e6..a0987f7 100644 --- a/week-2-project/tests/add-entry.js +++ b/week-2-project/tests/add-entry.js @@ -30,8 +30,8 @@ describe(`addEntry: should add a new key/value pair to this.entries`, () => { ['firstKey', 'secondKey', 'thirdKey', 'fourthKey'].forEach(arg => { it(`${arg}`, () => { const result = object.addEntry(arg, ''); - assert.ok(result[arg] instanceof Error); - assert.strictEqual(result[arg].message, `addEntry: key "${arg}" already exists`); + assert.ok(result instanceof Error); + assert.strictEqual(result.message, `addEntry: key "${arg}" already exists`); }); }); }); diff --git a/week-2-project/tests/find-by-key.js b/week-2-project/tests/find-by-key.js index 183cafe..1916184 100644 --- a/week-2-project/tests/find-by-key.js +++ b/week-2-project/tests/find-by-key.js @@ -21,8 +21,8 @@ describe(`findByKey: returns the requested key/value pair, or an informative err ['a', 'b', 'c', 'd'].forEach(arg => { it(`${arg}`, () => { const result = object.findByKey(arg); - assert.ok(result[arg] instanceof ReferenceError); - assert.strictEqual(result[arg].message, `findByKey: no property "${arg}" in this.entries`); + assert.ok(result instanceof ReferenceError); + assert.strictEqual(result.message, `findByKey: no property "${arg}" in this.entries`); }); }); }); diff --git a/week-2-project/tests/find-by-value.js b/week-2-project/tests/find-by-value.js index 5042fcc..0ae4f3a 100644 --- a/week-2-project/tests/find-by-value.js +++ b/week-2-project/tests/find-by-value.js @@ -31,7 +31,7 @@ describe(`findByValue: returns the requested key/value pair, or an informative e }); }); }); - describe(`otherwise returns an object containing the requested key/value pair`, () => { + describe(`otherwise returns an object containing the requested key/value pairs`, () => { [ ['firstValue', { firstKey: 'firstValue' }], ['secondValue', { secondKey: 'secondValue' }], @@ -44,11 +44,19 @@ describe(`findByValue: returns the requested key/value pair, or an informative e }); it(`it finds all keys containing "fourthValue"`, () => { const result = object.findByValue('fourthValue'); - assert.deepStrictEqual(Object.keys(result), ['fourthKey', 'fifthKey', 'sixthKey']); + assert.deepStrictEqual(result, { + fourthKey: 'fourthValue', + fifthKey: 'fourthValue', + sixthKey: 'fourthValue' + }); }); it(`and all keys containing "fifthValue"`, () => { const result = object.findByValue('fifthValue'); - assert.deepStrictEqual(Object.keys(result), ['seventhKey', 'eighthKey', 'ninthKey']); + assert.deepStrictEqual(result, { + seventhKey: 'fifthValue', + eighthKey: 'fifthValue', + ninthKey: 'fifthValue' + }); }); }); }); diff --git a/week-2-project/tests/remove-entry.js b/week-2-project/tests/remove-entry.js index 17e22c5..3b02792 100644 --- a/week-2-project/tests/remove-entry.js +++ b/week-2-project/tests/remove-entry.js @@ -21,8 +21,8 @@ describe(`removeEntry: should remove a key/value pair from this.entries`, () => ['tomato', 'potato', 'patate', 'pomme de terre'].forEach(arg => { it(`${arg}`, () => { const result = object.removeEntry(arg); - assert.ok(result[arg] instanceof Error); - assert.strictEqual(result[arg].message, `removeEntry: no property "${arg}" in this.entries`); + assert.ok(result instanceof Error); + assert.strictEqual(result.message, `removeEntry: no property "${arg}" in this.entries`); }); }); }); diff --git a/week-2-project/tests/update-entry.js b/week-2-project/tests/update-entry.js index fd9870f..f670fa0 100644 --- a/week-2-project/tests/update-entry.js +++ b/week-2-project/tests/update-entry.js @@ -30,8 +30,8 @@ describe(`updateEntry: should add a new key/value pair to this.entries`, () => { ['tomato', 'potato', 'patate', 'pomme'].forEach(arg => { it(`${arg}`, () => { const result = object.updateEntry(arg, ''); - assert.ok(result[arg] instanceof ReferenceError); - assert.strictEqual(result[arg].message, `updateEntry: no property "${arg}" in this.entries`); + assert.ok(result instanceof ReferenceError); + assert.strictEqual(result.message, `updateEntry: no property "${arg}" in this.entries`); }); }); }); From dd76c42da2ab7ee40441cab2b98de90ca66b9909 Mon Sep 17 00:00:00 2001 From: Anthony Meirlaen Date: Fri, 1 Nov 2019 17:23:07 +0100 Subject: [PATCH 02/12] Add all exercises to index.html view --- week-2-project/practice-problems/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/week-2-project/practice-problems/index.html b/week-2-project/practice-problems/index.html index 3b4bfc6..48a7c5f 100644 --- a/week-2-project/practice-problems/index.html +++ b/week-2-project/practice-problems/index.html @@ -22,8 +22,11 @@ - + + + +
From 5d771d941f16b0928299c065817aba6e5b7a7f62 Mon Sep 17 00:00:00 2001 From: Anthony Meirlaen Date: Fri, 1 Nov 2019 17:25:33 +0100 Subject: [PATCH 03/12] Use camel cased vars in asserts --- week-2-project/practice-problems/arrays-vs-objects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/week-2-project/practice-problems/arrays-vs-objects.js b/week-2-project/practice-problems/arrays-vs-objects.js index 4a7e82c..35261ea 100644 --- a/week-2-project/practice-problems/arrays-vs-objects.js +++ b/week-2-project/practice-problems/arrays-vs-objects.js @@ -35,8 +35,8 @@ try { // asserts - console.assert(obj[obj_key] === "object", "obj assert"); - console.assert(arr[arr_index] === "array", "arr assert"); + console.assert(obj[objKey] === "object", "obj assert"); + console.assert(arr[arrIndex] === "array", "arr assert"); } evaluate(swapValues2); From c2667196d182bcdc8e4336f5dc8e0aa2eb857c8d Mon Sep 17 00:00:00 2001 From: Anthony Meirlaen Date: Sat, 2 Nov 2019 16:01:53 +0100 Subject: [PATCH 04/12] add some doc about which javascript function to use psst this more of a commit to force a merge conflict --- week-1-project/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week-1-project/app.js b/week-1-project/app.js index fd5f1e0..5fdfbea 100644 --- a/week-1-project/app.js +++ b/week-1-project/app.js @@ -34,7 +34,7 @@ const object = { // write me! }, sumOfNumbery: function () { - // write me! + // write me! (using a Array.prototype.reduce()) }, sumOfNaNy: function () { // write me! From 675bc3f447b7fb9e5a62d661359bcb105f4e7b29 Mon Sep 17 00:00:00 2001 From: Anthony Meirlaen Date: Sat, 2 Nov 2019 17:14:22 +0100 Subject: [PATCH 05/12] add link to javascript info --- week-2-project/practice-problems/objects.js | 1 + 1 file changed, 1 insertion(+) diff --git a/week-2-project/practice-problems/objects.js b/week-2-project/practice-problems/objects.js index 003bc42..8197434 100644 --- a/week-2-project/practice-problems/objects.js +++ b/week-2-project/practice-problems/objects.js @@ -1,5 +1,6 @@ // https://medium.com/@naveenkarippai/learning-how-references-work-in-javascript-a066a4e15600 // https://www.youtube.com/watch?v=Z_ozyN5MyWY&list=PLzV58Zm8FuBJFfQN5il3ujx6FDAY8Ds3u&index=5 +// http://javascript.info/object { const pageTitle = 'objects'; From e2c0d68644c0385f77c08b6c5c6c701d9c2576d3 Mon Sep 17 00:00:00 2001 From: colevandersWands <18554853+colevandersWands@users.noreply.github.com> Date: Tue, 5 Nov 2019 12:40:35 +0100 Subject: [PATCH 06/12] week-3-project --- week-2-project/practice-problems/index.html | 3 +- week-2-project/practice-problems/objects.js | 14 +- week-3-project/README.md | 80 +++++-- week-3-project/app.js | 68 +----- .../error-based-decisions.js | 124 +++++++++++ .../practice-problems/getters-and-setters.js | 206 +++++++++++++++++- week-3-project/practice-problems/index.html | 1 + week-3-project/tests/add-entry.js | 4 +- week-3-project/tests/find-by-key.js | 4 +- week-3-project/tests/get-current-entry.js | 14 ++ week-3-project/tests/remove-entry.js | 4 +- week-3-project/tests/update-entry.js | 4 +- .../user-interface/handlers/favoriting.js | 23 ++ week-3-project/user-interface/index.html | 104 +++++---- 14 files changed, 509 insertions(+), 144 deletions(-) create mode 100644 week-3-project/practice-problems/error-based-decisions.js create mode 100644 week-3-project/user-interface/handlers/favoriting.js diff --git a/week-2-project/practice-problems/index.html b/week-2-project/practice-problems/index.html index 3b4bfc6..eac62b2 100644 --- a/week-2-project/practice-problems/index.html +++ b/week-2-project/practice-problems/index.html @@ -22,8 +22,7 @@ - - +
diff --git a/week-2-project/practice-problems/objects.js b/week-2-project/practice-problems/objects.js index 003bc42..ba31984 100644 --- a/week-2-project/practice-problems/objects.js +++ b/week-2-project/practice-problems/objects.js @@ -114,22 +114,22 @@ try { function passTheAssertions1() { - ; // declare and assign a1 - ; // declare and assign a2 + const a1 = {}; // declare and assign a1 + const a2 = a1; // declare and assign a2 console.assert(a1 === a2, 'a1 should strictly equal a2'); - ; // declare and assign b1 - ; // declare and assign b2 + const b1 = {}; // declare and assign b1 + const b2 = {}; // declare and assign b2 console.assert(b1 !== b2, 'b1 should not strictly equal b2'); // --- - ; // write one line to pass the assertions + a1.x = 'hi!'; // write one line to pass the assertions console.assert(a1.x === a2.x, 'a1.x should strictly equal a2.x'); console.assert(a1.x === 'hi!', 'a1.x should strictly equal "hi!"'); - ; // write two lines to pass the assertions - ; + b1.x = 'bye!'; // write two lines to pass the assertions + b2.x = 'bye!'; console.assert(b1.x === b2.x, 'b1.x should strictly equal b2.x'); console.assert(b1.x === 'bye!', 'b1.x should strictly equal "bye!"'); diff --git a/week-3-project/README.md b/week-3-project/README.md index 4591553..6850231 100644 --- a/week-3-project/README.md +++ b/week-3-project/README.md @@ -1,19 +1,61 @@ -practice problems -- -- -- -- - -app object -- -- -- -- -- - -user interface -- -- -- -- -- + +## Week 3 Project + + + +This project builds directly from last week's, so the tables below are pretty big but there actually less to build than last week! + + +--- + + + +### Core Object + + + +> this table is written like documentation + + + + +| __it should ...__ | __syntax__ | __parameters__ | __return value__ | __description__ | +| --- | --- | --- | --- | --- | +| _... set the the current key_| ```obj.currentEntry = key;``` | _key_: a string | ```true``` if the key is valid, otherwise throws an error | this setter will save the ```key``` as the currentKey if it is a string, and if ```this.entries``` has that key. otherwise it throws a helpful error | +| _... get the the current entry_| ```const entry = obj.currentEntry;``` | (none) | an object with one property: ```{key:value}```. key is the currentKey, and value is the value in ```this.entries``` or a helpful error | this getter allows you to always have access to an up-to-date value for ```this.currentKey```. If a user deletes that entry but doesn't reset the ```currentEntry```, no problem! | +| _... get an object with all the liked entries_| ```const likedEntries = obj.likedEntries``` | (none) | an Object with all liked entries | this getter will return an object with all the entries in ```this.entries``` matching the keys in ```this.likedKeys```. If an entry has been removed, the return value will have a helpful error | +| _... like entries_| ```obj.likeEntry(key)``` | _key_: a string | ```true``` if the key is valid, otherwise returns an error | it will push the key into ```this.likedKeys``` if it is valid, otherwise returns an error | +| _... unlike entries_| ```obj.unlikeEntry(key)``` | _key_: a string | ```true``` if the key is valid and already liked, otherwise returns an error | if the key is valid, and is in ```this.likedEntries``` it will be removed from the array. otherwise a helpful error is returned | +| _... determines if values are primitive or not_ | ```obj.isPrimitive(value)``` | _value_: any JS value | Boolean | It returns ```true``` if the argument is a primitive, otherwise it returns ```false```. | +| _... determines if an object has a given key_ | ```obj.hasKey(obj, key)``` | _obj_: an object
_key_: a string | Boolean | It returns ```true``` if the object has the given key, otherwise it returns ```false```. | +| _... determines if an object has a given value_ | ```obj.hasValue(obj, value)``` | _obj_: an object
_value_: any JS type | Boolean | It returns ```true``` if any key in the object stores this value, otherwise it returns ```false```. | +| _... adds key/value pairs to ```this.entries```_ | ```obj.addEntry(key, value)``` | _key_: a string
_value_: any primitive value | ```true``` or an error | It returns ```true``` if the key/value pair was successfully added, otherwise it returns helpful error describing what went wrong. | +| _... removes a key/value pair from ```this.entries```_ | ```obj.removeEntry(key)``` | _key_: a string | ```true``` or an error | It returns ```true``` if the key/value pair was successfully removed, otherwise it returns helpful error describing what went wrong. | +| _... updates a key/value pair in ```this.entries```_ | ```obj.updateEntry(key, value)``` | _key_: a string
_value_: any primitive type | ```true``` or an error | It returns ```true``` if the key/value pair was successfully updated, otherwise it returns helpful error describing what went wrong. | +| _... returns all key/value pairs in ```this.entries```_ | ```obj.readAll()``` | (no parameters) | an object | a new object with the same key/value pairs as ```this.entries``` | +| _... finds an entry by key_ | ```obj.findByKey(key)``` | _key_: a string | an object or an error | It returns an object with the given key, and it's value in ```this.entries```. Or a helpful error | +| _... finds an entry by value | ```obj.findByValue(value)``` | _value_: a primitive | an object or an error | It returns an object with all key/value pairs in ```this.entries``` containing the given value. Or a helpful error | + + + +--- + + + +### User Interface + + + +> this table is written as user stories. notice that users can't set or get the current entry! + + + +| __As a/n__ ... | __I can__ ... | __so that__ ... | +| --- | --- | --- | +| _... user_ | ... remember which entries were most interesting | ... I can study more effectively over long periods of time | +| _... enthusiastic JS student_ | ... know what this site does and how to use it | ... I can use it to organize my favorite primitive values | +| _... enthusiastic JS student_ | ... set input new keys and primitive values | ... I can practice always being aware of what types _and_ values my application stores | +| _... enthusiastic JS student_ | ... select a method to call with my inputs | ... modify the values stored in this app, and search for particular entries | +| _... enthusiastic JS student_ | ... see the values stored in ```this.entries``` rendered to the DOM | ... I can easily know what is stored in the app without console.logging | +| _... HYF coach_ | ... resize the browser window | ... I can test your responsive design | +| _... HYF coach_ | ... inspect the web page | ... I can see if you correctly used HTML5 semantic elements, CSS classes, and generally wrote clean code | diff --git a/week-3-project/app.js b/week-3-project/app.js index 4320ac7..b4fe84f 100644 --- a/week-3-project/app.js +++ b/week-3-project/app.js @@ -1,12 +1,10 @@ - - const object = { currentKey: '', set currentEntry(key) { - if (null) { // write this early return condition! + if (null) { // write the early return condition throw new TypeError('set currentEntry: key should be a string'); } - if (null) { // write this early return condition! (using this.hasKey) + if (null) { // write the early return condition throw new ReferenceError(`set currentEntry: no entry with key "${key}"`); } @@ -14,43 +12,35 @@ const object = { }, get currentEntry() { // write me! - // consider using this.findByKey & this.currentKey }, likedKeys: [], get likedEntries() { + // write me! - // consider using .map & this.findByKey, then .reduce & Object.assign - // this can be done in two steps: - // first, build an array of all the liked entries (this.findByKey) - // second, build a single object containing all of the liked entries }, likeEntry: function (key) { - if (null) { // write this early-return condition! + if (null) { // write the early return condition return new TypeError('likeEntry: key should be a string'); } - if (null) { // write this early-return condition! (using this.hasKey) + if (null) { // write the early return condition return new ReferenceError(`likeEntry: key "${key}" has been removed`); } - if (null) { // write this early-return condition! (using .every()) + if (null) { // write the early return condition return new Error(`likeEntry: key "${key}" is already liked`); } // write me! }, unlikeEntry: function (key) { - if (null) { // write this early-return condition! + if (null) { // write the early return condition return new TypeError('unlikeEntry: key should be a string'); } - if (null) { // write this early-return condition! (using .every()) + if (null) { // write the early return condition return new Error(`unlikeEntry: key "${key}" is not in this.likedKeys`); } // write me! - // consider using .filter }, - - // everything below here is the same as last week's project - // this week's project will build on top of last week's entries: {}, isPrimitive: function (value) { // write me! @@ -62,62 +52,22 @@ const object = { // write me! }, addEntry: function (key, value) { - if (null) { // write me! - return new TypeError('addEntry: key should be a string'); - } - if (null) { // write me! (using this.isPrimitive) - return new TypeError('addEntry: value should be a primitive'); - } - if (null) { // write me! (using this.hasKey) - return { [key]: new Error(`addEntry: key "${key}" already exists`) }; - } - // write me! }, removeEntry: function (key) { - if (null) { // write me! - return new TypeError('removeEntry: key should be a string'); - } - if (null) { // write me! (using this.hasKey) - return { [key]: new ReferenceError(`removeEntry: no property "${key}" in this.entries`) }; - } - // write me! }, updateEntry: function (key, value) { - if (null) { // write me! - return new TypeError('updateEntry: key should be a string'); - } - if (null) { // write me! (using this.isPrimitive) - return new TypeError('updateEntry: value should be a primitive'); - } - if (null) { // write me! (using this.hasKey) - return { [key]: new ReferenceError(`updateEntry: no property "${key}" in this.entries`) }; - } - // write me! }, readAll: function () { // write me! }, findByKey: function (key) { - if (null) { // write me! - return new TypeError('findByKey: key should be a string'); - } - if (null) { // write me! (using this.hasKey) - return { [key]: new ReferenceError(`findByKey: no property "${key}" in this.entries`) }; - } - // write me! }, findByValue: function (value) { - if (null) { // write me! (using this.isPrimitive) - return new TypeError('findByValue: value should be a primitive'); - } - if (null) { // write me! (using this.hasValue) - return new ReferenceError(`findByValue: no entry with value (${typeof value}, ${value})`); - } - // write me! }, } + diff --git a/week-3-project/practice-problems/error-based-decisions.js b/week-3-project/practice-problems/error-based-decisions.js new file mode 100644 index 0000000..f0b2f66 --- /dev/null +++ b/week-3-project/practice-problems/error-based-decisions.js @@ -0,0 +1,124 @@ +{ + const pageTitle = 'error-based decisions'; + const header = document.createElement("h2"); + header.innerHTML = pageTitle; + document.body.appendChild(header); + console.groupCollapsed(pageTitle); +} + +try { + + + /* this function is meant to be confusing, no need to understand it! + the point of these exercises is to learn how to work with functions that return errors + you can (and often will!) have to work with functions that return errors + ... without understanding what they do! + */ + const mightReturnAnError = a => "object" == typeof a + ? a instanceof Object + ? (() => { try { return a(), !0 } catch (a) { return new Error('second error') } })() + : new Error('first error') + : +a === +a || new Error('third error'); + + + const exercise1Tests = [ + { name: 'first', args: [-5], expected: true }, + { name: 'second', args: [null], expected: false }, + { name: 'third', args: [undefined], expected: false }, + { name: 'fourth', args: [true], expected: true }, + { name: 'fifth', args: [['second error']], expected: false }, + { name: 'sixth', args: [{ a: 'x' }], expected: false }, + { name: 'seventh', args: [() => { }], expected: false }, + { name: 'eighth', args: ['13'], expected: true }, + { name: 'ninth', args: ['second error'], expected: false }, + ] + function exercise1(arg) { + const result = mightReturnAnError(arg); + + if (null) { // write this condition + // write me! + } else { + // write me! + } + + } + exercise1.display = true; + evaluate(exercise1, exercise1Tests); + + + const exercise2Tests = [ + { name: 'first', args: [4], expected: 4 }, + { name: 'second', args: [null], expected: 'first error' }, + { name: 'third', args: [undefined], expected: 'third error' }, + { name: 'fourth', args: [false], expected: false }, + { name: 'fifth', args: [[]], expected: 'second error' }, + { name: 'sixth', args: [{}], expected: 'second error' }, + { name: 'seventh', args: [function () { }], expected: 'third error' }, + { name: 'eighth', args: ['4'], expected: '4' }, + { name: 'ninth', args: ['e'], expected: 'third error' }, + ] + function exercise2(arg) { + const result = mightReturnAnError(arg); + + // write me! + + } + exercise2.display = true; + evaluate(exercise2, exercise2Tests); + + + + const exercise3Tests = [ + { name: 'first', args: [4], expected: { number: 4 } }, + { name: 'second', args: [null], expected: { object: 'first error' } }, + { name: 'third', args: [undefined], expected: { 'undefined': 'third error' } }, + { name: 'fourth', args: [false], expected: { 'boolean': false } }, + { name: 'fifth', args: [[]], expected: { object: 'second error' } }, + { name: 'sixth', args: [{}], expected: { object: 'second error' } }, + { name: 'seventh', args: [function () { }], expected: { 'function': 'third error' } }, + { name: 'eighth', args: ['4'], expected: { string: '4' } }, + { name: 'ninth', args: ['e'], expected: { string: 'third error' } }, + ] + function exercise3(arg) { + const result = mightReturnAnError(arg); + + // write me! + + } + exercise3.display = true; + evaluate(exercise3, exercise3Tests); + + + const exercise4Tests = [ + { name: 'first', args: [4], expected: [null, 4] }, + { name: 'second', args: [null], expected: ['first error'] }, + { name: 'third', args: [undefined], expected: ['third error'] }, + { name: 'fourth', args: [false], expected: [null, false] }, + { name: 'fifth', args: [[]], expected: ['second error'] }, + { name: 'sixth', args: [{}], expected: ['second error'] }, + { name: 'seventh', args: [function () { }], expected: ['third error'] }, + { name: 'eighth', args: ['4'], expected: [null, '4'] }, + { name: 'ninth', args: ['e'], expected: ['third error'] }, + ] + function exercise4(arg) { + const result = mightReturnAnError(arg); + + // write me! + + } + exercise4.display = true; + evaluate(exercise4, exercise4Tests); + + + +} catch (err) { + console.log(err); + document.body.appendChild( + evaluate.errorSearchComponent('.js file', err) + ); +} + +{ + console.groupEnd(); + document.body.appendChild(document.createElement('hr')); +} diff --git a/week-3-project/practice-problems/getters-and-setters.js b/week-3-project/practice-problems/getters-and-setters.js index 68671d0..c5f2609 100644 --- a/week-3-project/practice-problems/getters-and-setters.js +++ b/week-3-project/practice-problems/getters-and-setters.js @@ -15,7 +15,7 @@ try { - function example_refactorMethodToGetter() { + function getterRefactor1() { const obj1 = { name: 'obj1', @@ -24,27 +24,211 @@ try { } } - console.assert(obj1.getGreeting() === `hi, I'm obj1`, 'assert 1'); - obj1.name = 'brussels' - console.assert(obj1.getGreeting() === `hi, I'm brussels`, 'assert 2'); - const obj2 = { name: 'obj2', get greeting() { - return `hi, I'm ${this.name}`; + // write me! } } - console.assert(obj2.greeting === `hi, I'm obj2`, 'assert 3'); - obj2.name = 'belgium' - console.assert(obj2.greeting === `hi, I'm belgium`, 'assert 4'); + const obj1Greeting1 = obj1.getGreeting(); + console.assert(obj1Greeting1 === `hi, I'm obj1`, `obj1's greeting is correct (1)`); + + const obj2Greeting1 = null; // fix this line! + console.assert(obj2Greeting1 === `hi, I'm obj2`, `obj2's greeting is correct (1)`); + + obj1.name = "first"; + obj2.name = "second"; + + const obj1Greeting2 = obj1.getGreeting(); + console.assert(obj1Greeting2 === `hi, I'm first`, `obj1's greeting is correct (2)`); + + const obj2Greeting2 = null; // fix this line! + console.assert(obj2Greeting2 === `hi, I'm second`, `obj2's greeting is correct (2)`); + + } + getterRefactor1.display = true; + evaluate(getterRefactor1); + + + function getterRefactor2() { + + const obj1 = { + numbers: [12, 4, 9, 36, 7, 0, -2], + modulo: 3, + getZeroMods: function () { + return this.numbers.filter(x => x % this.modulo === 0); + } + } + + const obj2 = { + numbers: [12, 4, 9, 36, 7, 0, -2], + modulo: 3, + get zeroMods() { + // write me! + } + } + + const obj1mods3 = null; + console.assert(obj1mods3[0] === 12, 'assert 1'); + console.assert(obj1mods3[1] === 9, 'assert 2'); + console.assert(obj1mods3[2] === 36, 'assert 3'); + + const obj2mods3 = null; + console.assert(obj2mods3[0] === 12, 'assert 4'); + console.assert(obj2mods3[1] === 9, 'assert 5'); + console.assert(obj2mods3[2] === 36, 'assert 6'); + + + obj1.modulo = 6; + obj2.modulo = 6; + + const obj1mods3second = null; + console.assert(obj1mods3second[0] === 12, 'assert 7'); + console.assert(obj1mods3second[1] === 36, 'assert 8'); + + const obj2mods3second = null; + console.assert(obj2mods3second[0] === 12, 'assert 9'); + console.assert(obj2mods3second[1] === 36, 'assert 10'); + + } + getterRefactor2.display = true; + evaluate(getterRefactor2); + + + function getterRefactor3() { + + const obj1 = { + entries: { first: 'hi!', second: 'bye!' }, + currentKey: 'second', + getCurrentEntry: function () { + return this.entries[this.currentKey]; + } + } + + const obj2 = { + entries: { first: 'hi!', second: 'bye!' }, + currentKey: 'second', + get currentEntry() { + // write me! + } + } + + // replace the null's to pass the asserts: + + const obj1current1 = null; + console.assert(obj1current1 === 'bye!', 'assert 1'); + + const obj2current1 = null; + console.assert(obj2current1 === 'bye!', 'assert 2'); + + obj1.currentKey = null; + obj2.currentKey = null; + + const obj1current2 = null; + console.assert(obj1current2 === 'hi!', 'assert 3'); + + const obj2current2 = null; + console.assert(obj2current2 === 'hi!', 'assert 4'); } - evaluate(example_refactorMethodToGetter); + getterRefactor3.display = true; + evaluate(getterRefactor3); + + + + function setterRefactor1() { + + const obj1 = { + greeting: ``, + setGreetingName: function (newName) { + this.greeting = `hi, I'm ${newName}!`; + } + }; + + const obj2 = { + greeting: ``, + set greetingName(newName) { + // write me! + } + }; + + obj1.setGreetingName('obj1'); + console.assert(obj1.greeting === "hi, I'm obj1!", 'assert 1'); + + ; // write me! + console.assert(obj2.greeting === "hi, I'm obj2!", 'assert 2'); + + obj1.setGreetingName('hi'); + console.assert(obj1.greeting === "hi, I'm hi!", 'assert 3'); + + ; // write me! + console.assert(obj2.greeting === "hi, I'm bye!", 'assert 4'); + + } + setterRefactor1.display = true; + evaluate(setterRefactor1); + + + function setterRefactor2() { + + + + } + setterRefactor2.display = true; + evaluate(setterRefactor2); + + + function setterRefactor3() { + + const obj1 = { + entries: { first: 'hi!', second: 'bye!' }, + current: {}, + setCurrentEntry: function (key) { + if (this.entries.hasOwnProperty(key)) { + this.current = { [key]: this.entries[key] }; + } else { + this.current = { [key]: new Error(`no entry with key "${key}"`) } + } + } + } + + const obj2 = { + entries: { first: 'hi!', second: 'bye!' }, + current: {}, + // write me! + } + + obj1.setCurrentEntry('second'); + console.assert(obj1.current.second === "bye!", 'assert 1'); + + ; // write me! + console.assert(obj2.current.second === "bye!", 'assert 2'); + + + obj1.setCurrentEntry('first'); + console.assert(obj1.current.first === "hi!", 'assert 3'); + console.assert(obj1.current.hasOwnProperty('second') === false, 'assert 4'); + + ; // write me! + console.assert(obj2.current.first === "hi!", 'assert 5'); + console.assert(obj2.current.hasOwnProperty('second') === false, 'assert 6'); + + + obj1.setCurrentEntry('hi'); + console.assert(obj1.current.hi.message === 'no entry with key "hi"', 'assert 7'); + console.assert(obj1.current.hasOwnProperty('first') === false, 'assert 8'); + + ; // write me! + console.assert(obj2.current.hi.message === 'no entry with key "hi"', 'assert 9'); + console.assert(obj2.current.hasOwnProperty('first') === false, 'assert 10'); + + } + setterRefactor3.display = true; + evaluate(setterRefactor3); - // more coming soon } catch (err) { console.log(err); diff --git a/week-3-project/practice-problems/index.html b/week-3-project/practice-problems/index.html index 5e3f15a..5831ef6 100644 --- a/week-3-project/practice-problems/index.html +++ b/week-3-project/practice-problems/index.html @@ -24,6 +24,7 @@ +
diff --git a/week-3-project/tests/add-entry.js b/week-3-project/tests/add-entry.js index 47914e6..a0987f7 100644 --- a/week-3-project/tests/add-entry.js +++ b/week-3-project/tests/add-entry.js @@ -30,8 +30,8 @@ describe(`addEntry: should add a new key/value pair to this.entries`, () => { ['firstKey', 'secondKey', 'thirdKey', 'fourthKey'].forEach(arg => { it(`${arg}`, () => { const result = object.addEntry(arg, ''); - assert.ok(result[arg] instanceof Error); - assert.strictEqual(result[arg].message, `addEntry: key "${arg}" already exists`); + assert.ok(result instanceof Error); + assert.strictEqual(result.message, `addEntry: key "${arg}" already exists`); }); }); }); diff --git a/week-3-project/tests/find-by-key.js b/week-3-project/tests/find-by-key.js index b0600d4..beb14ec 100644 --- a/week-3-project/tests/find-by-key.js +++ b/week-3-project/tests/find-by-key.js @@ -21,8 +21,8 @@ describe(`findByKey: returns the requested key/value pair, or an informative err ['a', 'b', 'c', 'd'].forEach(arg => { it(`${arg}`, () => { const result = object.findByKey(arg); - assert.ok(result[arg] instanceof ReferenceError); - assert.strictEqual(result[arg].message, `findByKey: no property "${arg}" in this.entries`); + assert.ok(result instanceof ReferenceError); + assert.strictEqual(result.message, `findByKey: no property "${arg}" in this.entries`); }); }); }); diff --git a/week-3-project/tests/get-current-entry.js b/week-3-project/tests/get-current-entry.js index 0c9d0ca..ca8f218 100644 --- a/week-3-project/tests/get-current-entry.js +++ b/week-3-project/tests/get-current-entry.js @@ -21,4 +21,18 @@ describe(`get currentEntry: get the value of this.currentKey if the argument is }); }); }); + describe(`if the current entry has been removed, return the key with it's error`, () => { + [ + 'firstKey', + 'secondKey', + 'thirdKey', + 'fourthKey', + ].forEach(key => { + it(`${key}`, () => { + delete object.entries[key]; + object.currentKey = key; + assert.deepStrictEqual(object.currentEntry[key].message, `findByKey: no property "${key}" in this.entries`); + }); + }); + }); }); diff --git a/week-3-project/tests/remove-entry.js b/week-3-project/tests/remove-entry.js index 17e22c5..3b02792 100644 --- a/week-3-project/tests/remove-entry.js +++ b/week-3-project/tests/remove-entry.js @@ -21,8 +21,8 @@ describe(`removeEntry: should remove a key/value pair from this.entries`, () => ['tomato', 'potato', 'patate', 'pomme de terre'].forEach(arg => { it(`${arg}`, () => { const result = object.removeEntry(arg); - assert.ok(result[arg] instanceof Error); - assert.strictEqual(result[arg].message, `removeEntry: no property "${arg}" in this.entries`); + assert.ok(result instanceof Error); + assert.strictEqual(result.message, `removeEntry: no property "${arg}" in this.entries`); }); }); }); diff --git a/week-3-project/tests/update-entry.js b/week-3-project/tests/update-entry.js index fd9870f..f670fa0 100644 --- a/week-3-project/tests/update-entry.js +++ b/week-3-project/tests/update-entry.js @@ -30,8 +30,8 @@ describe(`updateEntry: should add a new key/value pair to this.entries`, () => { ['tomato', 'potato', 'patate', 'pomme'].forEach(arg => { it(`${arg}`, () => { const result = object.updateEntry(arg, ''); - assert.ok(result[arg] instanceof ReferenceError); - assert.strictEqual(result[arg].message, `updateEntry: no property "${arg}" in this.entries`); + assert.ok(result instanceof ReferenceError); + assert.strictEqual(result.message, `updateEntry: no property "${arg}" in this.entries`); }); }); }); diff --git a/week-3-project/user-interface/handlers/favoriting.js b/week-3-project/user-interface/handlers/favoriting.js new file mode 100644 index 0000000..cd52854 --- /dev/null +++ b/week-3-project/user-interface/handlers/favoriting.js @@ -0,0 +1,23 @@ +function addStringHandler() { + + // read and process user input + + /* write the code to read the string input from the user */ + const key = null; // <------------- + const prop = null; // <------------- + + // pass user input through core logic (this works! no need to change it) + const result = typeof obj[prop] === 'function' // <---------------- + ? obj[prop](key) + : obj[prop] + + // report result to user (this works, no need to change it!) + // <--------------- + + // logs for developer + console.log('\n--- addStringHandler ---'); + console.log('stringToAdd:', typeof stringToAdd, ',', stringToAdd); + console.log('isNumbery:', typeof isNumbery, ',', isNumbery); + +}; +// connect this to it's button with an event listener! <---------- diff --git a/week-3-project/user-interface/index.html b/week-3-project/user-interface/index.html index 0a3d9e1..1b6655b 100644 --- a/week-3-project/user-interface/index.html +++ b/week-3-project/user-interface/index.html @@ -14,54 +14,82 @@ -
-
- key
- -
-
- value
- - -
+
+

CRUDing entries

+
+
+ key
+ +
+
+ value
+ + +
+
+
+
+
+ Which method do you want to call? + + + +
+
+
+
+ +
+
+
+
-
-
-
- Which method do you want to call? - - - -
-
-
-
- + +
+ +
+

favoriting

+
+ +
+
+
+
+ What do you want to do with this key? + + + +
+
+
+
-
-


- +
+ From 79a9c4840aea08e71d6dd8172b84e1e0bb51a4c7 Mon Sep 17 00:00:00 2001 From: colevandersWands <18554853+colevandersWands@users.noreply.github.com> Date: Fri, 8 Nov 2019 16:45:20 +0100 Subject: [PATCH 07/12] week-3-updates --- LICENSE.md | 7 ++++ dependencies/prism/script.js | 9 +++-- dependencies/prism/style.css | 44 +++++++++++++++++++++- dependencies/toString.js | 2 + week-1-project/index.html | 22 ++++++----- week-1-project/practice-problems/arrays.js | 3 +- week-2-project/app.js | 2 + week-2-project/index.html | 22 ++++++----- week-2-project/tests/find-by-value.js | 20 +++++----- week-2-project/tests/has-key.js | 13 ++++++- week-2-project/tests/has-value.js | 11 ++++++ week-2-project/tests/remove-entry.js | 2 +- week-3-project/index.html | 31 ++++++++------- week-3-project/tests/find-by-value.js | 18 ++++++--- week-3-project/tests/has-key.js | 14 ++++++- week-3-project/tests/has-value.js | 11 ++++++ week-3-project/tests/remove-entry.js | 2 +- 17 files changed, 174 insertions(+), 59 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index e69de29..877d652 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -0,0 +1,7 @@ +[![License: CC BY 4.0](https://licensebuttons.net/l/by/4.0/80x15.png)](https://creativecommons.org/licenses/by/4.0/) : 2019 -> Present + +Licensed by Hack Your Future Belgium: @HackYourFutureBelgium, https://hackyourfuture.be, contact@hackyourfuture.be + +___ +___ +### diff --git a/dependencies/prism/script.js b/dependencies/prism/script.js index a8782fb..0ddc38f 100644 --- a/dependencies/prism/script.js +++ b/dependencies/prism/script.js @@ -1,5 +1,6 @@ /* PrismJS 1.17.1 -https://prismjs.com/download.html#themes=prism-okaidia&languages=clike+javascript */ -var _self = "undefined" != typeof window ? window : "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = function (u) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0; var _ = { manual: u.Prism && u.Prism.manual, disableWorkerMessageHandler: u.Prism && u.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof L ? new L(e.type, _.util.encode(e.content), e.alias) : Array.isArray(e) ? e.map(_.util.encode) : e.replace(/&/g, "&").replace(/ e.length) return; if (!(k instanceof L)) { if (h && y != a.length - 1) { if (c.lastIndex = v, !(x = c.exec(e))) break; for (var b = x.index + (f && x[1] ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || !a[A].type && !a[A - 1].greedy); ++A)(P += a[A].length) <= b && (++y, v = P); if (a[y] instanceof L) continue; j = A - y, k = e.slice(v, P), x.index -= v } else { c.lastIndex = 0; var x = c.exec(k), j = 1 } if (x) { f && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var N = k.slice(0, b), S = k.slice(w), C = [y, j]; N && (++y, v += N.length, C.push(N)); var E = new L(l, g ? _.tokenize(x, g) : x, m, x, h); if (C.push(E), S && C.push(S), Array.prototype.splice.apply(a, C), 1 != j && _.matchGrammar(e, a, n, y, v, !0, l + "," + u), i) break } else if (i) break } } } } }, tokenize: function (e, a) { var n = [e], r = a.rest; if (r) { for (var t in r) a[t] = r[t]; delete a.rest } return _.matchGrammar(e, n, a, 0, 0, !1), n }, hooks: { all: {}, add: function (e, a) { var n = _.hooks.all; n[e] = n[e] || [], n[e].push(a) }, run: function (e, a) { var n = _.hooks.all[e]; if (n && n.length) for (var r, t = 0; r = n[t++];)r(a) } }, Token: L }; function L(e, a, n, r, t) { this.type = e, this.content = a, this.alias = n, this.length = 0 | (r || "").length, this.greedy = !!t } if (u.Prism = _, L.stringify = function (e, a) { if ("string" == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return L.stringify(e, a) }).join(""); var n = { type: e.type, content: L.stringify(e.content, a), tag: "span", classes: ["token", e.type], attributes: {}, language: a }; if (e.alias) { var r = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, r) } _.hooks.run("wrap", n); var t = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || "").replace(/"/g, """) + '"' }).join(" "); return "<" + n.tag + ' class="' + n.classes.join(" ") + '"' + (t ? " " + t : "") + ">" + n.content + "" }, !u.document) return u.addEventListener && (_.disableWorkerMessageHandler || u.addEventListener("message", function (e) { var a = JSON.parse(e.data), n = a.language, r = a.code, t = a.immediateClose; u.postMessage(_.highlight(r, _.languages[n], n)), t && u.close() }, !1)), _; var e = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); if (e && (_.filename = e.src, e.hasAttribute("data-manual") && (_.manual = !0)), !_.manual) { function n() { _.manual || _.highlightAll() } "loading" !== document.readyState ? window.requestAnimationFrame ? window.requestAnimationFrame(n) : window.setTimeout(n, 16) : document.addEventListener("DOMContentLoaded", n) } return _ }(_self); "undefined" != typeof module && module.exports && (module.exports = Prism), "undefined" != typeof global && (global.Prism = Prism); -Prism.languages.clike = { comment: [{ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, lookbehind: !0 }, { pattern: /(^|[^\\:])\/\/.*/, lookbehind: !0, greedy: !0 }], string: { pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, greedy: !0 }, "class-name": { pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i, lookbehind: !0, inside: { punctuation: /[.\\]/ } }, keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, boolean: /\b(?:true|false)\b/, function: /\w+(?=\()/, number: /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i, operator: /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, punctuation: /[{}[\];(),.:]/ }; -Prism.languages.javascript = Prism.languages.extend("clike", { "class-name": [Prism.languages.clike["class-name"], { pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/, lookbehind: !0 }], keyword: [{ pattern: /((?:^|})\s*)(?:catch|finally)\b/, lookbehind: !0 }, { pattern: /(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, lookbehind: !0 }], number: /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, function: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, operator: /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|[~?:]/ }), Prism.languages.javascript["class-name"][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/, Prism.languages.insertBefore("javascript", "keyword", { regex: { pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=\s*($|[\r\n,.;})\]]))/, lookbehind: !0, greedy: !0 }, "function-variable": { pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/, alias: "function" }, parameter: [{ pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/, lookbehind: !0, inside: Prism.languages.javascript }, { pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i, inside: Prism.languages.javascript }, { pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/, lookbehind: !0, inside: Prism.languages.javascript }, { pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/, lookbehind: !0, inside: Prism.languages.javascript }], constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/ }), Prism.languages.insertBefore("javascript", "string", { "template-string": { pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/, greedy: !0, inside: { "template-punctuation": { pattern: /^`|`$/, alias: "string" }, interpolation: { pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/, lookbehind: !0, inside: { "interpolation-punctuation": { pattern: /^\${|}$/, alias: "punctuation" }, rest: Prism.languages.javascript } }, string: /[\s\S]+/ } } }), Prism.languages.markup && Prism.languages.markup.tag.addInlined("script", "javascript"), Prism.languages.js = Prism.languages.javascript; +https://prismjs.com/download.html#themes=prism-okaidia&languages=clike+javascript&plugins=line-numbers */ +var _self = "undefined" != typeof window ? window : "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = function (u) { var c = /\blang(?:uage)?-([\w-]+)\b/i, r = 0; var _ = { manual: u.Prism && u.Prism.manual, disableWorkerMessageHandler: u.Prism && u.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof L ? new L(e.type, _.util.encode(e.content), e.alias) : Array.isArray(e) ? e.map(_.util.encode) : e.replace(/&/g, "&").replace(/ e.length) return; if (!(k instanceof L)) { if (d && y != r.length - 1) { if (c.lastIndex = v, !(O = c.exec(e))) break; for (var b = O.index + (f && O[1] ? O[1].length : 0), w = O.index + O[0].length, A = y, P = v, x = r.length; A < x && (P < w || !r[A].type && !r[A - 1].greedy); ++A)(P += r[A].length) <= b && (++y, v = P); if (r[y] instanceof L) continue; S = A - y, k = e.slice(v, P), O.index -= v } else { c.lastIndex = 0; var O = c.exec(k), S = 1 } if (O) { f && (h = O[1] ? O[1].length : 0); w = (b = O.index + h) + (O = O[0].slice(h)).length; var j = k.slice(0, b), N = k.slice(w), E = [y, S]; j && (++y, v += j.length, E.push(j)); var C = new L(l, g ? _.tokenize(O, g) : O, m, O, d); if (E.push(C), N && E.push(N), Array.prototype.splice.apply(r, E), 1 != S && _.matchGrammar(e, r, n, y, v, !0, l + "," + u), i) break } else if (i) break } } } } }, tokenize: function (e, r) { var n = [e], t = r.rest; if (t) { for (var a in t) r[a] = t[a]; delete r.rest } return _.matchGrammar(e, n, r, 0, 0, !1), n }, hooks: { all: {}, add: function (e, r) { var n = _.hooks.all; n[e] = n[e] || [], n[e].push(r) }, run: function (e, r) { var n = _.hooks.all[e]; if (n && n.length) for (var t, a = 0; t = n[a++];)t(r) } }, Token: L }; function L(e, r, n, t, a) { this.type = e, this.content = r, this.alias = n, this.length = 0 | (t || "").length, this.greedy = !!a } if (u.Prism = _, L.stringify = function (e, r) { if ("string" == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return L.stringify(e, r) }).join(""); var n = { type: e.type, content: L.stringify(e.content, r), tag: "span", classes: ["token", e.type], attributes: {}, language: r }; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t) } _.hooks.run("wrap", n); var a = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || "").replace(/"/g, """) + '"' }).join(" "); return "<" + n.tag + ' class="' + n.classes.join(" ") + '"' + (a ? " " + a : "") + ">" + n.content + "" }, !u.document) return u.addEventListener && (_.disableWorkerMessageHandler || u.addEventListener("message", function (e) { var r = JSON.parse(e.data), n = r.language, t = r.code, a = r.immediateClose; u.postMessage(_.highlight(t, _.languages[n], n)), a && u.close() }, !1)), _; var e = _.util.currentScript(); if (e && (_.filename = e.src, e.hasAttribute("data-manual") && (_.manual = !0)), !_.manual) { function n() { _.manual || _.highlightAll() } var t = document.readyState; "loading" === t || "interactive" === t && e && e.defer ? document.addEventListener("DOMContentLoaded", n) : window.requestAnimationFrame ? window.requestAnimationFrame(n) : window.setTimeout(n, 16) } return _ }(_self); "undefined" != typeof module && module.exports && (module.exports = Prism), "undefined" != typeof global && (global.Prism = Prism); +Prism.languages.clike = { comment: [{ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, lookbehind: !0 }, { pattern: /(^|[^\\:])\/\/.*/, lookbehind: !0, greedy: !0 }], string: { pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, greedy: !0 }, "class-name": { pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i, lookbehind: !0, inside: { punctuation: /[.\\]/ } }, keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, boolean: /\b(?:true|false)\b/, function: /\w+(?=\()/, number: /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i, operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, punctuation: /[{}[\];(),.:]/ }; +Prism.languages.javascript = Prism.languages.extend("clike", { "class-name": [Prism.languages.clike["class-name"], { pattern: /(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/, lookbehind: !0 }], keyword: [{ pattern: /((?:^|})\s*)(?:catch|finally)\b/, lookbehind: !0 }, { pattern: /(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, lookbehind: !0 }], number: /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, function: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, operator: /--|\+\+|\*\*=?|=>|&&|\|\||[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?[.?]?|[~:]/ }), Prism.languages.javascript["class-name"][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/, Prism.languages.insertBefore("javascript", "keyword", { regex: { pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=\s*(?:$|[\r\n,.;})\]]))/, lookbehind: !0, greedy: !0 }, "function-variable": { pattern: /#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/, alias: "function" }, parameter: [{ pattern: /(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/, lookbehind: !0, inside: Prism.languages.javascript }, { pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i, inside: Prism.languages.javascript }, { pattern: /(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/, lookbehind: !0, inside: Prism.languages.javascript }, { pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/, lookbehind: !0, inside: Prism.languages.javascript }], constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/ }), Prism.languages.insertBefore("javascript", "string", { "template-string": { pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/, greedy: !0, inside: { "template-punctuation": { pattern: /^`|`$/, alias: "string" }, interpolation: { pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/, lookbehind: !0, inside: { "interpolation-punctuation": { pattern: /^\${|}$/, alias: "punctuation" }, rest: Prism.languages.javascript } }, string: /[\s\S]+/ } } }), Prism.languages.markup && Prism.languages.markup.tag.addInlined("script", "javascript"), Prism.languages.js = Prism.languages.javascript; +!function () { if ("undefined" != typeof self && self.Prism && self.document) { var l = "line-numbers", c = /\n(?!$)/g, m = function (e) { var t = a(e)["white-space"]; if ("pre-wrap" === t || "pre-line" === t) { var n = e.querySelector("code"), r = e.querySelector(".line-numbers-rows"), s = e.querySelector(".line-numbers-sizer"), i = n.textContent.split(c); s || ((s = document.createElement("span")).className = "line-numbers-sizer", n.appendChild(s)), s.style.display = "block", i.forEach(function (e, t) { s.textContent = e || "\n"; var n = s.getBoundingClientRect().height; r.children[t].style.height = n + "px" }), s.textContent = "", s.style.display = "none" } }, a = function (e) { return e ? window.getComputedStyle ? getComputedStyle(e) : e.currentStyle || null : null }; window.addEventListener("resize", function () { Array.prototype.forEach.call(document.querySelectorAll("pre." + l), m) }), Prism.hooks.add("complete", function (e) { if (e.code) { var t = e.element, n = t.parentNode; if (n && /pre/i.test(n.nodeName) && !t.querySelector(".line-numbers-rows")) { for (var r = !1, s = /(?:^|\s)line-numbers(?:\s|$)/, i = t; i; i = i.parentNode)if (s.test(i.className)) { r = !0; break } if (r) { t.className = t.className.replace(s, " "), s.test(n.className) || (n.className += " line-numbers"); var l, a = e.code.match(c), o = a ? a.length + 1 : 1, u = new Array(o + 1).join(""); (l = document.createElement("span")).setAttribute("aria-hidden", "true"), l.className = "line-numbers-rows", l.innerHTML = u, n.hasAttribute("data-start") && (n.style.counterReset = "linenumber " + (parseInt(n.getAttribute("data-start"), 10) - 1)), e.element.appendChild(l), m(n), Prism.hooks.run("line-numbers", e) } } } }), Prism.hooks.add("line-numbers", function (e) { e.plugins = e.plugins || {}, e.plugins.lineNumbers = !0 }), Prism.plugins.lineNumbers = { getLine: function (e, t) { if ("PRE" === e.tagName && e.classList.contains(l)) { var n = e.querySelector(".line-numbers-rows"), r = parseInt(e.getAttribute("data-start"), 10) || 1, s = r + (n.children.length - 1); t < r && (t = r), s < t && (t = s); var i = t - r; return n.children[i] } } } } }(); diff --git a/dependencies/prism/style.css b/dependencies/prism/style.css index af3bbad..cedea10 100644 --- a/dependencies/prism/style.css +++ b/dependencies/prism/style.css @@ -1,5 +1,5 @@ /* PrismJS 1.17.1 -https://prismjs.com/download.html#themes=prism-okaidia&languages=clike+javascript */ +https://prismjs.com/download.html#themes=prism-okaidia&languages=clike+javascript&plugins=line-numbers */ /** * okaidia theme for JavaScript, CSS and HTML * Loosely based on Monokai textmate theme by http://www.monokai.nl/ @@ -124,3 +124,45 @@ pre[class*="language-"] { cursor: help; } +pre[class*="language-"].line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre[class*="language-"].line-numbers > code { + position: relative; + white-space: inherit; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + + .line-numbers-rows > span { + pointer-events: none; + display: block; + counter-increment: linenumber; + } + + .line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } + diff --git a/dependencies/toString.js b/dependencies/toString.js index ea80a88..979392c 100644 --- a/dependencies/toString.js +++ b/dependencies/toString.js @@ -1,3 +1,5 @@ +// ** doesn't do nicely with lots of comments in a method + /* opinionated & lazy formatting assumes double-spaced indentation diff --git a/week-1-project/index.html b/week-1-project/index.html index 3de938b..55a6cd3 100644 --- a/week-1-project/index.html +++ b/week-1-project/index.html @@ -46,18 +46,20 @@

Week 1 Project

diff --git a/week-1-project/practice-problems/arrays.js b/week-1-project/practice-problems/arrays.js index c5add90..9342ce9 100644 --- a/week-1-project/practice-problems/arrays.js +++ b/week-1-project/practice-problems/arrays.js @@ -1,4 +1,4 @@ -// https://www.youtube.com/watch?v=W1NTK09o-vM&list=PLzV58Zm8FuBJFfQN5il3ujx6FDAY8Ds3u&index=4 +// https://www.youtube.com/watch?v=W1NTK09o-vM&list=PLzV58Zm8FuBJFfQN5il3ujx6FDAY8Ds3u&index=4 // https://medium.com/@naveenkarippai/learning-how-references-work-in-javascript-a066a4e15600 { @@ -35,6 +35,7 @@ try { // to create a new array in memory, you must write new square brackets + // (or call an array method that returns a copy, more on that later) const array3 = []; // reassigning object2 will make it point to ... array2 = array3; diff --git a/week-2-project/app.js b/week-2-project/app.js index 1eec39e..90e883b 100644 --- a/week-2-project/app.js +++ b/week-2-project/app.js @@ -43,6 +43,8 @@ const object = { return new ReferenceError(`removeEntry: no property "${key}" in this.entries`); } + delete this.entries[key] + return true // write me! }, updateEntry: function (key, value) { diff --git a/week-2-project/index.html b/week-2-project/index.html index e559c32..f4e68c4 100644 --- a/week-2-project/index.html +++ b/week-2-project/index.html @@ -45,18 +45,20 @@

Week 2 Project

diff --git a/week-2-project/tests/find-by-value.js b/week-2-project/tests/find-by-value.js index 0ae4f3a..457a7af 100644 --- a/week-2-project/tests/find-by-value.js +++ b/week-2-project/tests/find-by-value.js @@ -31,31 +31,31 @@ describe(`findByValue: returns the requested key/value pair, or an informative e }); }); }); - describe(`otherwise returns an object containing the requested key/value pairs`, () => { + describe(`otherwise returns an object containing the requested key/value pair`, () => { [ ['firstValue', { firstKey: 'firstValue' }], ['secondValue', { secondKey: 'secondValue' }], ['thirdValue', { thirdKey: 'thirdValue' }], ].forEach(arg => { - it(`it finds the correct key for ${arg[0]}`, () => { + it(`it returns the correct entry for value : ${arg[0]}`, () => { const result = object.findByValue(arg[0]); assert.deepStrictEqual(result, arg[1]); }); }); - it(`it finds all keys containing "fourthValue"`, () => { + it(`it finds all keys containing "fourthValue ... "`, () => { const result = object.findByValue('fourthValue'); assert.deepStrictEqual(result, { - fourthKey: 'fourthValue', - fifthKey: 'fourthValue', - sixthKey: 'fourthValue' + 'fourthKey': 'fourthValue', + 'fifthKey': 'fourthValue', + 'sixthKey': 'fourthValue' }); }); - it(`and all keys containing "fifthValue"`, () => { + it(`... and all keys containing "fifthValue"`, () => { const result = object.findByValue('fifthValue'); assert.deepStrictEqual(result, { - seventhKey: 'fifthValue', - eighthKey: 'fifthValue', - ninthKey: 'fifthValue' + 'seventhKey': 'fifthValue', + 'eighthKey': 'fifthValue', + 'ninthKey': 'fifthValue' }); }); }); diff --git a/week-2-project/tests/has-key.js b/week-2-project/tests/has-key.js index 7388df3..62184f1 100644 --- a/week-2-project/tests/has-key.js +++ b/week-2-project/tests/has-key.js @@ -35,7 +35,18 @@ describe(`hasKey: determines if an object has a given key`, () => { }); }); describe(`and returns false for non-existant entries.`, () => { - ['entries', 'hasKey', 'toSource', 'valueOf', 'hasOwnProperty'].forEach(arg => { + ['entries', 'hasKey', 'toSource', 'valueOf', 'hasOwnProperty', ''].forEach(arg => { + it(arg, () => { + const result = object.hasKey(object.entries, arg); + assert.strictEqual(result, false); + }); + }); + }); + describe(`or when there are no entries!`, () => { + before(() => { + object.entries = {}; + }); + ['entries', 'hasKey', 'toSource', 'valueOf', 'hasOwnProperty', ''].forEach(arg => { it(arg, () => { const result = object.hasKey(object.entries, arg); assert.strictEqual(result, false); diff --git a/week-2-project/tests/has-value.js b/week-2-project/tests/has-value.js index 8e9c4fa..beb3f29 100644 --- a/week-2-project/tests/has-value.js +++ b/week-2-project/tests/has-value.js @@ -42,4 +42,15 @@ describe(`hasValue: determines if an object has a given value`, () => { }); }); }); + describe(`even when there are no entries!`, () => { + before(() => { + object.entries = {}; + }); + ['tomato', null, true, undefined, 4].forEach(arg => { + it(arg, () => { + const result = object.hasValue(object.entries, arg); + assert.strictEqual(result, false); + }); + }); + }); }); diff --git a/week-2-project/tests/remove-entry.js b/week-2-project/tests/remove-entry.js index 3b02792..f3b310f 100644 --- a/week-2-project/tests/remove-entry.js +++ b/week-2-project/tests/remove-entry.js @@ -38,7 +38,7 @@ describe(`removeEntry: should remove a key/value pair from this.entries`, () => describe(`... and actually removes the entries!`, () => { valuesToRemove.forEach(arg => { it(`object.hasKey(object.entries, ${arg}) === false`, () => { - assert.strictEqual(object.hasKey(object.entries, arg), false); + assert.strictEqual(this.entries.hasOwnProperty(arg), false); }); }); }); diff --git a/week-3-project/index.html b/week-3-project/index.html index 3105d68..344e85a 100644 --- a/week-3-project/index.html +++ b/week-3-project/index.html @@ -18,10 +18,10 @@ - + - + @@ -30,7 +30,7 @@
-

Week 2 Project

+

Week 3 Project

@@ -42,21 +42,24 @@

Week 2 Project

-
+
diff --git a/week-3-project/tests/find-by-value.js b/week-3-project/tests/find-by-value.js index 5042fcc..457a7af 100644 --- a/week-3-project/tests/find-by-value.js +++ b/week-3-project/tests/find-by-value.js @@ -37,18 +37,26 @@ describe(`findByValue: returns the requested key/value pair, or an informative e ['secondValue', { secondKey: 'secondValue' }], ['thirdValue', { thirdKey: 'thirdValue' }], ].forEach(arg => { - it(`it finds the correct key for ${arg[0]}`, () => { + it(`it returns the correct entry for value : ${arg[0]}`, () => { const result = object.findByValue(arg[0]); assert.deepStrictEqual(result, arg[1]); }); }); - it(`it finds all keys containing "fourthValue"`, () => { + it(`it finds all keys containing "fourthValue ... "`, () => { const result = object.findByValue('fourthValue'); - assert.deepStrictEqual(Object.keys(result), ['fourthKey', 'fifthKey', 'sixthKey']); + assert.deepStrictEqual(result, { + 'fourthKey': 'fourthValue', + 'fifthKey': 'fourthValue', + 'sixthKey': 'fourthValue' + }); }); - it(`and all keys containing "fifthValue"`, () => { + it(`... and all keys containing "fifthValue"`, () => { const result = object.findByValue('fifthValue'); - assert.deepStrictEqual(Object.keys(result), ['seventhKey', 'eighthKey', 'ninthKey']); + assert.deepStrictEqual(result, { + 'seventhKey': 'fifthValue', + 'eighthKey': 'fifthValue', + 'ninthKey': 'fifthValue' + }); }); }); }); diff --git a/week-3-project/tests/has-key.js b/week-3-project/tests/has-key.js index 7388df3..ff26be3 100644 --- a/week-3-project/tests/has-key.js +++ b/week-3-project/tests/has-key.js @@ -35,7 +35,19 @@ describe(`hasKey: determines if an object has a given key`, () => { }); }); describe(`and returns false for non-existant entries.`, () => { - ['entries', 'hasKey', 'toSource', 'valueOf', 'hasOwnProperty'].forEach(arg => { + ['entries', 'hasKey', 'toSource', 'valueOf', 'hasOwnProperty', ''].forEach(arg => { + it(arg, () => { + const result = object.hasKey(object.entries, arg); + console.log(result) + assert.strictEqual(result, false); + }); + }); + }); + describe(`or when there are no entries!`, () => { + before(() => { + object.entries = {}; + }); + ['entries', 'hasKey', 'toSource', 'valueOf', 'hasOwnProperty', ''].forEach(arg => { it(arg, () => { const result = object.hasKey(object.entries, arg); assert.strictEqual(result, false); diff --git a/week-3-project/tests/has-value.js b/week-3-project/tests/has-value.js index 8e9c4fa..beb3f29 100644 --- a/week-3-project/tests/has-value.js +++ b/week-3-project/tests/has-value.js @@ -42,4 +42,15 @@ describe(`hasValue: determines if an object has a given value`, () => { }); }); }); + describe(`even when there are no entries!`, () => { + before(() => { + object.entries = {}; + }); + ['tomato', null, true, undefined, 4].forEach(arg => { + it(arg, () => { + const result = object.hasValue(object.entries, arg); + assert.strictEqual(result, false); + }); + }); + }); }); diff --git a/week-3-project/tests/remove-entry.js b/week-3-project/tests/remove-entry.js index 3b02792..f3b310f 100644 --- a/week-3-project/tests/remove-entry.js +++ b/week-3-project/tests/remove-entry.js @@ -38,7 +38,7 @@ describe(`removeEntry: should remove a key/value pair from this.entries`, () => describe(`... and actually removes the entries!`, () => { valuesToRemove.forEach(arg => { it(`object.hasKey(object.entries, ${arg}) === false`, () => { - assert.strictEqual(object.hasKey(object.entries, arg), false); + assert.strictEqual(this.entries.hasOwnProperty(arg), false); }); }); }); From 2867d4ec328ea95ab91646c4047fba90fdd300e7 Mon Sep 17 00:00:00 2001 From: Evan Cole <18554853+colevandersWands@users.noreply.github.com> Date: Sat, 9 Nov 2019 11:41:12 +0100 Subject: [PATCH 08/12] cast description to string --- week-2-project/tests/has-value.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/week-2-project/tests/has-value.js b/week-2-project/tests/has-value.js index beb3f29..b86416e 100644 --- a/week-2-project/tests/has-value.js +++ b/week-2-project/tests/has-value.js @@ -47,7 +47,8 @@ describe(`hasValue: determines if an object has a given value`, () => { object.entries = {}; }); ['tomato', null, true, undefined, 4].forEach(arg => { - it(arg, () => { + const argString = typeof arg === 'string' ? '"' + arg + '"' : String(arg); + it(argString, () => { const result = object.hasValue(object.entries, arg); assert.strictEqual(result, false); }); From 77b901f9a8c570fd6f058cfca30355dcc6f242a2 Mon Sep 17 00:00:00 2001 From: Evan Cole <18554853+colevandersWands@users.noreply.github.com> Date: Sat, 9 Nov 2019 11:41:45 +0100 Subject: [PATCH 09/12] description as string --- week-3-project/tests/has-value.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/week-3-project/tests/has-value.js b/week-3-project/tests/has-value.js index beb3f29..b86416e 100644 --- a/week-3-project/tests/has-value.js +++ b/week-3-project/tests/has-value.js @@ -47,7 +47,8 @@ describe(`hasValue: determines if an object has a given value`, () => { object.entries = {}; }); ['tomato', null, true, undefined, 4].forEach(arg => { - it(arg, () => { + const argString = typeof arg === 'string' ? '"' + arg + '"' : String(arg); + it(argString, () => { const result = object.hasValue(object.entries, arg); assert.strictEqual(result, false); }); From 76c7b361eff281a9a8b34171c0f8eb20a958e85a Mon Sep 17 00:00:00 2001 From: Anthony Meirlaen Date: Sun, 10 Nov 2019 10:05:00 +0100 Subject: [PATCH 10/12] check if object has keys removed --- week-2-project/tests/remove-entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week-2-project/tests/remove-entry.js b/week-2-project/tests/remove-entry.js index f3b310f..8a14f0c 100644 --- a/week-2-project/tests/remove-entry.js +++ b/week-2-project/tests/remove-entry.js @@ -38,7 +38,7 @@ describe(`removeEntry: should remove a key/value pair from this.entries`, () => describe(`... and actually removes the entries!`, () => { valuesToRemove.forEach(arg => { it(`object.hasKey(object.entries, ${arg}) === false`, () => { - assert.strictEqual(this.entries.hasOwnProperty(arg), false); + assert.strictEqual(object.entries.hasOwnProperty(arg), false); }); }); }); From d58ea066752ab63f4922df204ffb21f0112d6924 Mon Sep 17 00:00:00 2001 From: Evan Cole <18554853+colevandersWands@users.noreply.github.com> Date: Sun, 10 Nov 2019 15:13:26 +0100 Subject: [PATCH 11/12] Update arrays-vs-objects.js --- week-3-project/practice-problems/arrays-vs-objects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/week-3-project/practice-problems/arrays-vs-objects.js b/week-3-project/practice-problems/arrays-vs-objects.js index 4a7e82c..35261ea 100644 --- a/week-3-project/practice-problems/arrays-vs-objects.js +++ b/week-3-project/practice-problems/arrays-vs-objects.js @@ -35,8 +35,8 @@ try { // asserts - console.assert(obj[obj_key] === "object", "obj assert"); - console.assert(arr[arr_index] === "array", "arr assert"); + console.assert(obj[objKey] === "object", "obj assert"); + console.assert(arr[arrIndex] === "array", "arr assert"); } evaluate(swapValues2); From f4c333dbf4fb16ab4b8ecc88049f7432d82e5db7 Mon Sep 17 00:00:00 2001 From: Anthony Meirlaen Date: Sat, 16 Nov 2019 21:15:09 +0100 Subject: [PATCH 12/12] Fix issues with validating removed entries --- week-3-project/tests/remove-entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week-3-project/tests/remove-entry.js b/week-3-project/tests/remove-entry.js index f3b310f..8a14f0c 100644 --- a/week-3-project/tests/remove-entry.js +++ b/week-3-project/tests/remove-entry.js @@ -38,7 +38,7 @@ describe(`removeEntry: should remove a key/value pair from this.entries`, () => describe(`... and actually removes the entries!`, () => { valuesToRemove.forEach(arg => { it(`object.hasKey(object.entries, ${arg}) === false`, () => { - assert.strictEqual(this.entries.hasOwnProperty(arg), false); + assert.strictEqual(object.entries.hasOwnProperty(arg), false); }); }); });