├── .github
└── stale.yml
├── .gitignore
├── README.md
├── SpecRunner.html
├── jasmine
└── jasmine-2.8.0
│ ├── boot.js
│ ├── console.js
│ ├── ironhack-logo.png
│ ├── jasmine-html.js
│ ├── jasmine.css
│ ├── jasmine.js
│ └── jasmine_favicon.png
├── src
└── functions-and-arrays.js
└── tests
└── functions-and-arrays.spec.js
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Configuration for probot-stale - https://github.com/probot/stale
2 |
3 | # Number of days of inactivity before an Issue or Pull Request becomes stale
4 | daysUntilStale: 30
5 |
6 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
7 | exemptLabels: []
8 |
9 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
10 | # onlyLabels:
11 | # - TestLabel
12 |
13 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
14 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
15 | daysUntilClose: 2
16 |
17 | # Label to use when marking as stale
18 | staleLabel: stale
19 |
20 | # Comment to post when marking as stale. Set to `false` to disable
21 | markComment: >
22 | This pull request has been automatically marked as stale because it didn't have any recent activity. It will be closed if no further activity occurs. Thank you
23 | for your contributions.
24 | closeComment: >
25 | This pull request is closed. Thank you.
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | .vscode
4 | package-lock.json
5 | yarn.lock
6 | *.log
7 | lab-solution.html
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # LAB | JS Functions & Arrays
4 |
5 |
6 |
7 |
Learning Goals
8 |
9 |
10 | This exercise allows you to practice and apply the concepts and techniques taught in class.
11 |
12 | Upon completion of this exercise, you will be able to:
13 |
14 | - Run predefined tests in Jasmine to verify that the program meets the technical requirements.
15 | - Identify expected code behavior by reading and understanding test results and errors.
16 | - Declare and invoke functions using function declaration, function expression, and arrow function syntax.
17 | - Use the `return` keyword to return a value from a function.
18 | - Pass primitive values as arguments to functions.
19 | - Pass arrays to functions as arguments.
20 | - Access items stored in arrays using the indexes,
21 | - Add, remove and check for items in an array using the index and array methods (`unshift`, `push`, `splice`, `shift`, `pop`, `indexOf`, and `includes`).
22 | - Iterate over arrays using the `for` and `forEach` loops.
23 |
24 |
25 |
26 |
27 |
28 |
29 | ## Introduction
30 |
31 | Array manipulation is a common task in programming. Whether you are calculating a total for a shopping cart, grabbing only the first names from a list of people, or moving a piece on a chessboard, you are probably modifying or manipulating an array somewhere in the code.
32 |
33 |
34 | ## Requirements
35 |
36 | - Fork this repo
37 | - Clone it to your machine
38 |
39 | ## Submission
40 |
41 | - Upon completion, run the following commands:
42 |
43 | ```bash
44 | git add .
45 | git commit -m "Solved lab"
46 | git push origin master
47 | ```
48 |
49 | - Create a Pull Request so that your TAs can check your work.
50 |
51 | ## Automated Testing Introduction
52 |
53 | ### What is automated testing?
54 |
55 | Automated software testing is the process of programmatically executing an application to validate and verify that it meets the business needs, as well as the technical requirements, and that it behaves as expected.
56 |
57 | Testing should be viewed as a continuous process, not a discrete operation or single activity in the development lifecycle. Designing tests at the beginning of the product lifecycle can mitigate common issues that arise when developing complex code bases.
58 |
59 | Having a strong *test suite* can provide you the ease of mind since you will be able to confidently improve upon your work while knowing that your not breaking a previously developed feature.
60 |
61 |
62 | ### Testing labs
63 |
64 | This LAB and some labs you will work on during the bootcamp are equipped with unit tests to provide automated feedback on your lab progress.
65 |
66 |
67 | ### Testing with Jasmine
68 |
69 | Jasmine is an automated testing framework for JavaScript. It is designed to be used in Behavior-driven Development (**BDD**) programming, focusing more on the business value than the technical details.
70 |
71 | We have already included Jasmine in the project you just forked, so let's see how to use it to implement our code.
72 |
73 |
74 | ### Usage
75 |
76 | Before starting coding, we will explain the project structure we have provided you:
77 |
78 | ```
79 | lab-js-functions-and-arrays
80 | ├── README.md
81 | ├── SpecRunner.html
82 | ├── jasmine
83 | │ └── ...
84 | ├── src
85 | │ └── functions-and-arrays.js
86 | └── tests
87 | └── functions-and-arrays.spec.js
88 | ```
89 |
90 | We will be working with the `src/functions-and-arrays.js`. You can find all the files in the `jasmine` folder needed to use Jasmine. All these files are already linked with the `SpecRunner.html` file.
91 |
92 | If you want to check the tests, they are in the `tests/functions-and-arrays.spec.js` file.
93 |
94 |
95 | #### Run tests
96 |
97 | Running automated tests with Jasmine is super easy. All you need to do is open the `SpecRunner.html` file in your browser. You will find something similar to this:
98 |
99 | [](https://user-images.githubusercontent.com/23629340/33389609-c2f3965c-d533-11e7-9a03-e0a89314dd98.png)
100 |
101 |
102 | #### Pass the tests
103 |
104 | You should write your code on the `src/functions-and-arrays.js` file. While following the instructions for each iteration, you should check every test and ensure it's *passing*, before moving on.
105 |
106 | Do not rush. You should take your time to read every iteration carefully and address the *breaking* tests as you progress through the exercise.
107 |
108 | When coding with tests, it is super important that you carefully read and understand the errors you are getting. This way, you will know what's expected from your code.
109 |
110 | To see the output of your JavaScript code, open the [Console in the Developer Tools](https://developer.chrome.com/docs/devtools/open/#console).
111 |
112 | **Important:** Note that **you don't need to execute the functions yourself**; the tests will automatically load and execute the functions on each test run. All you need to do is declare the functions, ensure they handle the parameters passed and return what is indicated in the iteration instructions and the test description. We provide you with a sample array for some iterations, so you can do some **manual** testing if you wish.
113 |
114 | ## Instructions
115 |
116 | While following the instructions for each iteration, carefully read the instructions and test descriptions to understand the task requirements fully. Do not rush. It would be best if you took your time to read every iteration carefully.
117 |
118 |
119 |
120 | ### Iteration #1: Find the maximum
121 |
122 | Implement the function `maxOfTwoNumbers` that takes two numbers as arguments and returns the bigger number.
123 |
124 |
125 |
126 | ### Iteration #2: Find the longest word
127 |
128 | Implement the function `findLongestWord` that takes as an argument an array of words and returns the longest one. If there are 2 with the same length, it should return the first occurrence.
129 |
130 | You can use the following array to test your solution:
131 |
132 | ```javascript
133 | const words = ['mystery', 'brother', 'aviator', 'crocodile', 'pearl', 'orchard', 'crackpot'];
134 | ```
135 |
136 |
137 |
138 | ### Iteration #3: Calculate the sum
139 |
140 | #### Iteration #3.1: Sum numbers
141 |
142 | Calculating a sum can be as simple as iterating over an array and adding each of the elements together.
143 |
144 | Implement the function named `sumNumbers` that takes an array of numbers as an argument and returns the sum of all the numbers in the array. Later in the course, we will learn how to do this using the `reduce` array method, making your work significantly easier. For now, let's practice _the "declarative"_ way of adding values using loops.
145 |
146 | You can use the following array to test your solution:
147 |
148 | ```javascript
149 | const numbers = [6, 12, 1, 18, 13, 16, 2, 1, 8, 10];
150 | ```
151 |
152 |
153 |
154 | #### Bonus - Iteration #3.2: A generic `sum()` function
155 |
156 | In iteration 3, you created a function that returns the sum of an array of numbers. But what if we want to calculate the sum of the length of words in an array? What if it also includes _boolean_ values? To achieve this, we must create a function allowing this flexibility.
157 |
158 | You should implement the function `sum()` in this iteration. The function should take an array of mixed values - numbers, strings, and booleans. The function should add all the string lengths, numeric values, and numeric values of booleans to the total sum and return the sum.
159 |
160 | You can use the following array to test your solution:
161 |
162 | ```javascript
163 | const mixedArr = [6, 12, 'miami', 1, true, 'barca', '200', 'lisboa', 8, 10];
164 |
165 | // should return: 57
166 | ```
167 |
168 |
169 | Note: Your function should only accept an array with numbers, strings, or booleans. If the array contains any other data type, such as an object, you should [throw an error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw). In JavaScript, the syntax for throwing an error is as follows:
170 | ```javascript
171 | throw new Error("Error message goes here");
172 | ```
173 |
174 | When specifying the error message, you should be specific and descriptive in explaining the error.
175 |
176 |
177 |
178 | ### Iteration #4: Calculate the average
179 |
180 | Calculating an average is a prevalent task. So let's practice it a bit.
181 |
182 | **The logic behind this:**
183 |
184 | 1. Find the sum as we did in the first exercise (or how about reusing the function `sumNumbers()`?)
185 | 2. Divide that sum by the number of elements in the array.
186 |
187 |
188 |
189 | #### Iteration #4.1: Array of numbers
190 |
191 | Implement the function `averageNumbers` that expects an array of numbers and returns the average of the numbers.
192 |
193 | You can use the following array to test your solution:
194 |
195 | ```javascript
196 | const numbers = [2, 6, 9, 10, 7, 4, 1, 9];
197 | ```
198 |
199 |
200 | #### Iteration #4.2: Array of strings
201 |
202 | Implement the function named `averageWordLength` that receives as a single argument an array of words and returns the average length of the words:
203 |
204 | You can use the following array to test your solution:
205 |
206 | ```javascript
207 | const words = ['seat', 'correspond', 'linen', 'motif', 'hole', 'smell', 'smart', 'chaos', 'fuel', 'palace'];
208 | ```
209 |
210 |
211 |
212 | #### Bonus - Iteration #4.3: A generic `avg()` function
213 |
214 | Create function `avg(arr)` that receives any mixed array and calculates the average. For example, consider an array filled with numbers and/or strings and/or booleans as a mixed array.
215 |
216 | The non-numerical values should be counted as follows:
217 |
218 | - Booleans: `true` counts as `1` and `false` counts as `0`.
219 | - Strings: use the string `length` as the numeric value.
220 |
221 | ```javascript
222 | const mixedArr = [6, 12, 'miami', 1, true, 'barca', '200', 'lisboa', 8, 10];
223 |
224 | // should return: 5.7
225 | ```
226 |
227 |
228 |
229 | ### Iteration #5: Unique arrays
230 |
231 | Take the following array, remove the duplicates, and return a new array. You are more than likely going to want to check out the Array methods [`indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) and [`includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes).
232 |
233 | Do this in the form of a function `uniquifyArray` that receives an array of words as an argument.
234 |
235 |
236 |
237 | You can use the following array to test your solution:
238 |
239 | ```javascript
240 | const words = [
241 | 'crab',
242 | 'poison',
243 | 'contagious',
244 | 'simple',
245 | 'bring',
246 | 'sharp',
247 | 'playground',
248 | 'poison',
249 | 'communion',
250 | 'simple',
251 | 'bring'
252 | ];
253 | ```
254 |
255 |
256 |
257 | ### Iteration #6: Find elements
258 |
259 | Let's create a simple array search.
260 |
261 | Declare a function named `doesWordExist` that will take in an array of words as one argument and a *word to search* for as the other. Return `true` if the word exists in the array; otherwise, return `false`.
262 |
263 | You can use the following array to test your solution:
264 |
265 | ```javascript
266 | const words = ['machine', 'subset', 'trouble', 'starting', 'matter', 'eating', 'truth', 'disobedience'];
267 | ```
268 |
269 |
270 |
271 | ### Iteration #7: Count repetition
272 |
273 | Declare a function named `howManyTimes` that will take in an array of words as the first argument and a word to search for as the second argument. The function will return the number of times that word appears in the array.
274 |
275 | You can use the following array to test your solution:
276 |
277 | ```javascript
278 | const words = [
279 | 'machine',
280 | 'matter',
281 | 'subset',
282 | 'trouble',
283 | 'starting',
284 | 'matter',
285 | 'eating',
286 | 'matter',
287 | 'truth',
288 | 'disobedience',
289 | 'matter'
290 | ];
291 | ```
292 |
293 |
294 |
295 |
296 |
297 | ### Bonus - Iteration #8
298 |
299 |
300 |
301 | #### Bonus - Iteration #8.1: Product of adjacent numbers
302 |
303 | Given multiple arrays, find the greatest product of four adjacent numbers.
304 |
305 | We consider adjacent any four numbers that are next to each other horizontally or vertically. For example, if we have a 5x5 Matrix like:
306 |
307 | ```bash
308 | [ 1, 2, 3, 4, 5]
309 | [ 1, 20, 3, 4, 5]
310 | [ 1, 20, 3, 4, 5]
311 | [ 1, 20, 3, 4, 5]
312 | [ 1, 4, 3, 4, 5]
313 | ```
314 |
315 | The greatest product will be the `20`x`20`x`20`x`4` = `32000`.
316 |
317 |
318 |
319 |
320 |
321 | Declare a function named `greatestProduct(matrix)` to find it in the 20×20 grid below!
322 |
323 | ```javascript
324 | const matrix = [
325 | [08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08],
326 | [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00],
327 | [81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65],
328 | [52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91],
329 | [22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80],
330 | [24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50],
331 | [32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70],
332 | [67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21],
333 | [24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72],
334 | [21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95],
335 | [78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92],
336 | [16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57],
337 | [86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58],
338 | [19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40],
339 | [04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66],
340 | [88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69],
341 | [04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36],
342 | [20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16],
343 | [20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54],
344 | [01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48]
345 | ];
346 | ```
347 |
348 |
349 |
350 |
351 |
352 | #### Bonus - Iteration #8.2: Product of diagonals
353 |
354 | Following the logic you've used in iteration #8.1, declare a function called `greatestProductOfDiagonals(matrix)`. It takes a matrix as a parameter and returns the greatest product of any four values laid out diagonally, in either direction.
355 |
356 |
357 |
358 | **Happy coding!** :heart:
359 |
360 |
361 |
362 | ## FAQs
363 |
364 |
365 |
366 |
367 | I am stuck in the exercise and don't know how to solve the problem or where to start.
368 |
369 |
370 | If you are stuck in your code and don't know how to solve the problem or where to start, you should take a step back and try to form a clear question about the specific issue you are facing. This will help you narrow down the problem and come up with potential solutions.
371 |
372 |
373 | For example, is it a concept that you don't understand, or are you receiving an error message that you don't know how to fix? It is usually helpful to try to state the problem as clearly as possible, including any error messages you are receiving. This can help you communicate the issue to others and potentially get help from classmates or online resources.
374 |
375 |
376 | Once you have a clear understanding of the problem, you will be able to start working toward the solution.
377 |
378 | [Back to top](#faqs)
379 |
380 |
381 |
382 |
383 | All of the Jasmine tests are failing and in red. Why did this happen?
384 |
385 |
386 | One possible reason why all of the Jasmine tests are failing is that there is a syntax error in the code being tested. If the code contains a syntax error, it will not be loaded properly and none of the tests will be able to run. This will cause all of the tests to fail.
387 |
388 | To troubleshoot this issue, you will need to examine the code being tested for syntax errors. Look for missing brackets, semicolons, or other syntax issues that could be causing the problem. If you find a syntax error, correct it and try running the tests again.
389 |
390 | Another possibility is that there is an issue with the tests. It is possible that you may have modified the test file and caused an issue. If you have made changes to the test file, try copying and pasting the original test file and running the tests again to see if this resolves the issue.
391 |
392 | [Back to top](#faqs)
393 |
394 |
395 |
396 |
397 | How do you find a length of a string in JavaScript?
398 |
399 |
400 | To find the length of a string, use the `length` property. Here is an example:
401 |
402 | ```js
403 | const str = "Hello, world!"";
404 | console.log(str.length); // 13
405 | ```
406 |
407 | The `length` property returns the number of characters in the string, including spaces and special characters.
408 |
409 | [Back to top](#faqs)
410 |
411 |
412 |
413 |
414 | How do I loop over an array?
415 |
416 |
417 | Loops allow you to repeat a block of code a certain number of times. There are several ways to loop over an array in JavaScript:
418 |
419 |
420 |
421 | #### For loop
422 |
423 | The `for` loop is the most traditional way to loop through an array in JavaScript. It consists of three parts: the *initialization*, the *condition*, and the *increment/decrement*:
424 |
425 | ```js
426 | const animals = ['cat', 'dog', 'bird'];
427 |
428 | // initialize counter variable (let i = 0)
429 | // set condition (i < animals.length)
430 | // increment counter (i++)
431 | for (let i = 0; i < animals.length; i++) {
432 | console.log(animals[i]);
433 | }
434 | ```
435 |
436 | In initialization, you declare a counter variable and set its initial value.
437 |
438 | The condition is a boolean expression that is evaluated before each iteration of the loop. If the condition is `true`, the loop will continue. Once the condition turns `false`, the loop will terminate.
439 |
440 | The increment/decrement is where you update the counter variable and it happens at the end of each iteration.
441 |
442 | The block of code inside the loop is repeated during each iteration.
443 |
444 |
445 |
446 | #### While loop
447 |
448 | The `while` loop is another way to loop through an array in JavaScript. It consists of a condition and a block of code that is executed as long as the condition is `true`.
449 |
450 | Like the `for` loop, the `while` loop requires a counter variable to keep track of the current position in the array. The counter variable must be initialized before the loop and incremented or decremented at the end of each iteration.
451 |
452 | ```js
453 | const animals = ['cat', 'dog', 'bird'];
454 |
455 | // initialize a counter variable (i)
456 | let i = 0;
457 |
458 | // set condition (i < animals.length)
459 | while (i < animals.length) {
460 | console.log(animals[i]);
461 |
462 | // increment counter (i++)
463 | i++;
464 | }
465 | ```
466 |
467 | [Back to top](#faqs)
468 |
469 |
470 |
471 |
472 | How do I loop over an array using the forEach() method?
473 |
474 |
475 | The `forEach()` method executes a provided function once for each array element. It does not return a new array but rather executes the function on each element in the array.
476 |
477 | The syntax of the `forEach()` method is as follows:
478 |
479 | ```js
480 | array.forEach( function(element) {
481 | // code to be executed for each element
482 | });
483 | ```
484 |
485 |
486 |
487 | Here is an example that uses the `forEach()` method to log each element and its index in an array to the console:
488 |
489 | ```js
490 | const fruits = ['apple', 'banana', 'cherry'];
491 |
492 | fruits.forEach( function(element, index) {
493 | console.log(`${index}: ${element}`);
494 | });
495 | ```
496 |
497 |
498 |
499 | You can also use an arrow function as the callback function for `forEach()`:
500 |
501 | ```js
502 | fruits.forEach((element, index) => {
503 | console.log(`${index}: ${element}`);
504 | });
505 | ```
506 |
507 | [Back to top](#faqs)
508 |
509 |
510 |
511 |
512 | What could cause array.length to return undefined?
513 |
514 |
515 | If you try to access the `.length` property on an array (e.g., `array.length`) but get `undefined`, it means that the variable you are accessing is not actually an array.
516 |
517 |
518 |
519 | **How do I fix this?**
520 |
521 | Check that the variable you are trying to access is actually an array.
522 |
523 | [Back to top](#faqs)
524 |
525 |
526 |
527 |
528 | Why is my function returning the last element of the array instead of the longest one?
529 |
530 |
531 | Your function might not be correctly checking for the longest element in the array. In other words, there may be an issue with the logic of the conditional statements in the function or with the comparison being used in the conditionals.
532 |
533 | To fix this issue, you should check the logic of the conditional statements in the function.
534 |
535 | [Back to top](#faqs)
536 |
537 |
538 |
539 |
540 | How can I compare the length of each word in an array in JavaScript?
541 |
542 |
543 | To compare the length of each word in an array in JavaScript, you can use a loop to iterate through the array and compare the length of each element using the `.length` property.
544 |
545 | Here is an example of how you loop over an array:
546 |
547 | ```js
548 | function findLongestWord(words) {
549 | for (let i = 0; i < words.length; i++) {
550 | console.log(words[i]);
551 | }
552 | }
553 | ```
554 |
555 |
556 |
557 | To compare the length of each element, you should use a conditional statement in the following way:
558 |
559 | ```js
560 | if ( words[i].length > longestWord.length) {
561 | console.log(`${words[i].length} is longer than ${longestWord.length}`);
562 | }
563 | ```
564 |
565 | [Back to top](#faqs)
566 |
567 |
568 |
569 |
570 | I am unable to push changes to the repository. What should I do?
571 |
572 |
573 | There are a couple of possible reasons why you may be unable to *push* changes to a Git repository:
574 |
575 | 1. **You have not committed your changes:** Before you can push your changes to the repository, you need to commit them using the `git commit` command. Make sure you have committed your changes and try pushing again. To do this, run the following terminal commands from the project folder:
576 | ```bash
577 | git add .
578 | git commit -m "Your commit message"
579 | git push
580 | ```
581 | 2. **You do not have permission to push to the repository:** If you have cloned the repository directly from the main Ironhack repository without making a *Fork* first, you do not have write access to the repository.
582 | To check which remote repository you have cloned, run the following terminal command from the project folder:
583 | ```bash
584 | git remote -v
585 | ```
586 | If the link shown is the same as the main Ironhack repository, you will need to fork the repository to your GitHub account first and then clone your fork to your local machine to be able to push the changes.
587 |
588 | **Note**: You should make a copy of your local code to avoid losing it in the process.
589 |
590 | [Back to top](#faqs)
591 |
592 |
593 |
--------------------------------------------------------------------------------
/SpecRunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Jasmine Spec Runner v2.8.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/boot.js:
--------------------------------------------------------------------------------
1 | /**
2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
3 |
4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
5 |
6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
7 |
8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
9 | */
10 |
11 | (function() {
12 |
13 | /**
14 | * ## Require & Instantiate
15 | *
16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
17 | */
18 | window.jasmine = jasmineRequire.core(jasmineRequire);
19 |
20 | /**
21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
22 | */
23 | jasmineRequire.html(jasmine);
24 |
25 | /**
26 | * Create the Jasmine environment. This is used to run all specs in a project.
27 | */
28 | var env = jasmine.getEnv();
29 |
30 | /**
31 | * ## The Global Interface
32 | *
33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
34 | */
35 | var jasmineInterface = jasmineRequire.interface(jasmine, env);
36 |
37 | /**
38 | * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
39 | */
40 | extend(window, jasmineInterface);
41 |
42 | /**
43 | * ## Runner Parameters
44 | *
45 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
46 | */
47 |
48 | var queryString = new jasmine.QueryString({
49 | getWindowLocation: function() { return window.location; }
50 | });
51 |
52 | var filterSpecs = !!queryString.getParam("spec");
53 |
54 | var catchingExceptions = queryString.getParam("catch");
55 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
56 |
57 | var throwingExpectationFailures = queryString.getParam("throwFailures");
58 | env.throwOnExpectationFailure(throwingExpectationFailures);
59 |
60 | var random = queryString.getParam("random");
61 | env.randomizeTests(random);
62 |
63 | var seed = queryString.getParam("seed");
64 | if (seed) {
65 | env.seed(seed);
66 | }
67 |
68 | /**
69 | * ## Reporters
70 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
71 | */
72 | var htmlReporter = new jasmine.HtmlReporter({
73 | env: env,
74 | onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
75 | onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
76 | onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
77 | addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
78 | getContainer: function() { return document.body; },
79 | createElement: function() { return document.createElement.apply(document, arguments); },
80 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
81 | timer: new jasmine.Timer(),
82 | filterSpecs: filterSpecs
83 | });
84 |
85 | /**
86 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
87 | */
88 | env.addReporter(jasmineInterface.jsApiReporter);
89 | env.addReporter(htmlReporter);
90 |
91 | /**
92 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
93 | */
94 | var specFilter = new jasmine.HtmlSpecFilter({
95 | filterString: function() { return queryString.getParam("spec"); }
96 | });
97 |
98 | env.specFilter = function(spec) {
99 | return specFilter.matches(spec.getFullName());
100 | };
101 |
102 | /**
103 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
104 | */
105 | window.setTimeout = window.setTimeout;
106 | window.setInterval = window.setInterval;
107 | window.clearTimeout = window.clearTimeout;
108 | window.clearInterval = window.clearInterval;
109 |
110 | /**
111 | * ## Execution
112 | *
113 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
114 | */
115 | var currentWindowOnload = window.onload;
116 |
117 | window.onload = function() {
118 | if (currentWindowOnload) {
119 | currentWindowOnload();
120 | }
121 | htmlReporter.initialize();
122 | env.execute();
123 | };
124 |
125 | /**
126 | * Helper function for readability above.
127 | */
128 | function extend(destination, source) {
129 | for (var property in source) destination[property] = source[property];
130 | return destination;
131 | }
132 |
133 | }());
134 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/console.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2017 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | function getJasmineRequireObj() {
24 | if (typeof module !== 'undefined' && module.exports) {
25 | return exports;
26 | } else {
27 | window.jasmineRequire = window.jasmineRequire || {};
28 | return window.jasmineRequire;
29 | }
30 | }
31 |
32 | getJasmineRequireObj().console = function(jRequire, j$) {
33 | j$.ConsoleReporter = jRequire.ConsoleReporter();
34 | };
35 |
36 | getJasmineRequireObj().ConsoleReporter = function() {
37 |
38 | var noopTimer = {
39 | start: function(){},
40 | elapsed: function(){ return 0; }
41 | };
42 |
43 | function ConsoleReporter(options) {
44 | var print = options.print,
45 | showColors = options.showColors || false,
46 | onComplete = options.onComplete || function() {},
47 | timer = options.timer || noopTimer,
48 | specCount,
49 | failureCount,
50 | failedSpecs = [],
51 | pendingCount,
52 | ansi = {
53 | green: '\x1B[32m',
54 | red: '\x1B[31m',
55 | yellow: '\x1B[33m',
56 | none: '\x1B[0m'
57 | },
58 | failedSuites = [];
59 |
60 | print('ConsoleReporter is deprecated and will be removed in a future version.');
61 |
62 | this.jasmineStarted = function() {
63 | specCount = 0;
64 | failureCount = 0;
65 | pendingCount = 0;
66 | print('Started');
67 | printNewline();
68 | timer.start();
69 | };
70 |
71 | this.jasmineDone = function() {
72 | printNewline();
73 | for (var i = 0; i < failedSpecs.length; i++) {
74 | specFailureDetails(failedSpecs[i]);
75 | }
76 |
77 | if(specCount > 0) {
78 | printNewline();
79 |
80 | var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
81 | failureCount + ' ' + plural('failure', failureCount);
82 |
83 | if (pendingCount) {
84 | specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
85 | }
86 |
87 | print(specCounts);
88 | } else {
89 | print('No specs found');
90 | }
91 |
92 | printNewline();
93 | var seconds = timer.elapsed() / 1000;
94 | print('Finished in ' + seconds + ' ' + plural('second', seconds));
95 | printNewline();
96 |
97 | for(i = 0; i < failedSuites.length; i++) {
98 | suiteFailureDetails(failedSuites[i]);
99 | }
100 |
101 | onComplete(failureCount === 0);
102 | };
103 |
104 | this.specDone = function(result) {
105 | specCount++;
106 |
107 | if (result.status == 'pending') {
108 | pendingCount++;
109 | print(colored('yellow', '*'));
110 | return;
111 | }
112 |
113 | if (result.status == 'passed') {
114 | print(colored('green', '.'));
115 | return;
116 | }
117 |
118 | if (result.status == 'failed') {
119 | failureCount++;
120 | failedSpecs.push(result);
121 | print(colored('red', 'F'));
122 | }
123 | };
124 |
125 | this.suiteDone = function(result) {
126 | if (result.failedExpectations && result.failedExpectations.length > 0) {
127 | failureCount++;
128 | failedSuites.push(result);
129 | }
130 | };
131 |
132 | return this;
133 |
134 | function printNewline() {
135 | print('\n');
136 | }
137 |
138 | function colored(color, str) {
139 | return showColors ? (ansi[color] + str + ansi.none) : str;
140 | }
141 |
142 | function plural(str, count) {
143 | return count == 1 ? str : str + 's';
144 | }
145 |
146 | function repeat(thing, times) {
147 | var arr = [];
148 | for (var i = 0; i < times; i++) {
149 | arr.push(thing);
150 | }
151 | return arr;
152 | }
153 |
154 | function indent(str, spaces) {
155 | var lines = (str || '').split('\n');
156 | var newArr = [];
157 | for (var i = 0; i < lines.length; i++) {
158 | newArr.push(repeat(' ', spaces).join('') + lines[i]);
159 | }
160 | return newArr.join('\n');
161 | }
162 |
163 | function specFailureDetails(result) {
164 | printNewline();
165 | print(result.fullName);
166 |
167 | for (var i = 0; i < result.failedExpectations.length; i++) {
168 | var failedExpectation = result.failedExpectations[i];
169 | printNewline();
170 | print(indent(failedExpectation.message, 2));
171 | print(indent(failedExpectation.stack, 2));
172 | }
173 |
174 | printNewline();
175 | }
176 |
177 | function suiteFailureDetails(result) {
178 | for (var i = 0; i < result.failedExpectations.length; i++) {
179 | printNewline();
180 | print(colored('red', 'An error was thrown in an afterAll'));
181 | printNewline();
182 | print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
183 |
184 | }
185 | printNewline();
186 | }
187 | }
188 |
189 | return ConsoleReporter;
190 | };
191 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/ironhack-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironhack-labs/lab-javascript-functions-and-arrays/8ff766d48cfaec4c92933502f549cd08ebd9661f/jasmine/jasmine-2.8.0/ironhack-logo.png
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/jasmine-html.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2017 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | jasmineRequire.html = function(j$) {
24 | j$.ResultsNode = jasmineRequire.ResultsNode();
25 | j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
26 | j$.QueryString = jasmineRequire.QueryString();
27 | j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
28 | };
29 |
30 | jasmineRequire.HtmlReporter = function(j$) {
31 |
32 | var noopTimer = {
33 | start: function() {},
34 | elapsed: function() { return 0; }
35 | };
36 |
37 | function HtmlReporter(options) {
38 | var env = options.env || {},
39 | getContainer = options.getContainer,
40 | createElement = options.createElement,
41 | createTextNode = options.createTextNode,
42 | onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
43 | onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
44 | onRandomClick = options.onRandomClick || function() {},
45 | addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
46 | filterSpecs = options.filterSpecs,
47 | timer = options.timer || noopTimer,
48 | results = [],
49 | specsExecuted = 0,
50 | failureCount = 0,
51 | pendingSpecCount = 0,
52 | htmlReporterMain,
53 | symbols,
54 | failedSuites = [];
55 |
56 | this.initialize = function() {
57 | clearPrior();
58 | htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
59 | createDom('div', {className: 'jasmine-banner'},
60 | createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
61 | createDom('span', {className: 'jasmine-version'}, j$.version)
62 | ),
63 | createDom('ul', {className: 'jasmine-symbol-summary'}),
64 | createDom('div', {className: 'jasmine-labname'}),
65 | createDom('div', {className: 'jasmine-alert'}),
66 | createDom('div', {className: 'jasmine-results'},
67 | createDom('div', {className: 'jasmine-failures'})
68 | )
69 | );
70 | getContainer().appendChild(htmlReporterMain);
71 | };
72 |
73 | var totalSpecsDefined;
74 | this.jasmineStarted = function(options) {
75 | totalSpecsDefined = options.totalSpecsDefined || 0;
76 | timer.start();
77 | };
78 |
79 | var summary = createDom('div', {className: 'jasmine-summary'});
80 |
81 | var topResults = new j$.ResultsNode({}, '', null),
82 | currentParent = topResults;
83 |
84 | this.suiteStarted = function(result) {
85 | currentParent.addChild(result, 'suite');
86 | currentParent = currentParent.last();
87 | };
88 |
89 | this.suiteDone = function(result) {
90 | if (result.status == 'failed') {
91 | failedSuites.push(result);
92 | }
93 |
94 | if (currentParent == topResults) {
95 | return;
96 | }
97 |
98 | currentParent = currentParent.parent;
99 | };
100 |
101 | this.specStarted = function(result) {
102 | currentParent.addChild(result, 'spec');
103 | };
104 |
105 | var failures = [];
106 | this.specDone = function(result) {
107 | if (noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
108 | console.error('Spec \'' + result.fullName + '\' has no expectations.');
109 | }
110 |
111 | if (result.status != 'disabled') {
112 | specsExecuted++;
113 | }
114 |
115 | if (!symbols){
116 | symbols = find('.jasmine-symbol-summary');
117 | }
118 |
119 | symbols.appendChild(createDom('li', {
120 | className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
121 | id: 'spec_' + result.id,
122 | title: result.fullName
123 | }
124 | ));
125 |
126 | if (result.status == 'failed') {
127 | failureCount++;
128 |
129 | var failure =
130 | createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
131 | createDom('div', {className: 'jasmine-description'},
132 | createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
133 | ),
134 | createDom('div', {className: 'jasmine-messages'})
135 | );
136 | var messages = failure.childNodes[1];
137 |
138 | for (var i = 0; i < result.failedExpectations.length; i++) {
139 | var expectation = result.failedExpectations[i];
140 | var stringStart = expectation.stack.indexOf("at UserContext.");
141 | var shortStackTrace = expectation.stack.slice(stringStart);
142 | messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
143 | messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, shortStackTrace));
144 | }
145 |
146 |
147 | failures.push(failure);
148 | }
149 |
150 | if (result.status == 'pending') {
151 | pendingSpecCount++;
152 | }
153 | };
154 |
155 | this.jasmineDone = function(doneResult) {
156 | var banner = find('.jasmine-banner');
157 | var labName = find('.jasmine-labname');
158 | var alert = find('.jasmine-alert');
159 | var order = doneResult && doneResult.order;
160 | labName.appendChild(createDom('img', {src: 'jasmine/jasmine-2.8.0/ironhack-logo.png'}, ''));
161 | labName.appendChild(createDom('span', {}, 'LAB | JS Functions & Arrays'));
162 | alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
163 |
164 | banner.appendChild(
165 | createDom('div', { className: 'jasmine-run-options' },
166 | createDom('span', { className: 'jasmine-trigger' }, 'Options'),
167 | createDom('div', { className: 'jasmine-payload' },
168 | createDom('div', { className: 'jasmine-exceptions' },
169 | createDom('input', {
170 | className: 'jasmine-raise',
171 | id: 'jasmine-raise-exceptions',
172 | type: 'checkbox'
173 | }),
174 | createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
175 | createDom('div', { className: 'jasmine-throw-failures' },
176 | createDom('input', {
177 | className: 'jasmine-throw',
178 | id: 'jasmine-throw-failures',
179 | type: 'checkbox'
180 | }),
181 | createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
182 | createDom('div', { className: 'jasmine-random-order' },
183 | createDom('input', {
184 | className: 'jasmine-random',
185 | id: 'jasmine-random-order',
186 | type: 'checkbox'
187 | }),
188 | createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
189 | )
190 | ));
191 |
192 | var raiseCheckbox = find('#jasmine-raise-exceptions');
193 |
194 | raiseCheckbox.checked = !env.catchingExceptions();
195 | raiseCheckbox.onclick = onRaiseExceptionsClick;
196 |
197 | var throwCheckbox = find('#jasmine-throw-failures');
198 | throwCheckbox.checked = env.throwingExpectationFailures();
199 | throwCheckbox.onclick = onThrowExpectationsClick;
200 |
201 | var randomCheckbox = find('#jasmine-random-order');
202 | randomCheckbox.checked = env.randomTests();
203 | randomCheckbox.onclick = onRandomClick;
204 |
205 | var optionsMenu = find('.jasmine-run-options'),
206 | optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
207 | optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
208 | isOpen = /\bjasmine-open\b/;
209 |
210 | optionsTrigger.onclick = function() {
211 | if (isOpen.test(optionsPayload.className)) {
212 | optionsPayload.className = optionsPayload.className.replace(isOpen, '');
213 | } else {
214 | optionsPayload.className += ' jasmine-open';
215 | }
216 | };
217 |
218 | if (specsExecuted < totalSpecsDefined) {
219 | var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
220 | var skippedLink = addToExistingQueryString('spec', '');
221 | alert.appendChild(
222 | createDom('span', {className: 'jasmine-bar jasmine-skipped'},
223 | createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage)
224 | )
225 | );
226 | }
227 | var statusBarMessage = '';
228 | var statusBarClassName = 'jasmine-bar ';
229 |
230 | if (totalSpecsDefined > 0) {
231 | statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
232 | if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
233 | statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
234 | } else {
235 | statusBarClassName += 'jasmine-skipped';
236 | statusBarMessage += 'No specs found';
237 | }
238 |
239 | var seedBar;
240 | if (order && order.random) {
241 | seedBar = createDom('span', {className: 'jasmine-seed-bar'},
242 | ', randomized with seed ',
243 | createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed)
244 | );
245 | }
246 |
247 | alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
248 |
249 | var errorBarClassName = 'jasmine-bar jasmine-errored';
250 | var errorBarMessagePrefix = 'AfterAll ';
251 |
252 | for(var i = 0; i < failedSuites.length; i++) {
253 | var failedSuite = failedSuites[i];
254 | for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
255 | alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
256 | }
257 | }
258 |
259 | var globalFailures = (doneResult && doneResult.failedExpectations) || [];
260 | for(i = 0; i < globalFailures.length; i++) {
261 | var failure = globalFailures[i];
262 | alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
263 | }
264 |
265 | var results = find('.jasmine-results');
266 | results.appendChild(summary);
267 |
268 | summaryList(topResults, summary);
269 |
270 | function summaryList(resultsTree, domParent) {
271 | var specListNode;
272 | for (var i = 0; i < resultsTree.children.length; i++) {
273 | var resultNode = resultsTree.children[i];
274 | if (filterSpecs && !hasActiveSpec(resultNode)) {
275 | continue;
276 | }
277 | if (resultNode.type == 'suite') {
278 | var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
279 | createDom('li', {className: 'jasmine-suite-detail'},
280 | createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
281 | )
282 | );
283 |
284 | summaryList(resultNode, suiteListNode);
285 | domParent.appendChild(suiteListNode);
286 | }
287 | if (resultNode.type == 'spec') {
288 | if (domParent.getAttribute('class') != 'jasmine-specs') {
289 | specListNode = createDom('ul', {className: 'jasmine-specs'});
290 | domParent.appendChild(specListNode);
291 | }
292 | var specDescription = resultNode.result.description;
293 | if(noExpectations(resultNode.result)) {
294 | specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
295 | }
296 | if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
297 | specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
298 | }
299 | specListNode.appendChild(
300 | createDom('li', {
301 | className: 'jasmine-' + resultNode.result.status,
302 | id: 'spec-' + resultNode.result.id
303 | },
304 | createDom('a', {href: specHref(resultNode.result)}, specDescription)
305 | )
306 | );
307 | }
308 | }
309 | }
310 |
311 | if (failures.length) {
312 | alert.appendChild(
313 | createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
314 | createDom('span', {}, 'Spec List | '),
315 | createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures')));
316 | alert.appendChild(
317 | createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'},
318 | createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'),
319 | createDom('span', {}, ' | Failures ')));
320 |
321 | find('.jasmine-failures-menu').onclick = function() {
322 | setMenuModeTo('jasmine-failure-list');
323 | };
324 | find('.jasmine-spec-list-menu').onclick = function() {
325 | setMenuModeTo('jasmine-spec-list');
326 | };
327 |
328 | // Set the default list to be shown - test descriptions or failures
329 | // setMenuModeTo('jasmine-failure-list');
330 | setMenuModeTo('jasmine-spec-list');
331 |
332 |
333 | var failureNode = find('.jasmine-failures');
334 | for (i = 0; i < failures.length; i++) {
335 | failureNode.appendChild(failures[i]);
336 | }
337 | }
338 | };
339 |
340 | return this;
341 |
342 | function find(selector) {
343 | return getContainer().querySelector('.jasmine_html-reporter ' + selector);
344 | }
345 |
346 | function clearPrior() {
347 | // return the reporter
348 | var oldReporter = find('');
349 |
350 | if(oldReporter) {
351 | getContainer().removeChild(oldReporter);
352 | }
353 | }
354 |
355 | function createDom(type, attrs, childrenVarArgs) {
356 | var el = createElement(type);
357 |
358 | for (var i = 2; i < arguments.length; i++) {
359 | var child = arguments[i];
360 |
361 | if (typeof child === 'string') {
362 | el.appendChild(createTextNode(child));
363 | } else {
364 | if (child) {
365 | el.appendChild(child);
366 | }
367 | }
368 | }
369 |
370 | for (var attr in attrs) {
371 | if (attr == 'className') {
372 | el[attr] = attrs[attr];
373 | } else {
374 | el.setAttribute(attr, attrs[attr]);
375 | }
376 | }
377 |
378 | return el;
379 | }
380 |
381 | function pluralize(singular, count) {
382 | var word = (count == 1 ? singular : singular + 's');
383 |
384 | return '' + count + ' ' + word;
385 | }
386 |
387 | function specHref(result) {
388 | return addToExistingQueryString('spec', result.fullName);
389 | }
390 |
391 | function seedHref(seed) {
392 | return addToExistingQueryString('seed', seed);
393 | }
394 |
395 | function defaultQueryString(key, value) {
396 | return '?' + key + '=' + value;
397 | }
398 |
399 | function setMenuModeTo(mode) {
400 | htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
401 | }
402 |
403 | function noExpectations(result) {
404 | return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
405 | result.status === 'passed';
406 | }
407 |
408 | function hasActiveSpec(resultNode) {
409 | if (resultNode.type == 'spec' && resultNode.result.status != 'disabled') {
410 | return true;
411 | }
412 |
413 | if (resultNode.type == 'suite') {
414 | for (var i = 0, j = resultNode.children.length; i < j; i++) {
415 | if (hasActiveSpec(resultNode.children[i])) {
416 | return true;
417 | }
418 | }
419 | }
420 | }
421 | }
422 |
423 | return HtmlReporter;
424 | };
425 |
426 | jasmineRequire.HtmlSpecFilter = function() {
427 | function HtmlSpecFilter(options) {
428 | var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
429 | var filterPattern = new RegExp(filterString);
430 |
431 | this.matches = function(specName) {
432 | return filterPattern.test(specName);
433 | };
434 | }
435 |
436 | return HtmlSpecFilter;
437 | };
438 |
439 | jasmineRequire.ResultsNode = function() {
440 | function ResultsNode(result, type, parent) {
441 | this.result = result;
442 | this.type = type;
443 | this.parent = parent;
444 |
445 | this.children = [];
446 |
447 | this.addChild = function(result, type) {
448 | this.children.push(new ResultsNode(result, type, this));
449 | };
450 |
451 | this.last = function() {
452 | return this.children[this.children.length - 1];
453 | };
454 | }
455 |
456 | return ResultsNode;
457 | };
458 |
459 | jasmineRequire.QueryString = function() {
460 | function QueryString(options) {
461 |
462 | this.navigateWithNewParam = function(key, value) {
463 | options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
464 | };
465 |
466 | this.fullStringWithNewParam = function(key, value) {
467 | var paramMap = queryStringToParamMap();
468 | paramMap[key] = value;
469 | return toQueryString(paramMap);
470 | };
471 |
472 | this.getParam = function(key) {
473 | return queryStringToParamMap()[key];
474 | };
475 |
476 | return this;
477 |
478 | function toQueryString(paramMap) {
479 | var qStrPairs = [];
480 | for (var prop in paramMap) {
481 | qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
482 | }
483 | return '?' + qStrPairs.join('&');
484 | }
485 |
486 | function queryStringToParamMap() {
487 | var paramStr = options.getWindowLocation().search.substring(1),
488 | params = [],
489 | paramMap = {};
490 |
491 | if (paramStr.length > 0) {
492 | params = paramStr.split('&');
493 | for (var i = 0; i < params.length; i++) {
494 | var p = params[i].split('=');
495 | var value = decodeURIComponent(p[1]);
496 | if (value === 'true' || value === 'false') {
497 | value = JSON.parse(value);
498 | }
499 | paramMap[decodeURIComponent(p[0])] = value;
500 | }
501 | }
502 |
503 | return paramMap;
504 | }
505 |
506 | }
507 |
508 | return QueryString;
509 | };
510 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/jasmine.css:
--------------------------------------------------------------------------------
1 | body { overflow-y: scroll; }
2 |
3 | .jasmine-labname {
4 | display: flex;
5 | align-items: center;
6 | justify-content: left;
7 | background-color: #2e354c; /* #32c3ff */
8 | padding: 8px;
9 | }
10 |
11 | .jasmine-labname span {
12 | color: white;
13 | font-size: 19px;
14 | margin-left: 10px;
15 | }
16 |
17 | .jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; }
18 | .jasmine_html-reporter a { text-decoration: none; }
19 | .jasmine_html-reporter a:hover { text-decoration: underline; }
20 | .jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; }
21 | .jasmine_html-reporter .jasmine-banner, .jasmine_html-reporter .jasmine-symbol-summary, .jasmine_html-reporter .jasmine-summary, .jasmine_html-reporter .jasmine-result-message, .jasmine_html-reporter .jasmine-spec .jasmine-description, .jasmine_html-reporter .jasmine-spec-detail .jasmine-description, .jasmine_html-reporter .jasmine-alert .jasmine-bar, .jasmine_html-reporter .jasmine-stack-trace { padding-left: 9px; padding-right: 9px; }
22 | .jasmine_html-reporter .jasmine-banner { position: relative; }
23 | .jasmine_html-reporter .jasmine-banner .jasmine-title { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAAZCAMAAACGusnyAAACdlBMVEX/////AP+AgICqVaqAQICZM5mAVYCSSZKAQICOOY6ATYCLRouAQICJO4mSSYCIRIiPQICHPIeOR4CGQ4aMQICGPYaLRoCFQ4WKQICPPYWJRYCOQoSJQICNPoSIRICMQoSHQICHRICKQoOHQICKPoOJO4OJQYOMQICMQ4CIQYKLQICIPoKLQ4CKQICNPoKJQISMQ4KJQoSLQYKJQISLQ4KIQoSKQYKIQICIQISMQoSKQYKLQIOLQoOJQYGLQIOKQIOMQoGKQYOLQYGKQIOLQoGJQYOJQIOKQYGJQIOKQoGKQIGLQIKLQ4KKQoGLQYKJQIGKQYKJQIGKQIKJQoGKQYKLQIGKQYKLQIOJQoKKQoOJQYKKQIOJQoKKQoOKQIOLQoKKQYOLQYKJQIOKQoKKQYKKQoKJQYOKQYKLQIOKQoKLQYOKQYKLQIOJQoGKQYKJQYGJQoGKQYKLQoGLQYGKQoGJQYKKQYGJQIKKQoGJQYKLQIKKQYGLQYKKQYGKQYGKQYKJQYOKQoKJQYOKQYKLQYOLQYOKQYKLQYOKQoKKQYKKQYOKQYOJQYKKQYKLQYKKQIKKQoKKQYKKQYKKQoKJQIKKQYKLQYKKQYKKQIKKQYKKQYKKQYKKQIKKQYKJQYGLQYGKQYKKQYKKQYGKQIKKQYGKQYOJQoKKQYOLQYKKQYOKQoKKQYKKQoKKQYKKQYKJQYKLQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKJQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKLQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKmIDpEAAAA0XRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAiIyQlJycoKissLS4wMTQ1Njc4OTo7PDw+P0BCQ0RISUpLTE1OUFNUVVdYWFlaW15fYGFiY2ZnaGlqa2xtb3BxcnN0dnh5ent8fX5/gIGChIWIioyNjo+QkZOUlZaYmZqbnJ2eoKGio6WmqKmsra6vsLGztre4ubq7vL2+wMHDxMjJysvNzs/Q0dLU1tfY2dvc3t/g4eLj5ebn6Onq6+zt7u/w8vP09fb3+Pn6+/z9/vkVQXAAAAMaSURBVHhe5dXxV1N1GMfxz2ABbDgIAm5VDJOyVDIJLUMaVpBWUZUaGbmqoGpZRSiGiRWp6KoZ5AB0ZY50RImZQIlahKkMYXv/R90dBvET/rJfOr3Ouc8v99zPec59zvf56j+vYKlViSf7250X4Mr3O29Tgq08BdGB4DhcekEJ5YkQKFsgWZdtj9JpV+I8xPjLFqkrsEIqO8PHSpis36jWazcqjEsfJjkvRssVU37SdIOu4XCf5vEJPsnwJpnRNU9JmxhMk8l1gehIrq7hTFjzOD+Vf88629qKMJVNltInFeRexRQyJlNeqd1iGDlSzrIUIyXbyFfm3RYprcQRe7lqtWyGYbfc6dT0R2vmdOOkX3u55C1rP37ftiH+tDby4r/RBT0w8TyEkr+epB9XgPDmSYYWbrhCuFYaIyw3fDQAXTnSkh+ANofiHmWf9l+FY1I90FdQTetstO00o23novzVsJ7uB3/C5TkbjRwZ5JerwV4iRWq9HFbFMaK/d0TYqayRiQPuIxxS3Bu8JWU90/60tKi7vkhaznez0a/TbVOKj5CaOZh6fWG6/Lyv9B/ZLR1gw/S/fpbeVD3MCW1li6SvWDOn65tr99/uvWtBS0XDm4s1t+sOHpG0kpBKx/l77wOSnxLpcx6TXmXLTPQOKYOf9Q1dfr8/SJ2mFdCvl1Yl93DiHUZvXeLJbGSzYu5gVJ2slbSakOR8dxCq5adQ2oFLqsE9Ex3L4qQO0eOPeU5x56bypXp4onSEb5OkICX6lDat55TeoztNKQcJaakrz9KCb95oD69IKq+yKW4XPjknaS52V0TZqE2cTtXjcHSCRmUO88e+85hj3EP74i9p8pylw7lxgMDyyl6OV7ZejnjNMfatu87LxRbH0IS35gt2a4ZjmGpVBdKK3Wr6INk8jWWSGqbA55CKgjBRC6E9w78ydTg3ABS3AFV1QN0Y4Aa2pgEjWnQURj9L0ayK6R2ysEqxHUKzYnLvvyU+i9KM2JHJzE4vyZOyDcOwOsySajeLPc8sNvPJkFlyJd20wpqAzZeAfZ3oWybxd+P/3j+SG3uSBdf2VQAAAABJRU5ErkJggg==') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; }
24 | .jasmine_html-reporter .jasmine-banner .jasmine-version { margin-left: 14px; position: relative; top: 6px; }
25 | .jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; }
26 | .jasmine_html-reporter .jasmine-version { color: #aaa; }
27 | .jasmine_html-reporter .jasmine-banner { margin-top: 14px; }
28 | .jasmine_html-reporter .jasmine-duration { color: #fff; float: right; line-height: 28px; padding-right: 9px; }
29 | .jasmine_html-reporter .jasmine-symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
30 | .jasmine_html-reporter .jasmine-symbol-summary li { display: inline-block; height: 10px; width: 14px; font-size: 16px; }
31 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed { font-size: 14px; }
32 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed:before { color: #007069; content: "\02022"; }
33 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed { line-height: 9px; }
34 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; }
35 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled { font-size: 14px; }
36 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled:before { color: #bababa; content: "\02022"; }
37 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending { line-height: 17px; }
38 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending:before { color: #ba9d37; content: "*"; }
39 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty { font-size: 14px; }
40 | .jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty:before { color: #ba9d37; content: "\02022"; }
41 | .jasmine_html-reporter .jasmine-run-options { float: right; margin-right: 5px; border: 1px solid #8a4182; color: #8a4182; position: relative; line-height: 20px; }
42 | .jasmine_html-reporter .jasmine-run-options .jasmine-trigger { cursor: pointer; padding: 8px 16px; }
43 | .jasmine_html-reporter .jasmine-run-options .jasmine-payload { position: absolute; display: none; right: -1px; border: 1px solid #8a4182; background-color: #eee; white-space: nowrap; padding: 4px 8px; }
44 | .jasmine_html-reporter .jasmine-run-options .jasmine-payload.jasmine-open { display: block; }
45 | .jasmine_html-reporter .jasmine-bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
46 | .jasmine_html-reporter .jasmine-bar.jasmine-failed { background-color: #ca3a11; }
47 | .jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; }
48 | .jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; }
49 | .jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
50 | .jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; }
51 | .jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; }
52 | .jasmine_html-reporter .jasmine-bar a { color: white; }
53 | .jasmine_html-reporter.jasmine-spec-list .jasmine-bar.jasmine-menu.jasmine-failure-list, .jasmine_html-reporter.jasmine-spec-list .jasmine-results .jasmine-failures { display: none; }
54 | .jasmine_html-reporter.jasmine-failure-list .jasmine-bar.jasmine-menu.jasmine-spec-list, .jasmine_html-reporter.jasmine-failure-list .jasmine-summary { display: none; }
55 | .jasmine_html-reporter .jasmine-results { margin-top: 14px; }
56 | .jasmine_html-reporter .jasmine-summary { margin-top: 14px; }
57 | .jasmine_html-reporter .jasmine-summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
58 | .jasmine_html-reporter .jasmine-summary ul.jasmine-suite { margin-top: 7px; margin-bottom: 7px; }
59 | .jasmine_html-reporter .jasmine-summary li.jasmine-passed a { color: #007069; }
60 | .jasmine_html-reporter .jasmine-summary li.jasmine-failed a { color: #ca3a11; }
61 | .jasmine_html-reporter .jasmine-summary li.jasmine-empty a { color: #ba9d37; }
62 | .jasmine_html-reporter .jasmine-summary li.jasmine-pending a { color: #ba9d37; }
63 | .jasmine_html-reporter .jasmine-summary li.jasmine-disabled a { color: #bababa; }
64 | .jasmine_html-reporter .jasmine-description + .jasmine-suite { margin-top: 0; }
65 | .jasmine_html-reporter .jasmine-suite { margin-top: 14px; }
66 | .jasmine_html-reporter .jasmine-suite a { color: #333; }
67 | .jasmine_html-reporter .jasmine-failures .jasmine-spec-detail { margin-bottom: 28px; }
68 | .jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description { background-color: #ca3a11; }
69 | .jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description a { color: white; }
70 | .jasmine_html-reporter .jasmine-result-message { padding-top: 14px; color: #333; white-space: pre; }
71 | .jasmine_html-reporter .jasmine-result-message span.jasmine-result { display: block; }
72 | .jasmine_html-reporter .jasmine-stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; }
73 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/jasmine_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironhack-labs/lab-javascript-functions-and-arrays/8ff766d48cfaec4c92933502f549cd08ebd9661f/jasmine/jasmine-2.8.0/jasmine_favicon.png
--------------------------------------------------------------------------------
/src/functions-and-arrays.js:
--------------------------------------------------------------------------------
1 | // Iteration #1: Find the maximum
2 | function maxOfTwoNumbers() {}
3 |
4 |
5 |
6 | // Iteration #2: Find longest word
7 | const words = ['mystery', 'brother', 'aviator', 'crocodile', 'pearl', 'orchard', 'crackpot'];
8 |
9 | function findLongestWord() {}
10 |
11 |
12 |
13 | // Iteration #3: Calculate the sum
14 | const numbers = [6, 12, 1, 18, 13, 16, 2, 1, 8, 10];
15 |
16 | function sumNumbers() {}
17 |
18 |
19 |
20 | // Iteration #3.1 Bonus:
21 | function sum() {}
22 |
23 |
24 |
25 | // Iteration #4: Calculate the average
26 | // Level 1: Array of numbers
27 | const numbersAvg = [2, 6, 9, 10, 7, 4, 1, 9];
28 |
29 | function averageNumbers() {}
30 |
31 |
32 | // Level 2: Array of strings
33 | const wordsArr = ['seat', 'correspond', 'linen', 'motif', 'hole', 'smell', 'smart', 'chaos', 'fuel', 'palace'];
34 |
35 | function averageWordLength() { }
36 |
37 | // Bonus - Iteration #4.1
38 | function avg() {}
39 |
40 | // Iteration #5: Unique arrays
41 | const wordsUnique = [
42 | 'crab',
43 | 'poison',
44 | 'contagious',
45 | 'simple',
46 | 'bring',
47 | 'sharp',
48 | 'playground',
49 | 'poison',
50 | 'communion',
51 | 'simple',
52 | 'bring'
53 | ];
54 |
55 | function uniquifyArray() {}
56 |
57 |
58 |
59 | // Iteration #6: Find elements
60 | const wordsFind = ['machine', 'subset', 'trouble', 'starting', 'matter', 'eating', 'truth', 'disobedience'];
61 |
62 | function doesWordExist() {}
63 |
64 |
65 |
66 | // Iteration #7: Count repetition
67 | const wordsCount = [
68 | 'machine',
69 | 'matter',
70 | 'subset',
71 | 'trouble',
72 | 'starting',
73 | 'matter',
74 | 'eating',
75 | 'matter',
76 | 'truth',
77 | 'disobedience',
78 | 'matter'
79 | ];
80 |
81 | function howManyTimes() {}
82 |
83 |
84 |
85 | // Iteration #8: Bonus
86 | const matrix = [
87 | [8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8],
88 | [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0],
89 | [81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65],
90 | [52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91],
91 | [22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80],
92 | [24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50],
93 | [32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70],
94 | [67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21],
95 | [24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72],
96 | [21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95],
97 | [78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92],
98 | [16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57],
99 | [86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58],
100 | [19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40],
101 | [4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66],
102 | [88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69],
103 | [4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36],
104 | [20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16],
105 | [20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54],
106 | [1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48]
107 | ];
108 |
109 | function greatestProduct() {}
110 |
111 |
112 |
113 |
114 | // The following is required to make unit tests work.
115 | /* Environment setup. Do not modify the below code. */
116 | if (typeof module !== 'undefined') {
117 | module.exports = {
118 | maxOfTwoNumbers,
119 | findLongestWord,
120 | sumNumbers,
121 | sum,
122 | averageNumbers,
123 | averageWordLength,
124 | avg,
125 | uniquifyArray,
126 | doesWordExist,
127 | howManyTimes,
128 | greatestProduct
129 | };
130 | }
131 |
--------------------------------------------------------------------------------
/tests/functions-and-arrays.spec.js:
--------------------------------------------------------------------------------
1 | const shuffle = (currentArray) => {
2 | const array = [...currentArray];
3 | let counter = array.length;
4 |
5 | while (counter > 0) {
6 | let randomIndex = Math.floor(Math.random() * counter);
7 | counter--;
8 | let temp = array[counter];
9 | array[counter] = array[randomIndex];
10 | array[randomIndex] = temp;
11 | }
12 | return array;
13 | };
14 |
15 |
16 |
17 | describe('Find the maximum', () => {
18 | it('should declare a function named maxOfTwoNumbers', () => {
19 | expect(typeof maxOfTwoNumbers).toBe('function');
20 | });
21 |
22 | it('should return greater of two arguments - if the first argument greater', () => {
23 | expect(maxOfTwoNumbers(2, 1)).toBe(2);
24 | expect(maxOfTwoNumbers(5, -7)).toBe(5);
25 | });
26 |
27 | it('should return greater of two arguments - if the second argument greater', () => {
28 | expect(maxOfTwoNumbers(1, 3)).toBe(3);
29 | expect(maxOfTwoNumbers(-5, 3)).toBe(3);
30 | });
31 |
32 | it('should return either arguments - if both arguments are equal', () => {
33 | expect(maxOfTwoNumbers(4, 4)).toBe(4);
34 | });
35 | });
36 |
37 | describe('Find the longest word', () => {
38 | it('should declare a function named findLongestWord', () => {
39 | expect(typeof findLongestWord).toBe('function');
40 | });
41 |
42 | it('should return null when called with an empty array', () => {
43 | expect(findLongestWord([])).toBe(null);
44 | });
45 |
46 | it('should return the word when called with a single-word array', () => {
47 | expect(findLongestWord(['foo'])).toBe('foo');
48 | });
49 |
50 | it('should return the first occurrence of the word when longest have multiple occurrences ', () => {
51 | expect(findLongestWord(['foo', 'bar'])).toBe('foo');
52 | expect(findLongestWord(['bar', 'foo'])).toBe('bar');
53 | });
54 |
55 | it('should return the longest occurrence when it has multiple words', () => {
56 | let words = ['a', 'zab', '12abc', '$$abcd', 'abcde', 'ironhack'];
57 | for (let i = 0; i < 10; i++) {
58 | words = shuffle(words);
59 | expect(findLongestWord(words)).toBe('ironhack');
60 | }
61 | });
62 | });
63 |
64 | describe('Calculate the sum of array of numbers', () => {
65 | it('should declare a function named sumNumbers', () => {
66 | expect(typeof sumNumbers).toBe('function');
67 | });
68 |
69 | it('should return zero if receives an empty array when called', () => {
70 | expect(sumNumbers([])).toBe(0);
71 | });
72 |
73 | it('should return the sum with one number array', () => {
74 | expect(sumNumbers([4])).toBe(4);
75 | });
76 |
77 | it('should return zero if all elements are zero', () => {
78 | expect(sumNumbers([0, 0, 0, 0, 0])).toBe(0);
79 | });
80 |
81 | it('should return the sum when passed array of numbers', () => {
82 | expect(sumNumbers([10, 5, 4, 32, 8])).toBe(59);
83 | });
84 | });
85 |
86 | describe('Bonus: Calculate the sum', () => {
87 | it('should declare a function named sum', () => {
88 | expect(typeof sum).toBe('function');
89 | });
90 |
91 | it('should return zero if receives an empty array when called', () => {
92 | expect(sum([])).toBe(0);
93 | });
94 |
95 | it('should return the sum with one number array', () => {
96 | expect(sum([4])).toBe(4);
97 | });
98 |
99 | it('should return zero if all elements are zero', () => {
100 | expect(sum([0, 0, 0, 0, 0])).toBe(0);
101 | });
102 |
103 | it('should return the sum when passed array of numbers', () => {
104 | expect(sum([10, 5, 4, 32, 8])).toBe(59);
105 | });
106 |
107 | it('should return the sum when passed array of strings', () => {
108 | expect(sum(['ana', 'marco', 'nicolas', 'tania', 'ptwd'])).toBe(24);
109 | });
110 |
111 | it('should return the sum when passed array of mixed strings and numbers - ', () => {
112 | expect(sum([6, 12, 'miami', 1, 'barca', '200', 'lisboa', 8, 10])).toBe(56);
113 | });
114 |
115 | it('should return the sum when passed array of mixed strings, numbers and booleans - ', () => {
116 | // false is counted as 0
117 | expect(sum([6, 12, 'miami', 1, 'barca', '200', 'lisboa', 8, false])).toBe(46);
118 | // true is counted as 1
119 | expect(sum([6, 12, 'miami', 1, 'barca', '200', 'lisboa', 8, true])).toBe(47);
120 | });
121 |
122 | it('should throw an error when unsupported data type (object or array) present in the array', () => {
123 | expect(() => sum([6, 12, 'miami', 1, 'barca', '200', 'lisboa', 8, [], {}])).toThrow();
124 | });
125 |
126 | });
127 |
128 | describe('Calculate the average of an array of numbers', () => {
129 | it('should declare a function named averageNumbers', () => {
130 | expect(typeof averageNumbers).toBe('function');
131 | });
132 |
133 | it('should return null if receives an empty array when called', () => {
134 | expect(averageNumbers([])).toBe(null);
135 | });
136 |
137 | it('should return the average of a one-element array', () => {
138 | expect(averageNumbers([9])).toBe(9);
139 | });
140 |
141 | it('should return the average even with negative values', () => {
142 | expect(averageNumbers([9, -3, -4, 6])).toBe(2);
143 | });
144 |
145 | it('should return the average of the array', () => {
146 | expect(averageNumbers([9, 10, 82, 92, 32, 102, 58])).toBe(55);
147 | });
148 |
149 | });
150 |
151 | describe('Calculate the average of an array of strings', () => {
152 | it('should declare a function named averageWordLength', () => {
153 | expect(typeof averageWordLength).toBe('function');
154 | });
155 |
156 | it('should return null if receives an empty array when called', () => {
157 | expect(averageWordLength([])).toBe(null);
158 | });
159 |
160 | it('should return the average of a one-element array', () => {
161 | expect(averageWordLength(['ironhack'])).toBe(8);
162 | });
163 |
164 | it('should return the average of a the array', () => {
165 | expect(
166 | averageWordLength(['Ironhack', 'Madrid', 'Barcelona', 'Paris', 'Miami', 'Mexico', 'Berlin', 'Programmers'])
167 | ).toBe(7);
168 | });
169 | });
170 |
171 | describe('Bonus: Calculate the average of a mixed elements array', () => {
172 | it('should declare a function named avg', () => {
173 | expect(typeof avg).toBe('function');
174 | });
175 |
176 | it('should return null if receives an empty array when called', () => {
177 | expect(avg([])).toBe(null);
178 | });
179 |
180 | it('should return the average of the array', () => {
181 | // false is counted as 0
182 | expect(avg([6, 12, 'miami', 1, 'barca', '200', 'lisboa', 8, false])).toBe(46/9);
183 | // true is counted as 1
184 | expect(avg([6, 12, 'miami', 1, 'barca', '200', 'lisboa', 8, true])).toBe(47/9);
185 | });
186 | });
187 |
188 | describe('Unique array', () => {
189 | it('should declare a function named uniquifyArray', () => {
190 | expect(typeof uniquifyArray).toBe('function');
191 | });
192 |
193 | it('should return null if receives an empty array when called', () => {
194 | expect(uniquifyArray([])).toEqual(null);
195 | });
196 |
197 | it('should return the correct uniqified array when an array of the same elements passed as argument', () => {
198 | expect(uniquifyArray(['Ironhack', 'Ironhack', 'Ironhack'])).toEqual(['Ironhack']);
199 | });
200 |
201 | it('should return the same array when no element is repeated', () => {
202 | expect(uniquifyArray(['Cat', 'Dog', 'Cow'])).toEqual(['Cat', 'Dog', 'Cow']);
203 | });
204 |
205 | it('should return the uniquified array', () => {
206 | expect(
207 | uniquifyArray(['iPhone', 'Samsung', 'Android', 'iOS', 'iPhone', 'Samsung', 'Nokia', 'Blackberry', 'Android'])
208 | ).toEqual(['iPhone', 'Samsung', 'Android', 'iOS', 'Nokia', 'Blackberry']);
209 | });
210 | });
211 |
212 | describe('Find elements', () => {
213 | it('should declare a function named doesWordExist', () => {
214 | expect(typeof doesWordExist).toBe('function');
215 | });
216 |
217 | it('should return null if receives an empty array when called', () => {
218 | expect(doesWordExist([])).toBe(null);
219 | });
220 |
221 | it('should return true if the word we are looking for is the only one in the array', () => {
222 | expect(doesWordExist(['machine'], 'machine')).toBe(true);
223 | });
224 |
225 | it('should return false if the word we are looking for is not in the array', () => {
226 | expect(doesWordExist(['machine', 'poison', 'eat', 'apple', 'horse'], 'ratatouille')).toBe(false);
227 | });
228 |
229 | it('should return true if the word we are looking for is in the array', () => {
230 | expect(doesWordExist(['pizza', 'sandwich', 'snack', 'soda', 'book', 'computer'], 'book')).toBe(true);
231 | });
232 | });
233 |
234 | describe('Count repetition', () => {
235 | it('should declare a function named howManyTimes', () => {
236 | expect(typeof howManyTimes).toBe('function');
237 | });
238 |
239 | it('should return 0 (zero) if receives an empty array when called', () => {
240 | expect(howManyTimes([])).toBe(0);
241 | });
242 |
243 | it('should return 1 (one) when the word appears only one time in the array', () => {
244 | expect(howManyTimes(['basketball', 'football', 'tennis'], 'tennis')).toBe(1);
245 | });
246 |
247 | it("should return 0 (zero) when the word doesn't appear in the array", () => {
248 | expect(howManyTimes(['basketball', 'football', 'tennis'], 'rugby')).toBe(0);
249 | });
250 |
251 | it('should return 5 (five) when the word appears 5 times in the array', () => {
252 | expect(
253 | howManyTimes(
254 | [
255 | 'basketball',
256 | 'football',
257 | 'tennis',
258 | 'rugby',
259 | 'rugby',
260 | 'ping pong',
261 | 'rugby',
262 | 'basketball',
263 | 'rugby',
264 | 'handball',
265 | 'rugby'
266 | ],
267 | 'rugby'
268 | )
269 | ).toBe(5);
270 | });
271 | });
272 |
273 | describe('Bonus Quest - greatestProduct', () => {
274 | it('should declare a function named greatestProduct', () => {
275 | expect(typeof greatestProduct).toBe('function');
276 | });
277 |
278 | it('should return 1 (one) when all numbers of the arrays are 1', () => {
279 | let matrix = [
280 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
281 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
282 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
283 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
284 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
285 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
286 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
287 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
288 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
289 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
290 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
291 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
292 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
293 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
294 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
295 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
296 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
297 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
298 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
299 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
300 | ];
301 | expect(greatestProduct(matrix)).toBe(1);
302 | });
303 |
304 | it('should return 16 when all the numbers of the arrays are 2', () => {
305 | let matrix = [
306 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
307 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
308 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
309 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
310 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
311 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
312 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
313 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
314 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
315 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
316 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
317 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
318 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
319 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
320 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
321 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
322 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
323 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
324 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
325 | [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
326 | ];
327 | expect(greatestProduct(matrix)).toBe(16);
328 | });
329 | });
330 |
--------------------------------------------------------------------------------