├── .github
├── stale.yml
└── workflows
│ └── test.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
├── data.js
└── movies.js
└── tests
└── movies.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: 21
5 |
6 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
7 | exemptLabels:
8 | - bug
9 | - enhancement
10 |
11 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
12 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
13 | daysUntilClose: 2
14 |
15 | # Label to use when marking as stale
16 | staleLabel: stale
17 |
18 | # Comment to post when marking as stale. Set to `false` to disable
19 | markComment: >
20 | 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
21 | for your contributions.
22 | closeComment: >
23 | This pull request is closed. Thank you.
24 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Automated Testing
2 | on: [push, pull_request]
3 | jobs:
4 | test:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - name: Load code
8 | uses: actions/checkout@v2
9 | - name: Prepare environment
10 | uses: actions/setup-node@v2
11 | with:
12 | node-version: '14'
13 | check-latest: true
14 | - name: Install dependencies
15 | run: npm i
16 | - name: Run tests
17 | run: npm run test -- --ci --reporters=default --reporters=jest-junit
18 | - name: Reports the results of tests
19 | uses: IgnusG/jest-report-action@v2.3.3
20 | if: always()
21 | with:
22 | access-token: ${{ secrets.GITHUB_TOKEN }}
23 | run-name: test
24 |
--------------------------------------------------------------------------------
/.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 | Greatest Movies of All Time
4 |
5 | 
6 |
7 |
8 |
9 |
Learning Goals
10 |
11 |
12 | This exercise allows you to practice and apply the concepts and techniques taught in class.
13 |
14 | Upon completion of this exercise, you will be able to:
15 |
16 | - Declare functions using the function expression and arrow function syntax.
17 | - Pass functions as arguments to other functions (callbacks).
18 | - Pass arrays and objects to functions as arguments.
19 | - Iterate over arrays using the `forEach()` method.
20 | - Manipulate arrays using the `map()` method.
21 | - Filter array elements using the `filter()` method.
22 | - Reduce array values using the `reduce()` method.
23 | - Sort arrays using the `sort()` method.
24 | - Explore and apply different ways to copy an array (`slice()` and spread operator `...`).
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## Introduction
32 |
33 | We have just learned some useful methods that will help us manipulate **objects and arrays**. In this exercise, we will practice working with these methods, and you are required to use at least one of them in each iteration.
34 |
35 |
36 |
37 | ## Requirements
38 |
39 | - Fork this repo.
40 | - Clone this repo.
41 |
42 |
43 |
44 | ## Submission
45 |
46 | - Upon completion, run the following commands:
47 |
48 | ```bash
49 | git add .
50 | git commit -m "Solved lab"
51 | git push origin master
52 | ```
53 |
54 | - Create a Pull Request so that your TAs can check your work.
55 |
56 |
57 |
58 | ## Test Your Code
59 |
60 | This LAB is equipped with unit tests to provide automated feedback on your lab progress. In case you want to check the tests, they are in the `tests/movies.spec.js` file.
61 |
62 | To run the tests and your JavaScript code, open the `SpecRunner.html` file using the [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) VSCode extension.
63 |
64 | To see the outputs of the `console.log` in your JavaScript code, open the [Console in the Developer Tools](https://developer.chrome.com/docs/devtools/open/#console).
65 |
66 |
67 |
68 | ## Instructions
69 |
70 | You will work on the `src/movies.js` file, which is already loaded in the `SpecRunner.html` file.
71 |
72 | The `src/data.js` file containing the array of movies is also loaded in the `SpecRunner.html` file.
73 |
74 |
75 |
76 | ## Iteration 0: Movies array
77 |
78 | The best way to practice is to work with real data. In the **`src/data.js`** file, you will find an array of info about **the best 250 movies of all times** according to [IMDB Ranking](http://www.imdb.com/chart/top?ref_=nv_mv_250_6) that you will use to display what each iteration asks!
79 |
80 | Here is an example of how the data is displayed:
81 |
82 | ```javascript
83 | {
84 | "title": "The Shawshank Redemption",
85 | "year": 1994,
86 | "director": "Frank Darabont",
87 | "duration": "2h 22min",
88 | "genre": ["Crime","Drama"],
89 | "score": 9.3
90 | }
91 | ```
92 |
93 | You will be digging deeper into some "facts" that this data set has. For example, we can use this data set to find the most popular movie, the average duration of the movie, the list of movies by some director, etc.
94 |
95 | In this iteration, no action is required, but here comes your challenge: In the following iterations, you will use your JS knowledge to manipulate this data.
96 |
97 | Remember to read each iteration description carefully before working on the solution.
98 |
99 |
100 |
101 | ### Iteration 1: All directors
102 |
103 | We need to get the array of all directors. Since this is a warm up, we will give you a hint: you have to _map_ through the array of movies and get all the directors into one array as a final result. Go ahead and create a function named `getAllDirectors()` that receives an array of movies as an argument and returns a new (_mapped_) array.
104 |
105 |
106 |
107 | #### Bonus - Iteration 1.1: _Clean_ the array of directors
108 |
109 | Some of the directors had directed multiple movies, so they will pop up multiple times in the array of directors. How could you "clean" this array and make it unified (meaning, without duplicates)? _Don't prioritize the bonus part now. You can return to it when you finish the mandatory iterations._ :wink:
110 |
111 |
112 |
113 | ### Iteration 2: Steven Spielberg. The best?
114 |
115 | One of the most famous directors in cinema is **[Steven Spielberg](https://en.wikipedia.org/wiki/Steven_Spielberg)**, and he has some really awesome drama movies that are on our list, but we want to know how many of them are there.
116 |
117 | Create a `howManyMovies()` function that receives an array as a parameter and `filter` :eyes: the array so we can have only the **drama** movies where **Steven Spielberg** is the director.
118 |
119 |
120 |
121 | ### Iteration 3: All scores average
122 |
123 | These are the best movies based on their scores, so they all have remarkable scores. In this iteration, we want to know the average score of all of them and display it on the console. Create a `scoresAverage()` function that receives an array as a parameter and solves the challenge.
124 |
125 | The score must be returned rounded to 2 decimals!
126 |
127 | **:bulb: Maybe you want to _"reduce"_ the data to a single value. :wink:**
128 |
129 |
130 |
131 | ### Iteration 4: Drama movies
132 |
133 | Drama is the genre that repeats the most on our `array`. Apparently, people love drama! :eyes:
134 |
135 | Create a `dramaMoviesScore()` function that receives an array as a parameter to get the average score of all drama movies! Let's see if it is better than the general average.
136 |
137 | Again, rounded to 2 decimals!
138 |
139 |
140 |
141 | ### Iteration 5: Order by year
142 |
143 | We need to sort the movies in ascending order by their release year. This should be easy using one of the **methods** we have just learned. :wink:
144 | Create a function `orderByYear()` that receives an array as a parameter and returns a _new sorted array_.
145 |
146 | 
147 |
148 | If two movies have the same year, order them in alphabetical order by their title! :heavy_check_mark:
149 |
150 | :warning: **Important:** Your function should *return a new array*, containing the movies ordered by the year. Your function should not modify (mutate) the original array. You may need to research how to make a "copy" or "clone" an array.
151 |
152 |
153 |
154 | ### Iteration 6: Alphabetic order
155 |
156 | Another popular way to order the movies is to sort them alphabetically using the `title` key. However, in this case, we only need to print the title of the first 20. Easy peasy for an expert like you. :wink:
157 |
158 | Create an `orderAlphabetically()` function that receives an array and returns an array of the first 20 titles, alphabetically ordered. Return only the title of each movie, and if the array you receive has less than 20 movies, return all of them.
159 |
160 |
161 |
162 | :warning: **Important:** Your function should *return a new array*, containing movie objects sorted alphabetically. Your function should not modify (mutate) the original array. You may need to research how to make a "copy" or "clone" an array.
163 |
164 |
165 |
166 | ### BONUS - Iteration 7: Time format
167 |
168 | We got the info from the **IMDB** web page, but the duration info was saved in a format that is difficult for us to compare movies.
169 |
170 | Finding the longest movie is almost impossible using that format, so let's change it!
171 |
172 | - Create a `turnHoursToMinutes()` function that receives an array as a parameter and, with some _magic_ implemented by you - replaces the duration info of each of the movies for its equivalent in minutes. For example:
173 |
174 | ```javascript
175 | {
176 | "title": "The Shawshank Redemption",
177 | "year": 1994,
178 | "director": "Frank Darabont",
179 | "duration": "2h 22min",
180 | "genre": ["Crime","Drama"],
181 | "score" :9.3
182 | }
183 | ```
184 |
185 | Should be:
186 |
187 | ```javascript
188 | {
189 | "title": "The Shawshank Redemption",
190 | "year": 1994,
191 | "director": "Frank Darabont",
192 | "duration": 142,
193 | "genre": ["Crime","Drama"],
194 | "score": 9.3
195 | }
196 | ```
197 |
198 |
199 |
200 | :warning: **Important:** Your function should *return a new array*, containing movie objects with the duration time in minutes. Your function should not modify (mutate) the original array.
201 |
202 |
203 |
204 | ### BONUS - Iteration 8: Best yearly score average
205 |
206 | We always hear so much about classic movies, but we want to know which year has the best average score so that we can declare the **BEST YEAR FOR CINEMA** officially!
207 |
208 | Go ahead and find which year has the best average score for the movies released that year!
209 | Create `bestYearAvg()` function that receives an array of movies and gives us an answer to which year was the best year for cinema and what was its average score. The `bestYearAvg()` should return a **string** with the following structure:
210 |
211 |
212 | **The best year was \ with an average score of \**
213 |
214 |
215 |
216 | 
217 |
218 |
219 |
220 | **Happy coding!** :blue_heart:
221 |
222 |
223 |
224 | ## FAQs
225 |
226 |
227 |
228 |
229 | I am stuck in the exercise and don't know how to solve the problem or where to start.
230 |
231 |
232 |
233 | 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.
234 |
235 |
236 | For example, is it a concept you don't understand, or are you receiving an error message you don't know how to fix? It is usually helpful to state the problem as clearly as possible, including any error messages you receive. This can help you communicate the issue to others and potentially get help from classmates or online resources.
237 |
238 |
239 | Once you have a clear understanding of the problem, you will be able to start working toward the solution.
240 |
241 | [Back to top](#faqs)
242 |
243 |
244 |
245 |
246 | All of the Jasmine tests are failing and in red. Why did this happen?
247 |
248 |
249 |
250 | 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.
251 |
252 | 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.
253 |
254 | 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.
255 |
256 | [Back to top](#faqs)
257 |
258 |
259 |
260 |
261 | How do I loop over an array using the forEach() method?
262 |
263 |
264 |
265 | 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.
266 |
267 | The syntax of the `forEach()` method is as follows:
268 |
269 | ```js
270 | array.forEach( function(element) {
271 | // code to be executed for each element
272 | });
273 | ```
274 |
275 | Here is an example that uses the `forEach()` method to log each element and its index in an array to the console:
276 |
277 | ```js
278 | const fruits = ["apple", "banana", "cherry"];
279 |
280 | fruits.forEach( function(element, index) {
281 | console.log(`${index}: ${element}`);
282 | });
283 | ```
284 |
285 | You can also use an arrow function as the callback function for `forEach()`:
286 |
287 | ```js
288 | fruits.forEach((element, index) => {
289 | console.log(`${index}: ${element}`);
290 | });
291 | ```
292 |
293 | [Back to top](#faqs)
294 |
295 |
296 |
297 |
298 | How to use the filter() array method?
299 |
300 |
301 | The `filter()` method is used for iterating through an array and selecting only certain elements to include in a new array.
302 |
303 | The `filter()` method returns a new array with all elements that pass a certain condition. The `filter()` method takes a callback function as an argument.
304 |
305 | The callback function should return a boolean value (`true` / `false`) or a *truthy*/*falsy* value:
306 |
307 | - If the callback function returns `true` for a particular element, that element will be included in the new array.
308 | - If the callback function returns `false` for a particular element, that element will be excluded from the new array.
309 |
310 | Here is an example of filtering an array to get a new array containing only students that have a course property of `"Web Dev"`:
311 |
312 | ```js
313 | const students = [
314 | { name: "Anna", course: "Web Dev" },
315 | { name: "Bill", course: "UX/UI" },
316 | { name: "Cori", course: "Data" },
317 | { name: "Dave", course: "Web Dev" },
318 | { name: "Erin", course: "UX/UI" }
319 | ];
320 |
321 | const webDevStudents = students.filter( function(el) {
322 | return el.course === "Web Dev";
323 | });
324 |
325 | console.log(webDevStudents);
326 | // Output:
327 | // [
328 | // {name: "Anna", course: "Web Dev"},
329 | // {name: "Dave", course: "Web Dev"}
330 | // ]
331 | ```
332 |
333 |
334 |
335 | [Back to top](#faqs)
336 |
337 |
338 |
339 |
340 | How to use the map() array method?
341 |
342 |
343 | The `map()` method is used to create a new array by returning a value for each element in an array.
344 |
345 | The `filter()` method takes a callback function as an argument. The `map()` method returns a new array containing the values returned from the callback function.
346 |
347 | Here is an example of using the `map()` method to extract the `grade` property from each student object in the `students` array and create a new array with the grades:
348 |
349 | ```js
350 | const students = [
351 | { name: "Anna", grade: 8 },
352 | { name: "Bill", grade: 9 },
353 | { name: "Cloe", grade: 7 }
354 | ];
355 |
356 | // Use map() to extract the 'grade' from each student object
357 | const studentGrades = students.map(function (student) {
358 | // Return the value to be included in the new array
359 | return student.grade;
360 | });
361 |
362 |
363 | console.log(studentGrades); // Output: [8, 9, 7]
364 | ```
365 |
366 |
367 |
368 | [Back to top](#faqs)
369 |
370 |
371 |
372 |
373 | How to use the sort() array method?
374 |
375 |
376 | The `sort()` method is used to sort the elements of an array in place. This means the original array is mutated and the sorted elements are rearranged within the same array.
377 |
378 | The default sort order is based on converting the elements into strings and then comparing their sequences of UTF-16 Unicode values. This means that the `sort()` method can be used directly to sort an array of strings in alphabetical order. However, when working with numbers, the default sort order may not produce the desired result and it is necessary to provide a sorting function as an argument to the `sort()` method.
379 |
380 | #### Sorting numbers - ascending order
381 |
382 | Here is an example of using the `sort()` method to sort an array of numbers in ascending order:
383 |
384 | ```js
385 | const numbers = [5, 2, 3, 1, 4];
386 |
387 | numbers.sort((a, b) => a - b);
388 |
389 | console.log(numbers); // Output: [1, 2, 3, 4, 5]
390 | ```
391 |
392 |
393 |
394 | #### Sorting numbers - ascending order
395 |
396 | Here is an example of using the `sort()` method to sort an array of numbers in descending order:
397 |
398 | ```js
399 | const numbers = [5, 2, 3, 1, 4];
400 |
401 | numbers.sort((a, b) => b - a);
402 |
403 | console.log(numbers); // Output: [5, 4, 3, 2, 1]
404 | ```
405 |
406 |
407 |
408 | #### Sorting strings - ascending order A-Z
409 |
410 | Here is an example of using the `sort()` method to sort an array of strings in ascending order (A-Z):
411 |
412 | ```js
413 | const words = ["cherry", "apple", "blueberry"];
414 |
415 | words.sort((a, b) => a.localeCompare(b));
416 |
417 | console.log(words); // Output: ["apple", "blueberry", "cherry"]
418 | ```
419 |
420 | The `localeCompare()` method is used to compare the strings in alphabetical order. In the above example `localeCompare()` method returns a negative value if `a` comes before `b` in the sort order, a positive value if `a` comes after `b`, and 0 if they are equal. This causes the strings to be sorted in ascending order (A-Z).
421 |
422 |
423 |
424 | #### Sorting strings - descending order Z-A
425 |
426 | Alternatively, you can use the default sort order by simply calling the `sort()` method without a compare function:
427 |
428 | ```js
429 | const words = ["cherry", "apple", "blueberry"];
430 |
431 | words.sort();
432 |
433 | console.log(words); // Output: ["apple", "blueberry", "cherry"]
434 | ```
435 |
436 |
437 |
438 | [Back to top](#faqs)
439 |
440 |
441 |
442 |
443 | How to use the reduce() array method?
444 |
445 |
446 | The `reduce()` method is used to reduce an array of values to a single value by adding each element to the accumulator.
447 |
448 |
449 |
450 | #### Syntax
451 |
452 | The `reduce()` method takes two arguments: a *callback function* and the *initial value*.
453 |
454 | ```js
455 | array.reduce((accumulator, element, index, array) => {}, initialValue);
456 | ```
457 |
458 | The callback function takes four arguments:
459 |
460 | - `accumulator`: the accumulated value. The `accumulator` is initialized with the value passed as the second argument: `initialValue`.
461 | - `element`: the current element being processed in the array
462 | - `index`: *(optional)* the index of the current element being processed in the array
463 | - `array`: *(optional)* the original array
464 |
465 |
466 |
467 | #### Example
468 |
469 | Here is an example of using the `reduce()` method to calculate the sum of all `grade` values in an array:
470 |
471 | ```js
472 | const students = [
473 | { name: "John", grade: 8 },
474 | { name: "Jane", grade: 9 },
475 | { name: "Bob", grade: 7 }
476 | ];
477 |
478 | const gradesTotal = students.reduce((accumulator, element) {
479 | // For each array element, add its 'grade' to the accumulator
480 | const newAccumulator = accumulator + element.grade;
481 | // Return the new accumulator value for the next iteration
482 | return newAccumulator;
483 | }, 0);
484 |
485 | console.log(gradesTotal); // Output: 24
486 | ```
487 |
488 | In the above example, the accumulator was initialized with the initial value of `0`.
489 |
490 | The callback function adds the `grade` of the current element to the accumulator on each iteration. The returned value becomes the new accumulator value for the next iteration. The `reduce()` method returns the final value of the accumulator, which is the sum of all elements in the array.
491 |
492 |
493 |
494 | [Back to top](#faqs)
495 |
496 |
497 |
498 |
499 | How to use the slice() array method?
500 |
501 |
502 | The `slice()` method is used to copy a portion of an array and return it as a new array. The `slice()` method doesn't mutate the original array.
503 |
504 |
505 |
506 | #### Syntax
507 |
508 | ```js
509 | const newArray = array.slice(start, end);
510 | ```
511 |
512 | - `start` is the index at which the slice begins.
513 | - `end` is the index at which the slice ends.
514 |
515 |
516 |
517 | The `slice()` method extracts elements from the original array and includes them in the new array up to, but not including, the `end` index. If the `end` index is not provided, the `slice()` method will extract elements from the `start` index to the *end of the original array*.
518 |
519 |
520 |
521 | Here is an example of using the `slice()` method to copy array elements:
522 |
523 | ```js
524 | const strings = ["a", "b", "c", "d", "e"];
525 |
526 | // Extract elements from index 1 to index 3
527 | const slice = strings.slice(1, 3);
528 |
529 | console.log(slice); // Output: ["b", "c"]
530 | ```
531 |
532 |
533 |
534 | [Back to top](#faqs)
535 |
536 |
537 |
538 |
539 | I am unable to push changes to the repository. What should I do?
540 |
541 |
542 | There are a couple of possible reasons why you may be unable to *push* changes to a Git repository:
543 |
544 | 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:
545 | ```bash
546 | git add .
547 | git commit -m "Your commit message"
548 | git push
549 | ```
550 | 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.
551 | To check which remote repository you have cloned, run the following terminal command from the project folder:
552 | ```bash
553 | git remote -v
554 | ```
555 | 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.
556 |
557 | **Note**: You should make a copy of your local code to avoid losing it in the process.
558 |
559 | [Back to top](#faqs)
560 |
561 |
562 |
--------------------------------------------------------------------------------
/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 |
24 |
--------------------------------------------------------------------------------
/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-greatest-movies/45f28b667dd10b018cd672d147ac78e41c6bf95d/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 | Greatest Movies of All Time'));
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-greatest-movies/45f28b667dd10b018cd672d147ac78e41c6bf95d/jasmine/jasmine-2.8.0/jasmine_favicon.png
--------------------------------------------------------------------------------
/src/data.js:
--------------------------------------------------------------------------------
1 | const movies = [
2 | {
3 | title: 'The Shawshank Redemption',
4 | year: 1994,
5 | director: 'Frank Darabont',
6 | duration: '2h 22min',
7 | genre: ['Crime', 'Drama'],
8 | score: 9.3
9 | },
10 | {
11 | title: 'The Godfather',
12 | year: 1972,
13 | director: 'Francis Ford Coppola',
14 | duration: '2h 55min',
15 | genre: ['Crime', 'Drama'],
16 | score: 9.2
17 | },
18 | {
19 | title: 'The Godfather: Part II',
20 | year: 1974,
21 | director: 'Francis Ford Coppola',
22 | duration: '3h 22min',
23 | genre: ['Crime', 'Drama'],
24 | score: 9
25 | },
26 | {
27 | title: 'The Dark Knight',
28 | year: 2008,
29 | director: 'Christopher Nolan',
30 | duration: '2h 32min',
31 | genre: ['Action', 'Crime', 'Drama', 'Thriller'],
32 | score: 9
33 | },
34 | {
35 | title: '12 Angry Men',
36 | year: 1957,
37 | director: 'Sidney Lumet',
38 | duration: '1h 36min',
39 | genre: ['Crime', 'Drama'],
40 | score: 8.9
41 | },
42 | {
43 | title: 'Schindler"s List',
44 | year: 1993,
45 | director: 'Steven Spielberg',
46 | duration: '3h 15min',
47 | genre: ['Biography', 'Drama', 'History'],
48 | score: 8.9
49 | },
50 | {
51 | title: 'Pulp Fiction',
52 | year: 1994,
53 | director: 'Quentin Tarantino',
54 | duration: '2h 34min',
55 | genre: ['Crime', 'Drama'],
56 | score: 8.9
57 | },
58 | {
59 | title: 'The Lord of the Rings: The Return of the King',
60 | year: 2003,
61 | director: 'Peter Jackson',
62 | duration: '3h 21min',
63 | genre: ['Adventure', 'Drama', 'Fantasy'],
64 | score: 8.9
65 | },
66 | {
67 | title: 'Il buono, il brutto, il cattivo',
68 | year: 1966,
69 | director: 'Sergio Leone',
70 | duration: '3h 2min',
71 | genre: ['Western'],
72 | score: 8.9
73 | },
74 | {
75 | title: 'Fight Club',
76 | year: 1999,
77 | director: 'David Fincher',
78 | duration: '2h 19min',
79 | genre: ['Drama'],
80 | score: 8.8
81 | },
82 | {
83 | title: 'The Lord of the Rings: The Fellowship of the Ring',
84 | year: 2001,
85 | director: 'Peter Jackson',
86 | duration: '2h 58min',
87 | genre: ['Adventure', 'Drama', 'Fantasy'],
88 | score: 8.8
89 | },
90 | {
91 | title: 'Forrest Gump',
92 | year: 1994,
93 | director: 'Robert Zemeckis',
94 | duration: '2h 22min',
95 | genre: ['Comedy', 'Drama', 'Romance'],
96 | score: 8.8
97 | },
98 | {
99 | title: 'Star Wars: Episode V - The Empire Strikes Back',
100 | year: 1980,
101 | director: 'Irvin Kershner',
102 | duration: '2h 4min',
103 | genre: ['Action', 'Adventure', 'Fantasy', 'Sci-Fi'],
104 | score: 8.8
105 | },
106 | {
107 | title: 'Inception',
108 | year: 2010,
109 | director: 'Christopher Nolan',
110 | duration: '2h 28min',
111 | genre: ['Action', 'Adventure', 'Sci-Fi', 'Thriller'],
112 | score: 8.8
113 | },
114 | {
115 | title: 'The Lord of the Rings: The Two Towers',
116 | year: 2002,
117 | director: 'Peter Jackson',
118 | duration: '2h 59min',
119 | genre: ['Adventure', 'Drama', 'Fantasy'],
120 | score: 8.7
121 | },
122 | {
123 | title: 'One Flew Over the Cuckoo"s Nest',
124 | year: 1975,
125 | director: 'Milos Forman',
126 | duration: '2h 13min',
127 | genre: ['Drama'],
128 | score: 8.7
129 | },
130 | {
131 | title: 'Goodfellas',
132 | year: 1990,
133 | director: 'Martin Scorsese',
134 | duration: '2h 26min',
135 | genre: ['Crime', 'Drama'],
136 | score: 8.7
137 | },
138 | {
139 | title: 'The Matrix',
140 | year: 1999,
141 | director: 'Lana Wachowski',
142 | duration: '2h 16min',
143 | genre: ['Action', 'Sci-Fi'],
144 | score: 8.7
145 | },
146 | {
147 | title: 'Shichinin no samurai',
148 | year: 1954,
149 | director: 'Akira Kurosawa',
150 | duration: '3h 27min',
151 | genre: ['Adventure', 'Drama'],
152 | score: 8.7
153 | },
154 | {
155 | title: 'Star Wars',
156 | year: 1977,
157 | director: 'George Lucas',
158 | duration: '2h 1min',
159 | genre: ['Action', 'Adventure', 'Fantasy', 'Sci-Fi'],
160 | score: 8.7
161 | },
162 | {
163 | title: 'Cidade de Deus',
164 | year: 2002,
165 | director: 'Fernando Meirelles',
166 | duration: '2h 10min',
167 | genre: ['Crime', 'Drama'],
168 | score: 8.7
169 | },
170 | {
171 | title: 'Se7en',
172 | year: 1995,
173 | director: 'David Fincher',
174 | duration: '2h 7min',
175 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
176 | score: 8.6
177 | },
178 | {
179 | title: 'The Silence of the Lambs',
180 | year: 1991,
181 | director: 'Jonathan Demme',
182 | duration: '1h 58min',
183 | genre: ['Crime', 'Drama', 'Thriller'],
184 | score: 8.6
185 | },
186 | {
187 | title: 'It"s a Wonderful Life',
188 | year: 1946,
189 | director: 'Frank Capra',
190 | duration: '2h 10min',
191 | genre: ['Drama', 'Family', 'Fantasy'],
192 | score: 8.6
193 | },
194 | {
195 | title: 'La vita è bella',
196 | year: 1997,
197 | director: 'Roberto Benigni',
198 | duration: '1h 56min',
199 | genre: ['Comedy', 'Drama', 'War'],
200 | score: 8.6
201 | },
202 | {
203 | title: 'The Usual Suspects',
204 | year: 1995,
205 | director: 'Bryan Singer',
206 | duration: '1h 46min',
207 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
208 | score: 8.6
209 | },
210 | {
211 | title: 'Léon',
212 | year: 1988,
213 | director: 'Luc Besson',
214 | duration: '1h 50min',
215 | genre: ['Crime', 'Drama', 'Thriller'],
216 | score: 8.6
217 | },
218 | {
219 | title: 'Saving Private Ryan',
220 | year: 1998,
221 | director: 'Steven Spielberg',
222 | duration: '2h 49min',
223 | genre: ['Drama', 'War'],
224 | score: 8.6
225 | },
226 | {
227 | title: 'Sen to Chihiro no kamikakushi',
228 | year: 2001,
229 | director: 'Hayao Miyazaki',
230 | duration: '2h 5min',
231 | genre: ['Animation', 'Adventure', 'Family', 'Fantasy', 'Mystery'],
232 | score: 8.6
233 | },
234 | {
235 | title: 'American History X',
236 | year: 1998,
237 | director: 'Tony Kaye',
238 | duration: '1h 59min',
239 | genre: ['Crime', 'Drama'],
240 | score: 8.5
241 | },
242 | {
243 | title: 'C"era una volta il West',
244 | year: 1968,
245 | director: 'Sergio Leone',
246 | duration: '2h 44min',
247 | genre: ['Western'],
248 | score: 8.6
249 | },
250 | {
251 | title: 'Interstellar',
252 | year: 2014,
253 | director: 'Christopher Nolan',
254 | duration: '2h 49min',
255 | genre: ['Adventure', 'Drama', 'Sci-Fi'],
256 | score: 8.6
257 | },
258 | {
259 | title: 'Psycho',
260 | year: 1960,
261 | director: 'Alfred Hitchcock',
262 | duration: '1h 49min',
263 | genre: ['Horror', 'Mystery', 'Thriller'],
264 | score: 8.5
265 | },
266 | {
267 | title: 'The Green Mile',
268 | year: 1999,
269 | director: 'Frank Darabont',
270 | duration: '3h 9min',
271 | genre: ['Crime', 'Drama', 'Fantasy', 'Mystery'],
272 | score: 8.5
273 | },
274 | {
275 | title: 'Casablanca',
276 | year: 1942,
277 | director: 'Michael Curtiz',
278 | duration: '1h 42min',
279 | genre: ['Drama', 'Romance', 'War'],
280 | score: 8.5
281 | },
282 | {
283 | title: 'City Lights',
284 | year: 1931,
285 | director: 'Charles Chaplin',
286 | duration: '1h 27min',
287 | genre: ['Comedy', 'Drama', 'Romance'],
288 | score: 8.6
289 | },
290 | {
291 | title: 'Intouchables',
292 | year: 2011,
293 | director: 'Olivier Nakache',
294 | duration: '1h 52min',
295 | genre: ['Biography', 'Comedy', 'Drama'],
296 | score: 8.6
297 | },
298 | {
299 | title: 'Modern Times',
300 | year: 1936,
301 | director: 'Charles Chaplin',
302 | duration: '1h 27min',
303 | genre: ['Comedy', 'Drama', 'Family', 'Romance'],
304 | score: 8.5
305 | },
306 | {
307 | title: 'Raiders of the Lost Ark',
308 | year: 1981,
309 | director: 'Steven Spielberg',
310 | duration: '1h 55min',
311 | genre: ['Action', 'Adventure'],
312 | score: 8.5
313 | },
314 | {
315 | title: 'The Pianist',
316 | year: 2002,
317 | director: 'Roman Polanski',
318 | duration: '2h 30min',
319 | genre: ['Biography', 'Drama', 'Music', 'War'],
320 | score: 8.5
321 | },
322 | {
323 | title: 'The Departed',
324 | year: 2006,
325 | director: 'Martin Scorsese',
326 | duration: '2h 31min',
327 | genre: ['Crime', 'Drama', 'Thriller'],
328 | score: 8.5
329 | },
330 | {
331 | title: 'Rear Window',
332 | year: 1954,
333 | director: 'Alfred Hitchcock',
334 | duration: '1h 52min',
335 | genre: ['Mystery', 'Thriller'],
336 | score: 8.5
337 | },
338 | {
339 | title: 'Terminator 2: Judgment Day',
340 | year: 1991,
341 | director: 'James Cameron',
342 | duration: '2h 17min',
343 | genre: ['Action', 'Sci-Fi', 'Thriller'],
344 | score: 8.5
345 | },
346 | {
347 | title: 'Back to the Future',
348 | year: 1985,
349 | director: 'Robert Zemeckis',
350 | duration: '1h 56min',
351 | genre: ['Adventure', 'Comedy', 'Sci-Fi'],
352 | score: 8.5
353 | },
354 | {
355 | title: 'Whiplash',
356 | year: 2014,
357 | director: 'Damien Chazelle',
358 | duration: '1h 47min',
359 | genre: ['Drama', 'Music'],
360 | score: 8.5
361 | },
362 | {
363 | title: 'Gladiator',
364 | year: 2000,
365 | director: 'Ridley Scott',
366 | duration: '2h 35min',
367 | genre: ['Action', 'Adventure', 'Drama'],
368 | score: 8.5
369 | },
370 | {
371 | title: 'The Prestige',
372 | year: 1994,
373 | director: 'Christopher Nolan',
374 | duration: '2h 10min',
375 | genre: ['Drama', 'Mystery', 'Sci-Fi', 'Thriller'],
376 | score: 8.5
377 | },
378 | {
379 | title: 'The Lion King',
380 | year: 1994,
381 | director: 'Roger Allers',
382 | duration: '1h 28min',
383 | genre: ['Animation', 'Adventure', 'Drama', 'Family', 'Musical'],
384 | score: 8.5
385 | },
386 | {
387 | title: 'Memento',
388 | year: 2000,
389 | director: 'Christopher Nolan',
390 | duration: '1h 53min',
391 | genre: ['Mystery', 'Thriller'],
392 | score: 8.5
393 | },
394 | {
395 | title: 'Apocalypse Now',
396 | year: 1979,
397 | director: 'Francis Ford Coppola',
398 | duration: '2h 27min',
399 | genre: ['Drama', 'War'],
400 | score: 8.5
401 | },
402 | {
403 | title: 'Alien',
404 | year: 1979,
405 | director: 'Ridley Scott',
406 | duration: '1h 57min',
407 | genre: ['Horror', 'Sci-Fi'],
408 | score: 8.5
409 | },
410 | {
411 | title: 'The Great Dictator',
412 | year: 1940,
413 | director: 'Charles Chaplin',
414 | duration: '2h 5min',
415 | genre: ['Comedy', 'Drama', 'War'],
416 | score: 8.5
417 | },
418 | {
419 | title: 'Sunset Blvd.',
420 | year: 1950,
421 | director: 'Billy Wilder',
422 | duration: '1h 50min',
423 | genre: ['Drama', 'Film-Noir'],
424 | score: 8.5
425 | },
426 | {
427 | title:
428 | 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb',
429 | year: 1964,
430 | director: 'Stanley Kubrick',
431 | duration: '1h 35min',
432 | genre: ['Comedy'],
433 | score: 8.5
434 | },
435 | {
436 | title: 'Nuovo Cinema Paradiso',
437 | year: 1988,
438 | director: 'Giuseppe Tornatore',
439 | duration: '2h 35min',
440 | genre: ['Drama'],
441 | score: 8.5
442 | },
443 | {
444 | title: 'Das Leben der Anderen',
445 | year: 2006,
446 | director: 'Florian Henckel von Donnersmarck',
447 | duration: '2h 17min',
448 | genre: ['Drama', 'Thriller'],
449 | score: 8.5
450 | },
451 | {
452 | title: 'Hotaru no haka',
453 | year: 1988,
454 | director: 'Isao Takahata',
455 | duration: '1h 29min',
456 | genre: ['Animation', 'Drama', 'War'],
457 | score: 8.5
458 | },
459 | {
460 | title: 'Blade Runner 2049',
461 | year: 2017,
462 | director: 'Denis Villeneuve',
463 | duration: '2h 44min',
464 | genre: ['Mystery', 'Sci-Fi', 'Thriller'],
465 | score: 8.5
466 | },
467 | {
468 | title: 'Paths of Glory',
469 | year: 1957,
470 | director: 'Stanley Kubrick',
471 | duration: '1h 28min',
472 | genre: ['Drama', 'War'],
473 | score: 8.4
474 | },
475 | {
476 | title: 'Django Unchained',
477 | year: 2012,
478 | director: 'Quentin Tarantino',
479 | duration: '2h 45min',
480 | genre: ['Drama', 'Western'],
481 | score: 8.4
482 | },
483 | {
484 | title: 'The Shining',
485 | year: 1980,
486 | director: 'Stanley Kubrick',
487 | duration: '2h 26min',
488 | genre: ['Drama', 'Horror'],
489 | score: 8.4
490 | },
491 | {
492 | title: 'WALL·E',
493 | year: 2008,
494 | director: 'Andrew Stanton',
495 | duration: '1h 38min',
496 | genre: ['Animation', 'Adventure', 'Family', 'Sci-Fi'],
497 | score: 8.4
498 | },
499 | {
500 | title: 'American Beauty',
501 | year: 1999,
502 | director: 'Sam Mendes',
503 | duration: '2h 2min',
504 | genre: ['Drama', 'Romance'],
505 | score: 8.4
506 | },
507 | {
508 | title: 'The Dark Knight Rises',
509 | year: 2012,
510 | director: 'Christopher Nolan',
511 | duration: '2h 44min',
512 | genre: ['Action', 'Thriller'],
513 | score: 8.4
514 | },
515 | {
516 | title: 'Mononoke-hime',
517 | year: 1997,
518 | director: 'Hayao Miyazaki',
519 | duration: '2h 14min',
520 | genre: ['Animation', 'Adventure', 'Fantasy'],
521 | score: 8.4
522 | },
523 | {
524 | title: 'Oldeuboi',
525 | year: 2003,
526 | director: 'Chan-wook Park',
527 | duration: '2h',
528 | genre: ['Action', 'Drama', 'Mystery', 'Thriller'],
529 | score: 8.4
530 | },
531 | {
532 | title: 'Aliens',
533 | year: 1986,
534 | director: 'James Cameron',
535 | duration: '2h 17min',
536 | genre: ['Action', 'Adventure', 'Sci-Fi', 'Thriller'],
537 | score: 8.4
538 | },
539 | {
540 | title: 'Witness for the Prosecution',
541 | year: 1957,
542 | director: 'Billy Wilder',
543 | duration: '1h 56min',
544 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
545 | score: 8.4
546 | },
547 | {
548 | title: 'Once Upon a Time in America',
549 | year: 1984,
550 | director: 'Sergio Leone',
551 | duration: '3h 49min',
552 | genre: ['Crime', 'Drama'],
553 | score: 8.4
554 | },
555 | {
556 | title: 'Das Boot',
557 | year: 1981,
558 | director: 'Wolfgang Petersen',
559 | duration: '2h 29min',
560 | genre: ['Adventure', 'Drama', 'Thriller', 'War'],
561 | score: 8.4
562 | },
563 | {
564 | title: 'Citizen Kane',
565 | year: 1941,
566 | director: 'Orson Welles',
567 | duration: '1h 59min',
568 | genre: ['Drama', 'Mystery'],
569 | score: 8.4
570 | },
571 | {
572 | title: 'Dangal',
573 | year: 2016,
574 | director: 'Nitesh Tiwari',
575 | duration: '2h 41min',
576 | genre: ['Action', 'Biography', 'Drama', 'Sport'],
577 | score: 8.6
578 | },
579 | {
580 | title: 'Vertigo',
581 | year: 2001,
582 | director: 'Alfred Hitchcock',
583 | duration: '2h 8min',
584 | genre: ['Mystery', 'Romance', 'Thriller'],
585 | score: 8.4
586 | },
587 | {
588 | title: 'North by Northwest',
589 | year: 1959,
590 | director: 'Alfred Hitchcock',
591 | duration: '2h 16min',
592 | genre: ['Action', 'Adventure', 'Mystery', 'Thriller'],
593 | score: 8.4
594 | },
595 | {
596 | title: 'Star Wars: Episode VI - Return of the Jedi',
597 | year: 1983,
598 | director: 'Richard Marquand',
599 | duration: '2h 11min',
600 | genre: ['Action', 'Adventure', 'Fantasy', 'Sci-Fi'],
601 | score: 8.4
602 | },
603 | {
604 | title: 'Braveheart',
605 | year: 1995,
606 | director: 'Mel Gibson',
607 | duration: '2h 58min',
608 | genre: ['Biography', 'Drama', 'History', 'War'],
609 | score: 8.4
610 | },
611 | {
612 | title: 'Reservoir Dogs',
613 | year: 1992,
614 | director: 'Quentin Tarantino',
615 | duration: '1h 39min',
616 | genre: ['Crime', 'Drama', 'Thriller'],
617 | score: 8.3
618 | },
619 | {
620 | title: 'M',
621 | year: 1931,
622 | director: 'Fritz Lang',
623 | duration: '1h 57min',
624 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
625 | score: 8.4
626 | },
627 | {
628 | title: 'Requiem for a Dream',
629 | year: 2000,
630 | director: 'Darren Aronofsky',
631 | duration: '1h 42min',
632 | genre: ['Drama'],
633 | score: 8.3
634 | },
635 | {
636 | title: 'Le fabuleux destin d"Amélie Poulain',
637 | year: 2001,
638 | director: 'Jean-Pierre Jeunet',
639 | duration: '2h 2min',
640 | genre: ['Comedy', 'Romance'],
641 | score: 8.4
642 | },
643 | {
644 | title: 'Taare Zameen Par',
645 | year: 2007,
646 | director: 'Aamir Khan',
647 | duration: '2h 45min',
648 | genre: ['Drama', 'Family'],
649 | score: 8.5
650 | },
651 | {
652 | title: 'A Clockwork Orange',
653 | year: 1971,
654 | director: 'Stanley Kubrick',
655 | duration: '2h 16min',
656 | genre: ['Crime', 'Drama', 'Sci-Fi'],
657 | score: 8.3
658 | },
659 | {
660 | title: 'Kimi no na wa.',
661 | year: 2016,
662 | director: 'Makoto Shinkai',
663 | duration: '1h 46min',
664 | genre: ['Animation', 'Drama', 'Fantasy', 'Romance'],
665 | score: 8.5
666 | },
667 | {
668 | title: 'Lawrence of Arabia',
669 | year: 1962,
670 | director: 'David Lean',
671 | duration: '3h 36min',
672 | genre: ['Adventure', 'Biography', 'Drama', 'History', 'War'],
673 | score: 8.3
674 | },
675 | {
676 | title: 'Double Indemnity',
677 | year: 1944,
678 | director: 'Billy Wilder',
679 | duration: '1h 47min',
680 | genre: ['Crime', 'Drama', 'Film-Noir', 'Mystery', 'Thriller'],
681 | score: 8.3
682 | },
683 | {
684 | title: 'Amadeus',
685 | year: 1984,
686 | director: 'Milos Forman',
687 | duration: '2h 40min',
688 | genre: ['Biography', 'Drama', 'History', 'Music'],
689 | score: 8.3
690 | },
691 | {
692 | title: 'Eternal Sunshine of the Spotless Mind',
693 | year: 2004,
694 | director: 'Michel Gondry',
695 | duration: '1h 48min',
696 | genre: ['Drama', 'Romance', 'Sci-Fi'],
697 | score: 8.3
698 | },
699 | {
700 | title: 'Taxi Driver',
701 | year: 1976,
702 | director: 'Martin Scorsese',
703 | duration: '1h 53min',
704 | genre: ['Crime', 'Drama'],
705 | score: 8.3
706 | },
707 | {
708 | title: 'To Kill a Mockingbird',
709 | year: 1962,
710 | director: 'Robert Mulligan',
711 | duration: '2h 9min',
712 | genre: ['Crime', 'Drama'],
713 | score: 8.3
714 | },
715 | {
716 | title: 'Dunkirk',
717 | year: 2017,
718 | director: 'Christopher Nolan',
719 | duration: '1h 46min',
720 | genre: ['Action', 'Drama', 'History', 'Thriller', 'War'],
721 | score: 8.3
722 | },
723 | {
724 | title: 'Full Metal Jacket',
725 | year: 1987,
726 | director: 'Stanley Kubrick',
727 | duration: '1h 56min',
728 | genre: ['Drama', 'War'],
729 | score: 8.3
730 | },
731 | {
732 | title: '2001: A Space Odyssey',
733 | year: 1968,
734 | director: 'Stanley Kubrick',
735 | duration: '2h 29min',
736 | genre: ['Adventure', 'Sci-Fi'],
737 | score: 8.3
738 | },
739 | {
740 | title: 'Singin" in the Rain',
741 | year: 1952,
742 | director: 'Stanley Donen',
743 | duration: '1h 43min',
744 | genre: ['Comedy', 'Musical', 'Romance'],
745 | score: 8.3
746 | },
747 | {
748 | title: 'Toy Story 3',
749 | year: 2010,
750 | director: 'Lee Unkrich',
751 | duration: '1h 43min',
752 | genre: ['Animation', 'Adventure', 'Comedy', 'Family', 'Fantasy'],
753 | score: 8.3
754 | },
755 | {
756 | title: 'Toy Story',
757 | year: 1995,
758 | director: 'John Lasseter',
759 | duration: '1h 21min',
760 | genre: ['Animation', 'Adventure', 'Comedy', 'Family', 'Fantasy'],
761 | score: 8.3
762 | },
763 | {
764 | title: 'The Sting',
765 | year: 1973,
766 | director: 'George Roy Hill',
767 | duration: '2h 9min',
768 | genre: ['Comedy', 'Crime', 'Drama'],
769 | score: 8.3
770 | },
771 | {
772 | title: '3 Idiots',
773 | year: 2009,
774 | director: 'Rajkumar Hirani',
775 | duration: '2h 50min',
776 | genre: ['Adventure', 'Comedy', 'Drama', 'Romance'],
777 | score: 8.4
778 | },
779 | {
780 | title: 'Ladri di biciclette',
781 | year: 1948,
782 | director: 'Vittorio De Sica',
783 | duration: '1h 29min',
784 | genre: ['Drama'],
785 | score: 8.3
786 | },
787 | {
788 | title: 'Inglourious Basterds',
789 | year: 2009,
790 | director: 'Quentin Tarantino',
791 | duration: '2h 33min',
792 | genre: ['Adventure', 'Drama', 'War'],
793 | score: 8.3
794 | },
795 | {
796 | title: 'The Kid',
797 | year: 1921,
798 | director: 'Charles Chaplin',
799 | duration: '1h 8min',
800 | genre: ['Comedy', 'Drama', 'Family'],
801 | score: 8.3
802 | },
803 | {
804 | title: 'Snatch',
805 | year: 2000,
806 | director: 'Guy Ritchie',
807 | duration: '1h 44min',
808 | genre: ['Comedy', 'Crime'],
809 | score: 8.3
810 | },
811 | {
812 | title: 'Monty Python and the Holy Grail',
813 | year: 1975,
814 | director: 'Terry Gilliam',
815 | duration: '1h 31min',
816 | genre: ['Adventure', 'Comedy', 'Fantasy'],
817 | score: 8.3
818 | },
819 | {
820 | title: 'Good Will Hunting',
821 | year: 1997,
822 | director: 'Gus Van Sant',
823 | duration: '2h 6min',
824 | genre: ['Drama'],
825 | score: 8.3
826 | },
827 | {
828 | title: 'Jagten',
829 | year: 2012,
830 | director: 'Thomas Vinterberg',
831 | duration: '1h 55min',
832 | genre: ['Drama'],
833 | score: 8.3
834 | },
835 | {
836 | title: 'Per qualche dollaro in più',
837 | year: 1965,
838 | director: 'Sergio Leone',
839 | duration: '2h 12min',
840 | genre: ['Western'],
841 | score: 8.3
842 | },
843 | {
844 | title: 'L.A. Confidential',
845 | year: 1997,
846 | director: 'Curtis Hanson',
847 | duration: '2h 18min',
848 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
849 | score: 8.3
850 | },
851 | {
852 | title: 'Scarface',
853 | year: 1983,
854 | director: 'Brian De Palma',
855 | duration: '2h 50min',
856 | genre: ['Crime', 'Drama'],
857 | score: 8.3
858 | },
859 | {
860 | title: 'The Apartment',
861 | year: 1960,
862 | director: 'Billy Wilder',
863 | duration: '2h 5min',
864 | genre: ['Comedy', 'Drama', 'Romance'],
865 | score: 8.3
866 | },
867 | {
868 | title: 'Metropolis',
869 | year: 1927,
870 | director: 'Fritz Lang',
871 | duration: '2h 33min',
872 | genre: ['Drama', 'Sci-Fi'],
873 | score: 8.3
874 | },
875 | {
876 | title: 'Jodaeiye Nader az Simin',
877 | year: 2011,
878 | director: 'Asghar Farhadi',
879 | duration: '2h 3min',
880 | genre: ['Drama', 'Mystery'],
881 | score: 8.4
882 | },
883 | {
884 | title: 'Rashômon',
885 | year: 1950,
886 | director: 'Akira Kurosawa',
887 | duration: '1h 28min',
888 | genre: ['Crime', 'Drama', 'Mystery'],
889 | score: 8.3
890 | },
891 | {
892 | title: 'Indiana Jones and the Last Crusade',
893 | year: 1989,
894 | director: 'Steven Spielberg',
895 | duration: '2h 7min',
896 | genre: ['Action', 'Adventure', 'Fantasy'],
897 | score: 8.3
898 | },
899 | {
900 | title: 'All About Eve',
901 | year: 1950,
902 | director: 'Joseph L. Mankiewicz',
903 | duration: '2h 18min',
904 | genre: ['Drama'],
905 | score: 8.3
906 | },
907 | {
908 | title: 'Yôjinbô',
909 | year: 1961,
910 | director: 'Akira Kurosawa',
911 | duration: '1h 50min',
912 | genre: ['Action', 'Drama', 'Thriller'],
913 | score: 8.3
914 | },
915 | {
916 | title: 'Babam ve Oglum',
917 | year: 2005,
918 | director: 'Çagan Irmak',
919 | duration: '1h 48min',
920 | genre: ['Drama'],
921 | score: 8.5
922 | },
923 | {
924 | title: 'Up',
925 | year: 2009,
926 | director: 'Pete Docter',
927 | duration: '1h 36min',
928 | genre: ['Animation', 'Adventure', 'Comedy', 'Family'],
929 | score: 8.3
930 | },
931 | {
932 | title: 'Batman Begins',
933 | year: 2005,
934 | director: 'Christopher Nolan',
935 | duration: '2h 32min',
936 | genre: ['Action', 'Adventure', 'Thriller'],
937 | score: 8.3
938 | },
939 | {
940 | title: 'Some Like It Hot',
941 | year: 1959,
942 | director: 'Billy Wilder',
943 | duration: '2h 1min',
944 | genre: ['Comedy', 'Romance'],
945 | score: 8.3
946 | },
947 | {
948 | title: 'The Treasure of the Sierra Madre',
949 | year: 1948,
950 | director: 'John Huston',
951 | duration: '2h 6min',
952 | genre: ['Adventure', 'Drama', 'Western'],
953 | score: 8.3
954 | },
955 | {
956 | title: 'Unforgiven',
957 | year: 1992,
958 | director: 'Clint Eastwood',
959 | duration: '2h 10min',
960 | genre: ['Drama', 'Western'],
961 | score: 8.2
962 | },
963 | {
964 | title: 'Der Untergang',
965 | year: 2004,
966 | director: 'Oliver Hirschbiegel',
967 | duration: '2h 36min',
968 | genre: ['Biography', 'Drama', 'History', 'War'],
969 | score: 8.2
970 | },
971 | {
972 | title: 'Die Hard',
973 | year: 1988,
974 | director: 'John McTiernan',
975 | duration: '2h 11min',
976 | genre: ['Action', 'Thriller'],
977 | score: 8.2
978 | },
979 | {
980 | title: 'Raging Bull',
981 | year: 1980,
982 | director: 'Martin Scorsese',
983 | duration: '2h 9min',
984 | genre: ['Biography', 'Drama', 'Sport'],
985 | score: 8.2
986 | },
987 | {
988 | title: 'Heat',
989 | year: 1995,
990 | director: 'Michael Mann',
991 | duration: '2h 50min',
992 | genre: ['Action', 'Crime', 'Drama', 'Thriller'],
993 | score: 8.2
994 | },
995 | {
996 | title: 'The Third Man',
997 | year: 1949,
998 | director: 'Carol Reed',
999 | duration: '1h 44min',
1000 | genre: ['Film-Noir', 'Mystery', 'Thriller'],
1001 | score: 8.3
1002 | },
1003 | {
1004 | title: 'Bacheha-Ye aseman',
1005 | year: 1997,
1006 | director: 'Majid Majidi',
1007 | duration: '1h 29min',
1008 | genre: ['Drama', 'Family'],
1009 | score: 8.4
1010 | },
1011 | {
1012 | title: 'The Great Escape',
1013 | year: 1963,
1014 | director: 'John Sturges',
1015 | duration: '2h 52min',
1016 | genre: ['Adventure', 'Drama', 'History', 'Thriller', 'War'],
1017 | score: 8.2
1018 | },
1019 | {
1020 | title: 'Ikiru',
1021 | year: 1952,
1022 | director: 'Akira Kurosawa',
1023 | duration: '2h 23min',
1024 | genre: ['Drama'],
1025 | score: 8.3
1026 | },
1027 | {
1028 | title: 'Chinatown',
1029 | year: 1974,
1030 | director: 'Roman Polanski',
1031 | duration: '2h 10min',
1032 | genre: ['Drama', 'Mystery', 'Thriller'],
1033 | score: 8.2
1034 | },
1035 | {
1036 | title: 'El laberinto del fauno',
1037 | year: 2006,
1038 | director: 'Guillermo del Toro',
1039 | duration: '1h 58min',
1040 | genre: ['Drama', 'Fantasy', 'War'],
1041 | score: 8.2
1042 | },
1043 | {
1044 | title: 'Tonari no Totoro',
1045 | year: 1988,
1046 | director: 'Hayao Miyazaki',
1047 | duration: '1h 26min',
1048 | genre: ['Animation', 'Family', 'Fantasy'],
1049 | score: 8.2
1050 | },
1051 | {
1052 | title: 'Incendies',
1053 | year: 2010,
1054 | director: 'Denis Villeneuve',
1055 | duration: '2h 11min',
1056 | genre: ['Drama', 'Mystery', 'War'],
1057 | score: 8.2
1058 | },
1059 | {
1060 | title: 'Ran',
1061 | year: 1985,
1062 | director: 'Akira Kurosawa',
1063 | duration: '2h 42min',
1064 | genre: ['Action', 'Drama'],
1065 | score: 8.2
1066 | },
1067 | {
1068 | title: 'The Gold Rush',
1069 | year: 1925,
1070 | director: 'Charles Chaplin',
1071 | duration: '1h 35min',
1072 | genre: ['Adventure', 'Comedy', 'Drama', 'Family'],
1073 | score: 8.2
1074 | },
1075 | {
1076 | title: 'El secreto de sus ojos',
1077 | year: 2009,
1078 | director: 'Juan José Campanella',
1079 | duration: '2h 9min',
1080 | genre: ['Drama', 'Mystery', 'Romance', 'Thriller'],
1081 | score: 8.2
1082 | },
1083 | {
1084 | title: 'Inside Out',
1085 | year: 2014,
1086 | director: 'Pete Docter',
1087 | duration: '1h 35min',
1088 | genre: ['Animation', 'Adventure', 'Comedy', 'Drama', 'Family', 'Fantasy'],
1089 | score: 8.2
1090 | },
1091 | {
1092 | title: 'Judgment at Nuremberg',
1093 | year: 1961,
1094 | director: 'Stanley Kramer',
1095 | duration: '3h 6min',
1096 | genre: ['Drama', 'War'],
1097 | score: 8.3
1098 | },
1099 | {
1100 | title: 'On the Waterfront',
1101 | year: 1954,
1102 | director: 'Elia Kazan',
1103 | duration: '1h 48min',
1104 | genre: ['Crime', 'Drama', 'Thriller'],
1105 | score: 8.2
1106 | },
1107 | {
1108 | title: 'Hauru no ugoku shiro',
1109 | year: 2004,
1110 | director: 'Hayao Miyazaki',
1111 | duration: '1h 59min',
1112 | genre: ['Animation', 'Adventure', 'Family', 'Fantasy'],
1113 | score: 8.2
1114 | },
1115 | {
1116 | title: 'The Bridge on the River Kwai',
1117 | year: 1957,
1118 | director: 'David Lean',
1119 | duration: '2h 41min',
1120 | genre: ['Adventure', 'Drama', 'War'],
1121 | score: 8.2
1122 | },
1123 | {
1124 | title: 'Room',
1125 | year: 2015,
1126 | director: 'Lenny Abrahamson',
1127 | duration: '1h 58min',
1128 | genre: ['Drama'],
1129 | score: 8.2
1130 | },
1131 | {
1132 | title: 'Det sjunde inseglet',
1133 | year: 1957,
1134 | director: 'Ingmar Bergman',
1135 | duration: '1h 36min',
1136 | genre: ['Drama', 'Fantasy'],
1137 | score: 8.2
1138 | },
1139 | {
1140 | title: 'Lock, Stock and Two Smoking Barrels',
1141 | year: 1998,
1142 | director: 'Guy Ritchie',
1143 | duration: '1h 47min',
1144 | genre: ['Comedy', 'Crime'],
1145 | score: 8.2
1146 | },
1147 | {
1148 | title: 'Mr. Smith Goes to Washington',
1149 | year: 1939,
1150 | director: 'Frank Capra',
1151 | duration: '2h 9min',
1152 | genre: ['Comedy', 'Drama'],
1153 | score: 8.2
1154 | },
1155 | {
1156 | title: 'Blade Runner',
1157 | year: 1982,
1158 | director: 'Ridley Scott',
1159 | duration: '1h 57min',
1160 | genre: ['Sci-Fi', 'Thriller'],
1161 | score: 8.2
1162 | },
1163 | {
1164 | title: 'Casino',
1165 | year: 1995,
1166 | director: 'Martin Scorsese',
1167 | duration: '2h 58min',
1168 | genre: ['Crime', 'Drama'],
1169 | score: 8.2
1170 | },
1171 | {
1172 | title: 'A Beautiful Mind',
1173 | year: 2001,
1174 | director: 'Ron Howard',
1175 | duration: '2h 15min',
1176 | genre: ['Biography', 'Drama'],
1177 | score: 8.2
1178 | },
1179 | {
1180 | title: 'The Elephant Man',
1181 | year: 1980,
1182 | director: 'David Lynch',
1183 | duration: '2h 4min',
1184 | genre: ['Biography', 'Drama'],
1185 | score: 8.2
1186 | },
1187 | {
1188 | title: 'Smultronstället',
1189 | year: 1957,
1190 | director: 'Ingmar Bergman',
1191 | duration: '1h 31min',
1192 | genre: ['Drama', 'Romance'],
1193 | score: 8.2
1194 | },
1195 | {
1196 | title: 'V for Vendetta',
1197 | year: 2005,
1198 | director: 'James McTeigue',
1199 | duration: '2h 12min',
1200 | genre: ['Action', 'Drama', 'Thriller'],
1201 | score: 8.2
1202 | },
1203 | {
1204 | title: 'The Wolf of Wall Street',
1205 | year: 2013,
1206 | director: 'Martin Scorsese',
1207 | duration: '3h',
1208 | genre: ['Biography', 'Comedy', 'Crime', 'Drama'],
1209 | score: 8.2
1210 | },
1211 | {
1212 | title: 'The General',
1213 | year: 1926,
1214 | director: 'Clyde Bruckman',
1215 | duration: '1h 7min',
1216 | genre: ['Action', 'Adventure', 'Comedy', 'Drama', 'War', 'Western'],
1217 | score: 8.2
1218 | },
1219 | {
1220 | title: 'Warrior',
1221 | year: 2011,
1222 | director: 'Gavin O"Connor',
1223 | duration: '2h 20min',
1224 | genre: ['Drama', 'Sport'],
1225 | score: 8.2
1226 | },
1227 | {
1228 | title: 'Trainspotting',
1229 | year: 1996,
1230 | director: 'Danny Boyle',
1231 | duration: '1h 34min',
1232 | genre: ['Drama'],
1233 | score: 8.2
1234 | },
1235 | {
1236 | title: 'Dial M for Murder',
1237 | year: 1954,
1238 | director: 'Alfred Hitchcock',
1239 | duration: '1h 45min',
1240 | genre: ['Crime', 'Film-Noir', 'Thriller'],
1241 | score: 8.2
1242 | },
1243 | {
1244 | title: 'Gran Torino',
1245 | year: 2008,
1246 | director: 'Clint Eastwood',
1247 | duration: '1h 56min',
1248 | genre: ['Drama'],
1249 | score: 8.2
1250 | },
1251 | {
1252 | title: 'Sunrise: A Song of Two Humans',
1253 | year: 1927,
1254 | director: 'F.W. Murnau',
1255 | duration: '1h 34min',
1256 | genre: ['Drama', 'Romance'],
1257 | score: 8.2
1258 | },
1259 | {
1260 | title: 'Gone with the Wind',
1261 | year: 1939,
1262 | director: 'Victor Fleming',
1263 | duration: '3h 58min',
1264 | genre: ['Drama', 'History', 'Romance', 'War'],
1265 | score: 8.2
1266 | },
1267 | {
1268 | title: 'Andrey Rublev',
1269 | year: 1966,
1270 | director: 'Andrei Tarkovsky',
1271 | duration: '3h 25min',
1272 | genre: ['Biography', 'Drama', 'History'],
1273 | score: 8.3
1274 | },
1275 | {
1276 | title: 'The Deer Hunter',
1277 | year: 1978,
1278 | director: 'Michael Cimino',
1279 | duration: '3h 3min',
1280 | genre: ['Drama', 'War'],
1281 | score: 8.2
1282 | },
1283 | {
1284 | title: 'Fargo',
1285 | year: 1996,
1286 | director: 'Joel Coen',
1287 | duration: '1h 38min',
1288 | genre: ['Crime', 'Drama', 'Thriller'],
1289 | score: 8.1
1290 | },
1291 | {
1292 | title: 'The Sixth Sense',
1293 | year: 1999,
1294 | director: 'M. Night Shyamalan',
1295 | duration: '1h 47min',
1296 | genre: ['Drama', 'Mystery', 'Thriller'],
1297 | score: 8.1
1298 | },
1299 | {
1300 | title: 'The Thing',
1301 | year: 2004,
1302 | director: 'John Carpenter',
1303 | duration: '1h 49min',
1304 | genre: ['Horror', 'Mystery', 'Sci-Fi'],
1305 | score: 8.2
1306 | },
1307 | {
1308 | title: 'No Country for Old Men',
1309 | year: 2007,
1310 | director: 'Ethan Coen',
1311 | duration: '2h 2min',
1312 | genre: ['Crime', 'Drama', 'Thriller'],
1313 | score: 8.1
1314 | },
1315 | {
1316 | title: 'The Big Lebowski',
1317 | year: 1998,
1318 | director: 'Joel Coen',
1319 | duration: '1h 57min',
1320 | genre: ['Comedy', 'Crime'],
1321 | score: 8.2
1322 | },
1323 | {
1324 | title: 'Eskiya',
1325 | year: 1996,
1326 | director: 'Yavuz Turgul',
1327 | duration: '2h 8min',
1328 | genre: ['Crime', 'Drama', 'Thriller'],
1329 | score: 8.4
1330 | },
1331 | {
1332 | title: 'Finding Nemo',
1333 | year: 2003,
1334 | director: 'Andrew Stanton',
1335 | duration: '1h 40min',
1336 | genre: ['Animation', 'Adventure', 'Comedy', 'Family'],
1337 | score: 8.1
1338 | },
1339 | {
1340 | title: 'Tôkyô monogatari',
1341 | year: 1953,
1342 | director: 'Yasujirô Ozu',
1343 | duration: '2h 16min',
1344 | genre: ['Drama'],
1345 | score: 8.2
1346 | },
1347 | {
1348 | title: 'There Will Be Blood',
1349 | year: 2007,
1350 | director: 'Paul Thomas Anderson',
1351 | duration: '2h 38min',
1352 | genre: ['Drama', 'History'],
1353 | score: 8.1
1354 | },
1355 | {
1356 | title: 'Cool Hand Luke',
1357 | year: 1967,
1358 | director: 'Stuart Rosenberg',
1359 | duration: '2h 6min',
1360 | genre: ['Crime', 'Drama'],
1361 | score: 8.2
1362 | },
1363 | {
1364 | title: 'Rebecca',
1365 | year: 1940,
1366 | director: 'Alfred Hitchcock',
1367 | duration: '2h 10min',
1368 | genre: ['Drama', 'Mystery', 'Romance', 'Thriller'],
1369 | score: 8.2
1370 | },
1371 | {
1372 | title: 'Hacksaw Ridge',
1373 | year: 2016,
1374 | director: 'Mel Gibson',
1375 | duration: '2h 19min',
1376 | genre: ['Biography', 'Drama', 'History', 'War'],
1377 | score: 8.2
1378 | },
1379 | {
1380 | title: 'La La Land',
1381 | year: 2016,
1382 | director: 'Damien Chazelle',
1383 | duration: '2h 8min',
1384 | genre: ['Comedy', 'Drama', 'Music', 'Musical', 'Romance'],
1385 | score: 8.2
1386 | },
1387 | {
1388 | title: 'Idi i smotri',
1389 | year: 1992,
1390 | director: 'Elem Klimov',
1391 | duration: '2h 22min',
1392 | genre: ['Drama', 'War'],
1393 | score: 8.2
1394 | },
1395 | {
1396 | title: 'Kill Bill: Vol. 1',
1397 | year: 2003,
1398 | director: 'Quentin Tarantino',
1399 | duration: '1h 51min',
1400 | genre: ['Action', 'Crime', 'Thriller'],
1401 | score: 8.1
1402 | },
1403 | {
1404 | title: 'Rang De Basanti',
1405 | year: 2006,
1406 | director: 'Rakeysh Omprakash Mehra',
1407 | duration: '2h 37min',
1408 | genre: ['Comedy', 'Drama', 'History', 'Romance'],
1409 | score: 8.3
1410 | },
1411 | {
1412 | title: 'How to Train Your Dragon',
1413 | year: 2010,
1414 | director: 'Dean DeBlois',
1415 | duration: '1h 38min',
1416 | genre: ['Animation', 'Adventure', 'Comedy', 'Family', 'Fantasy'],
1417 | score: 8.1
1418 | },
1419 | {
1420 | title: 'La passion de Jeanne d"Arc',
1421 | year: 1928,
1422 | director: 'Carl Theodor Dreyer',
1423 | duration: '1h 50min',
1424 | genre: ['Biography', 'Drama', 'History'],
1425 | score: 8.2
1426 | },
1427 | {
1428 | title: 'Mary and Max',
1429 | year: 2009,
1430 | director: 'Adam Elliot',
1431 | duration: '1h 32min',
1432 | genre: ['Animation', 'Comedy', 'Drama'],
1433 | score: 8.2
1434 | },
1435 | {
1436 | title: 'Gone Girl',
1437 | year: 2014,
1438 | director: 'David Fincher',
1439 | duration: '2h 29min',
1440 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
1441 | score: 8.1
1442 | },
1443 | {
1444 | title: 'Into the Wild',
1445 | year: 2007,
1446 | director: 'Sean Penn',
1447 | duration: '2h 28min',
1448 | genre: ['Adventure', 'Biography', 'Drama'],
1449 | score: 8.1
1450 | },
1451 | {
1452 | title: 'Shutter Island',
1453 | year: 2010,
1454 | director: 'Martin Scorsese',
1455 | duration: '2h 18min',
1456 | genre: ['Mystery', 'Thriller'],
1457 | score: 8.1
1458 | },
1459 | {
1460 | title: 'Logan',
1461 | year: 2017,
1462 | director: 'James Mangold',
1463 | duration: '2h 17min',
1464 | genre: ['Action', 'Drama', 'Sci-Fi', 'Thriller'],
1465 | score: 8.2
1466 | },
1467 | {
1468 | title: 'It Happened One Night',
1469 | year: 1934,
1470 | director: 'Frank Capra',
1471 | duration: '1h 45min',
1472 | genre: ['Comedy', 'Romance'],
1473 | score: 8.2
1474 | },
1475 | {
1476 | title: 'Life of Brian',
1477 | year: 1979,
1478 | director: 'Terry Jones',
1479 | duration: '1h 34min',
1480 | genre: ['Comedy'],
1481 | score: 8.1
1482 | },
1483 | {
1484 | title: 'Relatos salvajes',
1485 | year: 2014,
1486 | director: 'Damián Szifron',
1487 | duration: '2h 2min',
1488 | genre: ['Comedy', 'Drama', 'Thriller'],
1489 | score: 8.1
1490 | },
1491 | {
1492 | title: 'A Wednesday',
1493 | year: 2008,
1494 | director: 'Neeraj Pandey',
1495 | duration: '1h 44min',
1496 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
1497 | score: 8.3
1498 | },
1499 | {
1500 | title: 'Platoon',
1501 | year: 1986,
1502 | director: 'Oliver Stone',
1503 | duration: '2h',
1504 | genre: ['Drama', 'War'],
1505 | score: 8.1
1506 | },
1507 | {
1508 | title: 'Hotel Rwanda',
1509 | year: 2004,
1510 | director: 'Terry George',
1511 | duration: '2h 1min',
1512 | genre: ['Biography', 'Drama', 'History', 'War'],
1513 | score: 8.1
1514 | },
1515 | {
1516 | title: 'Le salaire de la peur',
1517 | year: 1953,
1518 | director: 'Henri-Georges Clouzot',
1519 | duration: '2h 11min',
1520 | genre: ['Adventure', 'Drama', 'Thriller'],
1521 | score: 8.2
1522 | },
1523 | {
1524 | title: 'Network',
1525 | year: 1976,
1526 | director: 'Sidney Lumet',
1527 | duration: '2h 1min',
1528 | genre: ['Drama'],
1529 | score: 8.1
1530 | },
1531 | {
1532 | title: 'Rush',
1533 | year: 2013,
1534 | director: 'Ron Howard',
1535 | duration: '2h 3min',
1536 | genre: ['Action', 'Biography', 'Drama', 'History', 'Sport'],
1537 | score: 8.1
1538 | },
1539 | {
1540 | title: 'In the Name of the Father',
1541 | year: 1993,
1542 | director: 'Jim Sheridan',
1543 | duration: '2h 13min',
1544 | genre: ['Biography', 'Drama'],
1545 | score: 8.1
1546 | },
1547 | {
1548 | title: 'Stand by Me',
1549 | year: 1986,
1550 | director: 'Rob Reiner',
1551 | duration: '1h 29min',
1552 | genre: ['Adventure', 'Drama'],
1553 | score: 8.1
1554 | },
1555 | {
1556 | title: 'Persona',
1557 | year: 1966,
1558 | director: 'Ingmar Bergman',
1559 | duration: '1h 25min',
1560 | genre: ['Drama', 'Thriller'],
1561 | score: 8.1
1562 | },
1563 | {
1564 | title: 'Ben-Hur',
1565 | year: 1959,
1566 | director: 'William Wyler',
1567 | duration: '3h 32min',
1568 | genre: ['Adventure', 'Drama', 'History'],
1569 | score: 8.1
1570 | },
1571 | {
1572 | title: 'The Grand Budapest Hotel',
1573 | year: 2014,
1574 | director: 'Wes Anderson',
1575 | duration: '1h 39min',
1576 | genre: ['Adventure', 'Comedy', 'Drama'],
1577 | score: 8.1
1578 | },
1579 | {
1580 | title: 'Les quatre cents coups',
1581 | year: 1959,
1582 | director: 'François Truffaut',
1583 | duration: '1h 32min',
1584 | genre: ['Crime', 'Drama'],
1585 | score: 8.1
1586 | },
1587 | {
1588 | title: 'Salinui chueok',
1589 | year: 2003,
1590 | director: 'Joon-ho Bong',
1591 | duration: '2h 11min',
1592 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
1593 | score: 8.1
1594 | },
1595 | {
1596 | title: '12 Years a Slave',
1597 | year: 2013,
1598 | director: 'Steve McQueen',
1599 | duration: '2h 14min',
1600 | genre: ['Biography', 'Drama', 'History'],
1601 | score: 8.1
1602 | },
1603 | {
1604 | title: 'Mad Max: Fury Road',
1605 | year: 2015,
1606 | director: 'George Miller',
1607 | duration: '2h',
1608 | genre: ['Action', 'Adventure', 'Sci-Fi', 'Thriller'],
1609 | score: 8.1
1610 | },
1611 | {
1612 | title: 'Jurassic Park',
1613 | year: 2000,
1614 | director: 'Steven Spielberg',
1615 | duration: '2h 7min',
1616 | genre: ['Adventure', 'Sci-Fi', 'Thriller'],
1617 | score: 8.1
1618 | },
1619 | {
1620 | title: 'Spotlight',
1621 | year: 2015,
1622 | director: 'Tom McCarthy',
1623 | duration: '2h 8min',
1624 | genre: ['Crime', 'Drama', 'History'],
1625 | score: 8.1
1626 | },
1627 | {
1628 | title: 'Million Dollar Baby',
1629 | year: 2004,
1630 | director: 'Clint Eastwood',
1631 | duration: '2h 12min',
1632 | genre: ['Drama', 'Sport'],
1633 | score: 8.1
1634 | },
1635 | {
1636 | title: 'Stalker',
1637 | year: 1979,
1638 | director: 'Andrei Tarkovsky',
1639 | duration: '2h 42min',
1640 | genre: ['Drama', 'Sci-Fi'],
1641 | score: 8.1
1642 | },
1643 | {
1644 | title: 'Butch Cassidy and the Sundance Kid',
1645 | year: 1969,
1646 | director: 'George Roy Hill',
1647 | duration: '1h 50min',
1648 | genre: ['Biography', 'Crime', 'Drama', 'Western'],
1649 | score: 8.1
1650 | },
1651 | {
1652 | title: 'Amores perros',
1653 | year: 2000,
1654 | director: 'Alejandro González Iñárritu',
1655 | duration: '2h 34min',
1656 | genre: ['Drama', 'Thriller'],
1657 | score: 8.1
1658 | },
1659 | {
1660 | title: 'The Truman Show',
1661 | year: 1990,
1662 | director: 'Peter Weir',
1663 | duration: '1h 43min',
1664 | genre: ['Comedy', 'Drama', 'Sci-Fi'],
1665 | score: 8.1
1666 | },
1667 | {
1668 | title: 'Hachi: A Dog"s Tale',
1669 | year: 1983,
1670 | director: 'Lasse Hallström',
1671 | duration: '1h 33min',
1672 | genre: ['Drama', 'Family'],
1673 | score: 8.1
1674 | },
1675 | {
1676 | title: 'The Maltese Falcon',
1677 | year: 1941,
1678 | director: 'John Huston',
1679 | duration: '1h 40min',
1680 | genre: ['Film-Noir', 'Mystery'],
1681 | score: 8.1
1682 | },
1683 | {
1684 | title: 'Kaze no tani no Naushika',
1685 | year: 1984,
1686 | director: 'Hayao Miyazaki',
1687 | duration: '1h 57min',
1688 | genre: ['Animation', 'Adventure', 'Fantasy', 'Sci-Fi'],
1689 | score: 8.1
1690 | },
1691 | {
1692 | title: 'The Princess Bride',
1693 | year: 1987,
1694 | director: 'Rob Reiner',
1695 | duration: '1h 38min',
1696 | genre: ['Adventure', 'Family', 'Fantasy', 'Romance'],
1697 | score: 8.1
1698 | },
1699 | {
1700 | title: 'Before Sunrise',
1701 | year: 1995,
1702 | director: 'Richard Linklater',
1703 | duration: '1h 41min',
1704 | genre: ['Drama', 'Romance'],
1705 | score: 8.1
1706 | },
1707 | {
1708 | title: 'Le notti di Cabiria',
1709 | year: 1957,
1710 | director: 'Federico Fellini',
1711 | duration: '1h 50min',
1712 | genre: ['Drama'],
1713 | score: 8.2
1714 | },
1715 | {
1716 | title: 'Paper Moon',
1717 | year: 1973,
1718 | director: 'Peter Bogdanovich',
1719 | duration: '1h 42min',
1720 | genre: ['Comedy', 'Crime', 'Drama'],
1721 | score: 8.2
1722 | },
1723 | {
1724 | title: 'Prisoners',
1725 | year: 2013,
1726 | director: 'Denis Villeneuve',
1727 | duration: '2h 33min',
1728 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
1729 | score: 8.1
1730 | },
1731 | {
1732 | title: 'Harry Potter and the Deathly Hallows: Part 2',
1733 | year: 2011,
1734 | director: 'David Yates',
1735 | duration: '2h 10min',
1736 | genre: ['Adventure', 'Drama', 'Fantasy', 'Mystery'],
1737 | score: 8.1
1738 | },
1739 | {
1740 | title: 'The Grapes of Wrath',
1741 | year: 1940,
1742 | director: 'John Ford',
1743 | duration: '2h 9min',
1744 | genre: ['Drama', 'History'],
1745 | score: 8.1
1746 | },
1747 | {
1748 | title: 'Rocky',
1749 | year: 1976,
1750 | director: 'John G. Avildsen',
1751 | duration: '2h',
1752 | genre: ['Drama', 'Sport'],
1753 | score: 8.1
1754 | },
1755 | {
1756 | title: 'Catch Me If You Can',
1757 | year: 2002,
1758 | director: 'Steven Spielberg',
1759 | duration: '2h 21min',
1760 | genre: ['Biography', 'Crime', 'Drama'],
1761 | score: 8.1
1762 | },
1763 | {
1764 | title: 'Touch of Evil',
1765 | year: 1958,
1766 | director: 'Orson Welles',
1767 | duration: '1h 35min',
1768 | genre: ['Crime', 'Drama', 'Film-Noir', 'Thriller'],
1769 | score: 8.1
1770 | },
1771 | {
1772 | title: 'Les diaboliques',
1773 | year: 1955,
1774 | director: 'Henri-Georges Clouzot',
1775 | duration: '1h 57min',
1776 | genre: ['Crime', 'Drama', 'Horror', 'Mystery', 'Thriller'],
1777 | score: 8.1
1778 | },
1779 | {
1780 | title: 'Gandhi',
1781 | year: 1982,
1782 | director: 'Richard Attenborough',
1783 | duration: '3h 11min',
1784 | genre: ['Biography', 'Drama', 'History'],
1785 | score: 8.1
1786 | },
1787 | {
1788 | title: 'Donnie Darko',
1789 | year: 2001,
1790 | director: 'Richard Kelly',
1791 | duration: '1h 53min',
1792 | genre: ['Drama', 'Sci-Fi', 'Thriller'],
1793 | score: 8.1
1794 | },
1795 | {
1796 | title: 'Munna Bhai M.B.B.S.',
1797 | year: 2003,
1798 | director: 'Rajkumar Hirani',
1799 | duration: '2h 36min',
1800 | genre: ['Comedy', 'Drama', 'Romance'],
1801 | score: 8.2
1802 | },
1803 | {
1804 | title: 'Monsters, Inc.',
1805 | year: 2001,
1806 | director: 'Pete Docter',
1807 | duration: '1h 32min',
1808 | genre: ['Animation', 'Adventure', 'Comedy', 'Family', 'Fantasy'],
1809 | score: 8.1
1810 | },
1811 | {
1812 | title: 'Star Wars: Episode VII - The Force Awakens',
1813 | year: 2015,
1814 | director: 'J.J. Abrams',
1815 | duration: '2h 16min',
1816 | genre: ['Action', 'Adventure', 'Fantasy', 'Sci-Fi'],
1817 | score: 8.1
1818 | },
1819 | {
1820 | title: 'Annie Hall',
1821 | year: 1977,
1822 | director: 'Woody Allen',
1823 | duration: '1h 33min',
1824 | genre: ['Comedy', 'Romance'],
1825 | score: 8.1
1826 | },
1827 | {
1828 | title: 'The Terminator',
1829 | year: 1984,
1830 | director: 'James Cameron',
1831 | duration: '1h 47min',
1832 | genre: ['Action', 'Sci-Fi'],
1833 | score: 8
1834 | },
1835 | {
1836 | title: 'Barry Lyndon',
1837 | year: 1975,
1838 | director: 'Stanley Kubrick',
1839 | duration: '3h 4min',
1840 | genre: ['Adventure', 'Drama', 'History', 'War'],
1841 | score: 8.1
1842 | },
1843 | {
1844 | title: 'The Bourne Ultimatum',
1845 | year: 2007,
1846 | director: 'Paul Greengrass',
1847 | duration: '1h 55min',
1848 | genre: ['Action', 'Mystery', 'Thriller'],
1849 | score: 8.1
1850 | },
1851 | {
1852 | title: 'The Wizard of Oz',
1853 | year: 1939,
1854 | director: 'Victor Fleming',
1855 | duration: '1h 42min',
1856 | genre: ['Adventure', 'Family', 'Fantasy', 'Musical'],
1857 | score: 8.1
1858 | },
1859 | {
1860 | title: 'Groundhog Day',
1861 | year: 1993,
1862 | director: 'Harold Ramis',
1863 | duration: '1h 41min',
1864 | genre: ['Comedy', 'Fantasy', 'Romance'],
1865 | score: 8
1866 | },
1867 | {
1868 | title: 'La haine',
1869 | year: 1995,
1870 | director: 'Mathieu Kassovitz',
1871 | duration: '1h 38min',
1872 | genre: ['Crime', 'Drama'],
1873 | score: 8.1
1874 | },
1875 | {
1876 | title: '8½',
1877 | year: 1963,
1878 | director: 'Federico Fellini',
1879 | duration: '2h 18min',
1880 | genre: ['Drama'],
1881 | score: 8.1
1882 | },
1883 | {
1884 | title: 'Jaws',
1885 | year: 1975,
1886 | director: 'Steven Spielberg',
1887 | duration: '2h 4min',
1888 | genre: ['Adventure', 'Drama', 'Thriller'],
1889 | score: 8
1890 | },
1891 | {
1892 | title: 'Twelve Monkeys',
1893 | year: 1995,
1894 | director: 'Terry Gilliam',
1895 | duration: '2h 9min',
1896 | genre: ['Mystery', 'Sci-Fi', 'Thriller'],
1897 | score: 8
1898 | },
1899 | {
1900 | title: 'The Best Years of Our Lives',
1901 | year: 1946,
1902 | director: 'William Wyler',
1903 | duration: '2h 50min',
1904 | genre: ['Drama', 'Romance', 'War'],
1905 | score: 8.1
1906 | },
1907 | {
1908 | title: 'Mou gaan dou',
1909 | year: 2002,
1910 | director: 'Wai-Keung Lau',
1911 | duration: '1h 41min',
1912 | genre: ['Crime', 'Drama', 'Mystery', 'Thriller'],
1913 | score: 8.1
1914 | },
1915 | {
1916 | title: 'Paris, Texas',
1917 | year: 1984,
1918 | director: 'Wim Wenders',
1919 | duration: '2h 25min',
1920 | genre: ['Drama'],
1921 | score: 8.1
1922 | },
1923 | {
1924 | title: 'The Help',
1925 | year: 2011,
1926 | director: 'Tate Taylor',
1927 | duration: '2h 26min',
1928 | genre: ['Drama'],
1929 | score: 8.1
1930 | },
1931 | {
1932 | title: 'Faa yeung nin wa',
1933 | year: 2000,
1934 | director: 'Kar-Wai Wong',
1935 | duration: '1h 38min',
1936 | genre: ['Drama', 'Romance'],
1937 | score: 8.1
1938 | },
1939 | {
1940 | title: 'Sholay',
1941 | year: 1975,
1942 | director: 'Ramesh Sippy',
1943 | duration: '3h 18min',
1944 | genre: ['Action', 'Adventure', 'Comedy', 'Drama', 'Musical', 'Thriller'],
1945 | score: 8.2
1946 | },
1947 | {
1948 | title: 'Beauty and the Beast',
1949 | year: 1991,
1950 | director: 'Gary Trousdale',
1951 | duration: '1h 24min',
1952 | genre: ['Animation', 'Family', 'Fantasy', 'Musical', 'Romance'],
1953 | score: 8
1954 | },
1955 | {
1956 | title: 'La battaglia di Algeri',
1957 | year: 1966,
1958 | director: 'Gillo Pontecorvo',
1959 | duration: '2h 1min',
1960 | genre: ['Drama', 'War'],
1961 | score: 8.1
1962 | },
1963 | {
1964 | title: 'Ah-ga-ssi',
1965 | year: 2016,
1966 | director: 'Chan-wook Park',
1967 | duration: '2h 24min',
1968 | genre: ['Crime', 'Drama', 'Mystery', 'Romance', 'Thriller'],
1969 | score: 8.1
1970 | },
1971 | {
1972 | title: 'Piscores of the Caribbean: The Curse of the Black Pearl',
1973 | year: 2003,
1974 | director: 'Gore Verbinski',
1975 | duration: '2h 23min',
1976 | genre: ['Action', 'Adventure', 'Fantasy'],
1977 | score: 8
1978 | },
1979 | {
1980 | title: 'PK',
1981 | year: 2014,
1982 | director: 'Rajkumar Hirani',
1983 | duration: '2h 33min',
1984 | genre: ['Comedy', 'Drama', 'Fantasy', 'Sci-Fi'],
1985 | score: 8.2
1986 | },
1987 | {
1988 | title: 'Dog Day Afternoon',
1989 | year: 1975,
1990 | director: 'Sidney Lumet',
1991 | duration: '2h 5min',
1992 | genre: ['Biography', 'Crime', 'Drama', 'Thriller'],
1993 | score: 8
1994 | },
1995 | {
1996 | title: 'Dead Poets Society',
1997 | year: 1989,
1998 | director: 'Peter Weir',
1999 | duration: '2h 8min',
2000 | genre: ['Comedy', 'Drama'],
2001 | score: 8
2002 | }
2003 | ];
2004 |
--------------------------------------------------------------------------------
/src/movies.js:
--------------------------------------------------------------------------------
1 | // Iteration 1: All directors? - Get the array of all directors.
2 | // _Bonus_: It seems some of the directors had directed multiple movies so they will pop up multiple times in the array of directors.
3 | // How could you "clean" a bit this array and make it unified (without duplicates)?
4 | function getAllDirectors(moviesArray) {}
5 |
6 | // Iteration 2: Steven Spielberg. The best? - How many drama movies did STEVEN SPIELBERG direct?
7 | function howManyMovies(moviesArray) {}
8 |
9 | // Iteration 3: All scores average - Get the average of all scores with 2 decimals
10 | function scoresAverage(moviesArray) {}
11 |
12 | // Iteration 4: Drama movies - Get the average of Drama Movies
13 | function dramaMoviesScore(moviesArray) {}
14 |
15 | // Iteration 5: Ordering by year - Order by year, ascending (in growing order)
16 | function orderByYear(moviesArray) {}
17 |
18 | // Iteration 6: Alphabetic Order - Order by title and print the first 20 titles
19 | function orderAlphabetically(moviesArray) {}
20 |
21 | // BONUS - Iteration 7: Time Format - Turn duration of the movies from hours to minutes
22 | function turnHoursToMinutes(moviesArray) {}
23 |
24 | // BONUS - Iteration 8: Best yearly score average - Best yearly score average
25 | function bestYearAvg(moviesArray) {}
26 |
--------------------------------------------------------------------------------
/tests/movies.spec.js:
--------------------------------------------------------------------------------
1 | // Iteration 1
2 | describe('Function "getAllDirectors"', () => {
3 | it('should be declared', () => {
4 | expect(typeof getAllDirectors).toBe('function');
5 | });
6 |
7 | it('should return an array', () => {
8 | expect(getAllDirectors(movies) instanceof Array).toBe(true);
9 | });
10 |
11 | it('should return a new array, not update the original one', () => {
12 | const returnValue = getAllDirectors(movies);
13 | expect(returnValue instanceof Array).toBe(true);
14 | expect(getAllDirectors(movies)).not.toEqual(movies);
15 | });
16 |
17 | it('should return a new array with the same length as the original one', () => {
18 | const testArr = [
19 | {
20 | title: 'Paths of Glory',
21 | year: 1957,
22 | director: 'Stanley Kubrick',
23 | duration: '1h 28min',
24 | genre: ['Drama', 'War'],
25 | score: 8.4
26 | },
27 | {
28 | title: 'Django Unchained',
29 | year: 2012,
30 | director: 'Quentin Tarantino',
31 | duration: '2h 45min',
32 | genre: ['Drama', 'Western'],
33 | score: 8.4
34 | }
35 | ];
36 | expect(getAllDirectors(testArr)).toEqual([
37 | 'Stanley Kubrick',
38 | 'Quentin Tarantino'
39 | ]);
40 | });
41 | });
42 |
43 | // Iteration 2
44 |
45 | describe('Function "howManyMovies"', () => {
46 | it('should be declared', () => {
47 | expect(typeof howManyMovies).toBe('function');
48 | });
49 |
50 | it('should return a number', () => {
51 | expect(typeof howManyMovies(movies)).toBe('number');
52 | });
53 |
54 | it('should return 0 if the array is empty', () => {
55 | expect(howManyMovies([])).toBe(0);
56 | });
57 |
58 | it('should return 0 if none of the movies in the array were directed by Steven Spielberg', () => {
59 | expect(
60 | howManyMovies([
61 | {
62 | director: 'James McTeigue',
63 | genre: ['Action', 'Drama', 'Thriller']
64 | }
65 | ])
66 | ).toBe(0);
67 | });
68 |
69 | it('should only count drama movies', () => {
70 | expect(
71 | howManyMovies([
72 | {
73 | director: 'Steven Spielberg',
74 | genre: ['Action', 'Drama', 'Thriller']
75 | },
76 | {
77 | director: 'Steven Spielberg',
78 | genre: ['Action']
79 | }
80 | ])
81 | ).toBe(1);
82 | });
83 |
84 | it('should return 2 if there are only 2 Steven Spielberg movies', () => {
85 | expect(
86 | howManyMovies([
87 | {
88 | director: 'Steven Spielberg',
89 | genre: ['Action', 'Drama', 'Thriller']
90 | },
91 | {
92 | director: 'James McTeigue',
93 | genre: ['Action', 'Drama']
94 | },
95 | {
96 | director: 'Karl Moses',
97 | genre: ['Thriller', 'Drama']
98 | },
99 | {
100 | director: 'Steven Spielberg',
101 | genre: ['Drama', 'Thriller']
102 | }
103 | ])
104 | ).toBe(2);
105 | });
106 |
107 | it('should return 4 when called with the array of movies exported from "data.js"', () => {
108 | expect(howManyMovies(movies)).toBe(4);
109 | });
110 | });
111 |
112 | // Iteration 3
113 | describe('Function "scoresAverage"', () => {
114 | it('should be declared', () => {
115 | expect(typeof scoresAverage).toBe('function');
116 | });
117 |
118 | it('should return a number', () => {
119 | expect(typeof scoresAverage(movies)).toBe('number');
120 | });
121 |
122 | it(' should return the average score of 2 movies with score 8 each', () => {
123 | expect(scoresAverage([{ score: 8 }, { score: 8 }])).toBe(8);
124 | });
125 |
126 | it('should be rounded to 2 decimals places', () => {
127 | expect(scoresAverage([{ score: 8 }, { score: 9 }, { score: 9 }])).toBe(
128 | 8.67
129 | );
130 | });
131 |
132 | it('should return 0 if an empty array is passed', () => {
133 | expect(scoresAverage([])).toBe(0);
134 | });
135 |
136 | it('should return average even if one of the movies does not have score', () => {
137 | expect(scoresAverage([{ score: 6 }, { score: '' }, {}])).toBe(2);
138 | });
139 | });
140 |
141 | // Iteration 4
142 | describe('Function "dramaMoviesScore"', () => {
143 | it('should be declared', () => {
144 | expect(typeof dramaMoviesScore).toBe('function');
145 | });
146 |
147 | it('should return a number', () => {
148 | expect(typeof dramaMoviesScore(movies)).toBe('number');
149 | });
150 |
151 | it('should return the score of a single element array', () => {
152 | expect(dramaMoviesScore([{ genre: ['Drama'], score: 8 }])).toBe(8);
153 | });
154 |
155 | it('should return the average of the rating of the drama movies in the array', () => {
156 | expect(
157 | dramaMoviesScore([
158 | { genre: ['Drama'], score: 8 },
159 | { genre: ['Drama'], score: 9 },
160 | { genre: ['Drama'], score: 7 }
161 | ])
162 | ).toBe(8);
163 | });
164 |
165 | it('should return the average of the array, a floating point number', () => {
166 | expect(
167 | dramaMoviesScore([
168 | { genre: ['Drama'], score: 9 },
169 | { genre: ['Drama'], score: 9 },
170 | { genre: ['Drama'], score: 7 }
171 | ])
172 | ).toBe(8.33);
173 | });
174 |
175 | it('should only calculate the average for drama movies', () => {
176 | expect(
177 | dramaMoviesScore([
178 | { genre: ['Drama'], score: 8 },
179 | { genre: ['Romance'], score: 9 },
180 | { genre: ['Drama'], score: 7 }
181 | ])
182 | ).toBe(7.5);
183 | });
184 |
185 | it('should return 0 if there is no Drama movie', () => {
186 | expect(
187 | dramaMoviesScore([
188 | { genre: ['Action'], score: 8 },
189 | { genre: ['Romance'], score: 9 },
190 | { genre: ['Sci-Fi'], score: 7 }
191 | ])
192 | ).toBe(0);
193 | });
194 | });
195 |
196 | // Iteration 5
197 | describe('Function "orderByYear"', () => {
198 | it('should be declared', () => {
199 | expect(typeof orderByYear).toBe('function');
200 | });
201 |
202 | it('should return an array', () => {
203 | expect(typeof orderByYear(movies)).toBe('object');
204 | });
205 |
206 | it('should return a new array, not mutate the original one', () => {
207 | const arr = [];
208 | const returnValue = orderByYear(arr);
209 | expect(returnValue instanceof Array).toBe(true);
210 | expect(orderByYear(arr)).not.toBe(arr);
211 | });
212 |
213 | it('should return the element in a single element array', () => {
214 | expect(orderByYear([{ year: 1982 }])).toEqual([{ year: 1982 }]);
215 | });
216 |
217 | it('should return the new array in ascending order', () => {
218 | expect(
219 | orderByYear([{ year: 2002 }, { year: 1982 }, { year: 1995 }])
220 | ).toEqual([{ year: 1982 }, { year: 1995 }, { year: 2002 }]);
221 | });
222 |
223 | it('should order movies with the same year by their title, alphabetically', () => {
224 | expect(
225 | orderByYear([
226 | { title: 'abc', year: 2002 },
227 | { title: 'bac', year: 1982 },
228 | { title: 'aab', year: 1982 }
229 | ])
230 | ).toEqual([
231 | { title: 'aab', year: 1982 },
232 | { title: 'bac', year: 1982 },
233 | { title: 'abc', year: 2002 }
234 | ]);
235 | });
236 | });
237 |
238 | // Iteration 6
239 | describe('Function "orderAlphabetically"', () => {
240 | it('should be declared', () => {
241 | expect(typeof orderAlphabetically).toBe('function');
242 | });
243 |
244 | it('should return an array', () => {
245 | expect(typeof orderAlphabetically([])).toBe('object');
246 | });
247 |
248 | it('should return a new array, not mutate the original one', () => {
249 | const arr = [{ title: 'xyz' }, { title: 'abc' }];
250 | const returnValue = orderAlphabetically(arr);
251 | expect(returnValue instanceof Array).toBe(true);
252 | expect(orderByYear(arr)).not.toBe(arr);
253 | });
254 |
255 | it('should only return the title of the movies, each value should be a string', () => {
256 | expect(typeof orderAlphabetically([{ title: 'aab' }])[0]).toBe('string');
257 | });
258 |
259 | it('should return all of items when the array passed has fewer than 20 items', () => {
260 | const moviesArr = [{ title: 'aab' }, { title: 'bab' }, { title: 'acb' }];
261 | expect(orderAlphabetically(moviesArr).length).toBe(3);
262 | });
263 |
264 | it('If there are more than 20 elements, return only 20 of them.', () => {
265 | const moviesArr = [
266 | { title: 'aab' },
267 | { title: 'bab' },
268 | { title: 'acb' },
269 | { title: 'aab' },
270 | { title: 'bab' },
271 | { title: 'acb' },
272 | { title: 'aab' },
273 | { title: 'bab' },
274 | { title: 'acb' },
275 | { title: 'aab' },
276 | { title: 'bab' },
277 | { title: 'acb' },
278 | { title: 'aab' },
279 | { title: 'bab' },
280 | { title: 'acb' },
281 | { title: 'aab' },
282 | { title: 'bab' },
283 | { title: 'acb' },
284 | { title: 'aab' },
285 | { title: 'bab' },
286 | { title: 'acb' },
287 | { title: 'aab' },
288 | { title: 'bab' },
289 | { title: 'acb' },
290 | { title: 'aab' },
291 | { title: 'bab' },
292 | { title: 'acb' },
293 | { title: 'aab' },
294 | { title: 'bab' },
295 | { title: 'acb' },
296 | { title: 'aab' },
297 | { title: 'bab' },
298 | { title: 'acb' },
299 | { title: 'aab' },
300 | { title: 'bab' },
301 | { title: 'acb' }
302 | ];
303 | expect(orderAlphabetically(moviesArr).length).toBe(20);
304 | });
305 |
306 | it('should order them alphabetically.', () => {
307 | const moviesArr = [
308 | { title: 'aab' },
309 | { title: 'aaa' },
310 | { title: 'abc' },
311 | { title: 'acb' },
312 | { title: 'abb' }
313 | ];
314 |
315 | expect(orderAlphabetically(moviesArr)).toEqual([
316 | 'aaa',
317 | 'aab',
318 | 'abb',
319 | 'abc',
320 | 'acb'
321 | ]);
322 | });
323 |
324 | it('should return the top 20 after ordering them alphabetically.', () => {
325 | const moviesArr = [
326 | { title: 'aab' },
327 | { title: 'bab' },
328 | { title: 'acb' },
329 | { title: 'aaa' },
330 | { title: 'bbb' },
331 | { title: 'anc' },
332 | { title: 'kns' },
333 | { title: 'zds' },
334 | { title: 'pow' },
335 | { title: 'gda' },
336 | { title: 'res' },
337 | { title: 'ter' },
338 | { title: 'bca' },
339 | { title: 'ccc' },
340 | { title: 'bbt' },
341 | { title: 'qas' },
342 | { title: 'kmn' },
343 | { title: 'frt' },
344 | { title: 'afb' },
345 | { title: 'agb' },
346 | { title: 'apo' },
347 | { title: 'poa' },
348 | { title: 'cdf' },
349 | { title: 'sea' },
350 | { title: 'lom' },
351 | { title: 'acs' },
352 | { title: 'qas' },
353 | { title: 'mns' },
354 | { title: 'bvc' },
355 | { title: 'gha' },
356 | { title: 'lkj' },
357 | { title: 'era' },
358 | { title: 'ert' },
359 | { title: 'tex' },
360 | { title: 'zas' },
361 | { title: 'pol' }
362 | ];
363 |
364 | expect(orderAlphabetically(moviesArr)).toEqual([
365 | 'aaa',
366 | 'aab',
367 | 'acb',
368 | 'acs',
369 | 'afb',
370 | 'agb',
371 | 'anc',
372 | 'apo',
373 | 'bab',
374 | 'bbb',
375 | 'bbt',
376 | 'bca',
377 | 'bvc',
378 | 'ccc',
379 | 'cdf',
380 | 'era',
381 | 'ert',
382 | 'frt',
383 | 'gda',
384 | 'gha'
385 | ]);
386 | });
387 | });
388 |
389 | // ******************************************************************************************
390 | // *************************************** BONUS ********************************************
391 | // ******************************************************************************************
392 |
393 | // Iteration 7
394 | describe('Function "turnHoursToMinutes"', () => {
395 | it('should be declared', () => {
396 | expect(typeof turnHoursToMinutes).toBe('function');
397 | });
398 |
399 | it('should return an array', () => {
400 | expect(turnHoursToMinutes(movies) instanceof Array).toBe(true);
401 | });
402 |
403 | it('should return a new array, not mutate the original one', () => {
404 | const returnValue = turnHoursToMinutes(movies);
405 | expect(returnValue instanceof Array).toBe(true);
406 | expect(turnHoursToMinutes(movies)).not.toBe(movies);
407 | });
408 |
409 | it('should return an array of movies with duration as a number', () => {
410 | expect(typeof turnHoursToMinutes(movies)[0].duration).toBe('number');
411 | });
412 |
413 | it('should return an array of movies with the correct duration for a 31 minute movie', () => {
414 | const movieTry = [{ duration: '0h 31min' }];
415 | expect(turnHoursToMinutes(movieTry)[0].duration).toBe(31);
416 | });
417 |
418 | it('should return an array of movies with the correct duration for a 341 minute movie', () => {
419 | const movieTry = [{ duration: '5h 41min' }];
420 | expect(turnHoursToMinutes(movieTry)[0].duration).toBe(341);
421 | });
422 |
423 | it('should return an array of movies with the correct duration for a 2 hour movie', () => {
424 | const movieTry = [{ duration: '2h' }];
425 | expect(turnHoursToMinutes(movieTry)[0].duration).toBe(120);
426 | });
427 | });
428 |
429 | // Iteration 8
430 | describe('Function "bestYearAvg"', () => {
431 | it('should be declared', () => {
432 | expect(typeof bestYearAvg).toBe('function');
433 | });
434 |
435 | it('should return null if the array is empty', () => {
436 | expect(bestYearAvg([])).toBe(null);
437 | });
438 |
439 | it('should return the correct answer to a single element array', () => {
440 | expect(bestYearAvg([{ year: 2007, score: 8 }])).toEqual(
441 | 'The best year was 2007 with an average score of 8'
442 | );
443 | });
444 |
445 | it('should return the correct answer to a multiple elements array', () => {
446 | expect(bestYearAvg(movies)).toEqual(
447 | 'The best year was 1972 with an average score of 9.2'
448 | );
449 | });
450 |
451 | it('should return the oldest year when there is a tie', () => {
452 | const newMoviesArr = [
453 | { year: 2000, score: 9 },
454 | { year: 2000, score: 8 },
455 | { year: 1978, score: 10 },
456 | { year: 1978, score: 7 }
457 | ];
458 |
459 | expect(bestYearAvg(newMoviesArr)).toEqual(
460 | 'The best year was 1978 with an average score of 8.5'
461 | );
462 | });
463 | });
464 |
--------------------------------------------------------------------------------