├── .github
├── stale.yml
└── workflows
│ └── test.yml
├── .gitignore
├── DATA.md
├── 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
└── clue.js
└── tests
└── clue.spec.js
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Configuration for probot-stale - https://github.com/probot/stale
2 |
3 | # Number of days of inactivity before an Issue or Pull Request becomes stale
4 | daysUntilStale: 30
5 |
6 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
7 | exemptLabels: []
8 |
9 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
10 | # onlyLabels:
11 | # - TestLabel
12 |
13 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
14 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
15 | daysUntilClose: 2
16 |
17 | # Label to use when marking as stale
18 | staleLabel: stale
19 |
20 | # Comment to post when marking as stale. Set to `false` to disable
21 | markComment: >
22 | This pull request has been automatically marked as stale because it didn't have any recent activity. It will be closed if no further activity occurs. Thank you
23 | for your contributions.
24 | closeComment: >
25 | This pull request is closed. Thank you.
26 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Automated Testing
2 | on: push
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 |
--------------------------------------------------------------------------------
/DATA.md:
--------------------------------------------------------------------------------
1 | # Clue data
2 |
3 | Use this data to model your game cards into objects.
4 |
5 |
6 |
7 | ### Suspects
8 |
9 | ```
10 | mrGreen
11 | firstName: Jacob
12 | lastName: Green
13 | occupation: Entrepreneur
14 | age: 45
15 | description: He has a lot of connections
16 | image: https://pbs.twimg.com/profile_images/506787499331428352/65jTv2uC.jpeg
17 | color: green
18 | ```
19 |
20 | ```
21 | drOrchid
22 | firstName: Doctor
23 | lastName: Orchid
24 | occupation: Scientist
25 | age: 26
26 | description: PhD in plant toxicology. Adopted daughter of Mr. Boddy
27 | image: http://www.radiotimes.com/uploads/images/Original/111967.jpg
28 | color: white
29 | ```
30 |
31 | ```
32 | profPlum
33 | firstName: Victor
34 | lastName: Plum
35 | occupation: Designer
36 | age: 22
37 | description: Billionaire video game designer
38 | image: https://66.media.tumblr.com/ee7155882178f73b3781603f0908617c/tumblr_phhxc7EhPJ1w5fh03_540.jpg
39 | color: purple
40 | ```
41 |
42 | ```
43 | missScarlet
44 | firstName: Kasandra
45 | lastName: Scarlet
46 | occupation: Actor
47 | age: 31
48 | description: She is an A-list movie star with a dark past
49 | image: https://www.radiotimes.com/uploads/images/Original/111967.jpg
50 | color: red
51 | ```
52 |
53 | ```
54 | mrsPeacock
55 | firstName: Eleanor
56 | lastName: Peacock
57 | occupation: Socialité
58 | age: 36
59 | description: She is from a wealthy family and uses her status and money to earn popularity
60 | image: https://metrouk2.files.wordpress.com/2016/07/mrs-peacock.jpg
61 | color: blue
62 | ```
63 |
64 | ```
65 | mrMustard
66 | firstName: Jack
67 | lastName: Mustard
68 | occupation: Retired Football player
69 | age: 62
70 | description: He is a former football player who tries to get by on his former glory
71 | image: https://static.independent.co.uk/s3fs-public/thumbnails/image/2016/07/04/08/unspecified-3.jpg
72 | color: yellow
73 | ```
74 |
75 |
76 |
77 | ### Weapons
78 |
79 | ```
80 | name: rope --- weight: 10
81 | name: knife --- weight: 8
82 | name: candlestick --- weight: 2
83 | name: dumbbell --- weight: 30
84 | name: poison --- weight: 2
85 | name: axe --- weight: 15
86 | name: bat --- weight: 13
87 | name: trophy --- weight: 25
88 | name: pistol --- weight: 20
89 | ```
90 |
91 |
92 |
93 | ### Rooms
94 |
95 | ```
96 | name: Dining Room
97 | name: Conservatory
98 | name: Kitchen
99 | name: Study
100 | name: Library
101 | name: Billiard Room
102 | name: Lounge
103 | name: Ballroom
104 | name: Hall
105 | name: Spa
106 | name: Living Room
107 | name: Observatory
108 | name: Theater
109 | name: Guest House
110 | name: Patio
111 | ```
112 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # LAB | JS Clue (mixing objects and arrays)
4 |
5 |
6 |
7 |
Learning Goals
8 |
9 |
10 | This exercise allows you to practice and apply the concepts and techniques taught in class.
11 |
12 | Upon completion of this exercise, you will be able to:
13 |
14 | - Run predefined tests in Jasmine to verify that the program meets the technical requirements.
15 | - Identify expected code behavior by reading and understanding test results and errors.
16 | - Create objects using the object literal syntax
17 | - Declare and invoke functions
18 | - Use the `return` keyword to return a value from a function.
19 | - Pass arrays to functions as arguments.
20 | - Access objects stored in arrays,
21 | - Access object properties using the dot notation and bracket notation
22 | - Iterate over arrays using the `for` and `forEach` loops.
23 |
24 |
25 |
26 |
27 |
28 |
29 | ## Introduction
30 |
31 | Do you remember the classic detective board game Clue? It was a very popular game in the 90s.
32 |
33 | The plot starts with the death of Mr. Boddy, the very wealthy owner of Tudor Manor. He was killed under _highly suspicious circumstances_, and the player's mission is to uncover which **suspect** murdered him, what **weapon** was used, and in which **room** of the mansion the crime took place.
34 |
35 | When playing Clue, these three details are represented by a **suspect** card, a **weapon** card and a **room** card that are kept hidden in an envelope for the duration of the game. By progressively revealing the remaining cards, the players can infer which are the three cards that are hidden. When a player is confident that they know the solution to the mystery, they will try to reveal it. If a player guesses correctly, they win the game.
36 |
37 |
38 |
39 | ## Requirements
40 |
41 | - Fork this repo
42 | - Clone this repo
43 |
44 |
45 |
46 | ## Submission
47 |
48 | - Upon completion, run the following commands:
49 |
50 | ```sh
51 | git add .
52 | git commit -m "Solved lab"
53 | git push origin master
54 | ```
55 |
56 | - Create a Pull Request so that your TAs can check your work.
57 |
58 |
59 |
60 |
61 | ## Test Your Code
62 |
63 | This LAB is equipped with unit tests to provide automated feedback on your lab progress. If you want to check the tests, they are in the `tests/clue.spec.js` file.
64 |
65 | 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.
66 |
67 | 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).
68 |
69 |
70 |
71 | ## Instructions
72 |
73 | You will work in the `src/clue.js` file, already loaded in the `SpecRunner.html` file.
74 |
75 | 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.
76 |
77 |
78 |
79 | ### Iteration 1: Create the cards
80 |
81 | Clue has three different _card types_: **suspects**, **rooms**, and **weapons**.
82 |
83 | Let's create an `array` for every _card type_. These arrays should be named `suspectsArray`, `weaponsArray`, `roomsArray`.
84 | Each array will contain _objects_, where each _object_ represents one card.
85 |
86 | All of the information you need about **suspects**, **rooms**, and **weapons** can be found on the `DATA.md` file.
87 |
88 | _Suggestion_: Copy this data into the `clue.js` file and model it into objects nested inside your cards' arrays. This is a great chance for you to experiment with IDE shortcuts, multiple-line selection, find and replace, and other great features that VS Code provides.
89 |
90 |
91 |
92 | #### Suspects
93 |
94 | All of six possible _suspects_ in Clue have a **first name**, **last name**, **occupation**, **age**, **description**, **image** and **color**.
95 |
96 | To complete this iteration, you should have an array that looks something like the following:
97 |
98 | ```javascript
99 | const suspectsArray = [
100 | {
101 | firstName: 'Jacob',
102 | lastName: 'Green',
103 | occupation: 'Entrepreneur'
104 | // ...
105 | }
106 | // ...
107 | ];
108 | ```
109 |
110 |
111 |
112 | #### Weapons
113 |
114 | There are a total of nine _weapons_. Each of them has a different **name** and **weight**.
115 |
116 |
117 |
118 | #### Rooms
119 |
120 | The game board represents the blueprints of the mansion and features fifteen different _rooms_. Each room will only have a **name**.
121 |
122 |
123 |
124 | ### Iteration 2: Create the mystery
125 |
126 | At the beginning of the game, players shuffle each of the card stacks to create a combination of _suspect_, _weapon_ and _room_. This will be the mystery to solve.
127 |
128 |
129 |
130 | #### Random selector
131 |
132 | Declare a function named `selectRandom` to select one element from a card stack randomly. The function should expect an `array` as an argument and should return a random element from the array.
133 |
134 |
135 |
136 | #### Create the mystery
137 |
138 | Declare a function named `pickMystery` that takes no arguments and returns an object with three properties: _suspect_, _weapon_ and _room_, each holding as a value a card of that specific type. You can get a random card of each type by calling `selectRandom` on each card stack.
139 |
140 |
141 |
142 | ### Iteration 3: Reveal the mystery
143 |
144 | At last, we are ready to reveal the mystery.
145 |
146 | Declare a function named `revealMystery` that receives an _envelope_ `object` (with the shape of the object returned by `pickMystery`) as the single argument and returns a revealing message in the following format:
147 |
148 | **\ \ killed Mr. Boddy using the \ in the \!**
149 |
150 |
151 |
152 | ## Extra Resources
153 |
154 | - [Data Structures: Objects and Arrays](http://eloquentjavascript.net/04_data.html)
155 | - [20 Mind-blowing facts about Cluedo](http://whatculture.com/offbeat/20-mind-blowing-facts-you-didnt-know-about-cluedo)
156 | - [Cluedo - Wikipedia](https://en.wikipedia.org/wiki/Cluedo)
157 |
158 |
159 |
160 | **Happy coding!** :heart:
161 |
162 |
163 |
164 | ## FAQs
165 |
166 |
167 |
168 |
169 | I am stuck in the exercise and don't know how to solve the problem or where to start.
170 |
171 |
172 | 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.
173 |
174 | For example, is it a concept that you don't understand, or are you receiving an error message that you don't know how to fix? It is usually helpful to try to state the problem as clearly as possible, including any error messages you are receiving. This can help you communicate the issue to others and potentially get help from classmates or online resources.
175 |
176 | Once you have a clear understanding of the problem, you will be able to start working toward the solution.
177 |
178 | [Back to top](#faqs)
179 |
180 |
181 |
182 |
183 | How do I loop over an array?
184 |
185 |
186 | Loops allow you to repeat a block of code a certain number of times. There are several ways to loop over an array in JavaScript:
187 |
188 | #### For loop
189 |
190 | The `for` loop is the most traditional way to loop through an array in JavaScript. It consists of three parts: the *initialization*, the *condition*, and the *increment/decrement*:
191 |
192 | ```js
193 | const animals = ['cat', 'dog', 'bird'];
194 |
195 | // initialize counter variable (let i = 0)
196 | // set condition (i < animals.length)
197 | // increment counter (i++)
198 | for (let i = 0; i < animals.length; i++) {
199 | console.log(animals[i]);
200 | }
201 | ```
202 |
203 | The initialization is where you declare a counter variable and set its initial value.
204 | The condition is a boolean expression that is evaluated before each iteration of the loop. If the condition is `true`, the loop will continue. Once the condition turns `false`, the loop will terminate.
205 | The increment/decrement is where you update the counter variable and it happens at the end of each iteration.
206 | The block of code inside the loop is repeated during each iteration.
207 |
208 |
209 |
210 | #### While loop
211 |
212 | The `while` loop is another way to loop through an array in JavaScript. It consists of a condition and a block of code that is executed as long as the condition is `true`.
213 |
214 | Like the `for` loop, the `while` loop requires a counter variable to keep track of the current position in the array. The counter variable must be initialized before the loop and incremented or decremented at the end of each iteration.
215 |
216 | ```js
217 | const animals = ['cat', 'dog', 'bird'];
218 |
219 | // initialize a counter variable (i)
220 | let i = 0;
221 |
222 | // set condition (i < animals.length)
223 | while (i < animals.length) {
224 | console.log(animals[i]);
225 |
226 | // increment counter (i++)
227 | i++;
228 | }
229 | ```
230 |
231 | [Back to top](#faqs)
232 |
233 |
234 |
235 |
236 | How do I loop over an array using the forEach() method?
237 |
238 |
239 | 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.
240 |
241 | The syntax of the `forEach()` method is as follows:
242 |
243 | ```js
244 | array.forEach( function(element) {
245 | // code to be executed for each element
246 | });
247 | ```
248 |
249 |
250 |
251 | Here is an example that uses the `forEach()` method to log each element and its index in an array to the console:
252 |
253 | ```js
254 | const fruits = ['apple', 'banana', 'cherry'];
255 |
256 | fruits.forEach( function(element, index) {
257 | console.log(`${index}: ${element}`);
258 | });
259 | ```
260 |
261 |
262 |
263 | You can also use an arrow function as the callback function for `forEach()`:
264 |
265 | ```js
266 | fruits.forEach((element, index) => {
267 | console.log(`${index}: ${element}`);
268 | });
269 | ```
270 |
271 | [Back to top](#faqs)
272 |
273 |
274 |
275 |
276 | What could cause array.length to return undefined?
277 |
278 |
279 | If you try to access the `.length` property on an array (e.g., `array.length`) but get `undefined`, it means that the variable you are accessing is not actually an array.
280 |
281 |
282 |
283 | **How do I fix this?**
284 |
285 | Check that the variable you are trying to access is actually an array.
286 |
287 | [Back to top](#faqs)
288 |
289 |
290 |
291 |
292 | How do you generate a random number in JavaScript?
293 |
294 |
295 | To generate a random number using the `Math.random()` method.
296 |
297 |
298 | The `Math.random()` method returns a random floating-point (decimal) number in the range between `0` and `0.9999999999999999`. Example:
299 |
300 | ```js
301 | const randomNumber = Math.random();
302 | console.log(randomNumber);
303 | ```
304 |
305 |
306 |
307 | To generate a random integer within a specific range, use the following formula:
308 |
309 | ```js
310 | const min = 1;
311 | const max = 10;
312 | const randomInteger = Math.floor(Math.random() * (max-min + 1)) + min;
313 | console.log(randomInteger);
314 | ```
315 |
316 | This will generate a random number that is an integer between 1 and 10 (inclusive).
317 |
318 | For more information, check: [MDN: Math.random()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random)
319 |
320 | [Back to top](#faqs)
321 |
322 |
323 |
324 |
325 | All of the Jasmine tests are failing and in red. Why did this happen?
326 |
327 |
328 | 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.
329 |
330 |
331 |
332 | 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.
333 |
334 |
335 |
336 |
337 | 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.
338 |
339 |
340 |
341 | [Back to top](#faqs)
342 |
343 |
344 |
345 |
346 | I am unable to push changes to the repository. What should I do?
347 |
348 |
349 | There are a couple of possible reasons why you may be unable to *push* changes to a Git repository:
350 |
351 | 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:
352 | ```bash
353 | git add .
354 | git commit -m "Your commit message"
355 | git push
356 | ```
357 | 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.
358 | To check which remote repository you have cloned, run the following terminal command from the project folder:
359 | ```bash
360 | git remote -v
361 | ```
362 | 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.
363 |
364 | **Note**: You should make a copy of your local code to avoid losing it in the process.
365 |
366 | [Back to top](#faqs)
367 |
368 |
369 |
--------------------------------------------------------------------------------
/SpecRunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Jasmine Spec Runner v2.8.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/boot.js:
--------------------------------------------------------------------------------
1 | /**
2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
3 |
4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
5 |
6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
7 |
8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
9 | */
10 |
11 | (function() {
12 |
13 | /**
14 | * ## Require & Instantiate
15 | *
16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
17 | */
18 | window.jasmine = jasmineRequire.core(jasmineRequire);
19 |
20 | /**
21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
22 | */
23 | jasmineRequire.html(jasmine);
24 |
25 | /**
26 | * Create the Jasmine environment. This is used to run all specs in a project.
27 | */
28 | var env = jasmine.getEnv();
29 |
30 | /**
31 | * ## The Global Interface
32 | *
33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
34 | */
35 | var jasmineInterface = jasmineRequire.interface(jasmine, env);
36 |
37 | /**
38 | * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
39 | */
40 | extend(window, jasmineInterface);
41 |
42 | /**
43 | * ## Runner Parameters
44 | *
45 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
46 | */
47 |
48 | var queryString = new jasmine.QueryString({
49 | getWindowLocation: function() { return window.location; }
50 | });
51 |
52 | var filterSpecs = !!queryString.getParam("spec");
53 |
54 | var catchingExceptions = queryString.getParam("catch");
55 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
56 |
57 | var throwingExpectationFailures = queryString.getParam("throwFailures");
58 | env.throwOnExpectationFailure(throwingExpectationFailures);
59 |
60 | var random = queryString.getParam("random");
61 | env.randomizeTests(random);
62 |
63 | var seed = queryString.getParam("seed");
64 | if (seed) {
65 | env.seed(seed);
66 | }
67 |
68 | /**
69 | * ## Reporters
70 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
71 | */
72 | var htmlReporter = new jasmine.HtmlReporter({
73 | env: env,
74 | onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
75 | onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
76 | onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
77 | addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
78 | getContainer: function() { return document.body; },
79 | createElement: function() { return document.createElement.apply(document, arguments); },
80 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
81 | timer: new jasmine.Timer(),
82 | filterSpecs: filterSpecs
83 | });
84 |
85 | /**
86 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
87 | */
88 | env.addReporter(jasmineInterface.jsApiReporter);
89 | env.addReporter(htmlReporter);
90 |
91 | /**
92 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
93 | */
94 | var specFilter = new jasmine.HtmlSpecFilter({
95 | filterString: function() { return queryString.getParam("spec"); }
96 | });
97 |
98 | env.specFilter = function(spec) {
99 | return specFilter.matches(spec.getFullName());
100 | };
101 |
102 | /**
103 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
104 | */
105 | window.setTimeout = window.setTimeout;
106 | window.setInterval = window.setInterval;
107 | window.clearTimeout = window.clearTimeout;
108 | window.clearInterval = window.clearInterval;
109 |
110 | /**
111 | * ## Execution
112 | *
113 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
114 | */
115 | var currentWindowOnload = window.onload;
116 |
117 | window.onload = function() {
118 | if (currentWindowOnload) {
119 | currentWindowOnload();
120 | }
121 | htmlReporter.initialize();
122 | env.execute();
123 | };
124 |
125 | /**
126 | * Helper function for readability above.
127 | */
128 | function extend(destination, source) {
129 | for (var property in source) destination[property] = source[property];
130 | return destination;
131 | }
132 |
133 | }());
134 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/console.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2017 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | function getJasmineRequireObj() {
24 | if (typeof module !== 'undefined' && module.exports) {
25 | return exports;
26 | } else {
27 | window.jasmineRequire = window.jasmineRequire || {};
28 | return window.jasmineRequire;
29 | }
30 | }
31 |
32 | getJasmineRequireObj().console = function(jRequire, j$) {
33 | j$.ConsoleReporter = jRequire.ConsoleReporter();
34 | };
35 |
36 | getJasmineRequireObj().ConsoleReporter = function() {
37 |
38 | var noopTimer = {
39 | start: function(){},
40 | elapsed: function(){ return 0; }
41 | };
42 |
43 | function ConsoleReporter(options) {
44 | var print = options.print,
45 | showColors = options.showColors || false,
46 | onComplete = options.onComplete || function() {},
47 | timer = options.timer || noopTimer,
48 | specCount,
49 | failureCount,
50 | failedSpecs = [],
51 | pendingCount,
52 | ansi = {
53 | green: '\x1B[32m',
54 | red: '\x1B[31m',
55 | yellow: '\x1B[33m',
56 | none: '\x1B[0m'
57 | },
58 | failedSuites = [];
59 |
60 | print('ConsoleReporter is deprecated and will be removed in a future version.');
61 |
62 | this.jasmineStarted = function() {
63 | specCount = 0;
64 | failureCount = 0;
65 | pendingCount = 0;
66 | print('Started');
67 | printNewline();
68 | timer.start();
69 | };
70 |
71 | this.jasmineDone = function() {
72 | printNewline();
73 | for (var i = 0; i < failedSpecs.length; i++) {
74 | specFailureDetails(failedSpecs[i]);
75 | }
76 |
77 | if(specCount > 0) {
78 | printNewline();
79 |
80 | var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
81 | failureCount + ' ' + plural('failure', failureCount);
82 |
83 | if (pendingCount) {
84 | specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
85 | }
86 |
87 | print(specCounts);
88 | } else {
89 | print('No specs found');
90 | }
91 |
92 | printNewline();
93 | var seconds = timer.elapsed() / 1000;
94 | print('Finished in ' + seconds + ' ' + plural('second', seconds));
95 | printNewline();
96 |
97 | for(i = 0; i < failedSuites.length; i++) {
98 | suiteFailureDetails(failedSuites[i]);
99 | }
100 |
101 | onComplete(failureCount === 0);
102 | };
103 |
104 | this.specDone = function(result) {
105 | specCount++;
106 |
107 | if (result.status == 'pending') {
108 | pendingCount++;
109 | print(colored('yellow', '*'));
110 | return;
111 | }
112 |
113 | if (result.status == 'passed') {
114 | print(colored('green', '.'));
115 | return;
116 | }
117 |
118 | if (result.status == 'failed') {
119 | failureCount++;
120 | failedSpecs.push(result);
121 | print(colored('red', 'F'));
122 | }
123 | };
124 |
125 | this.suiteDone = function(result) {
126 | if (result.failedExpectations && result.failedExpectations.length > 0) {
127 | failureCount++;
128 | failedSuites.push(result);
129 | }
130 | };
131 |
132 | return this;
133 |
134 | function printNewline() {
135 | print('\n');
136 | }
137 |
138 | function colored(color, str) {
139 | return showColors ? (ansi[color] + str + ansi.none) : str;
140 | }
141 |
142 | function plural(str, count) {
143 | return count == 1 ? str : str + 's';
144 | }
145 |
146 | function repeat(thing, times) {
147 | var arr = [];
148 | for (var i = 0; i < times; i++) {
149 | arr.push(thing);
150 | }
151 | return arr;
152 | }
153 |
154 | function indent(str, spaces) {
155 | var lines = (str || '').split('\n');
156 | var newArr = [];
157 | for (var i = 0; i < lines.length; i++) {
158 | newArr.push(repeat(' ', spaces).join('') + lines[i]);
159 | }
160 | return newArr.join('\n');
161 | }
162 |
163 | function specFailureDetails(result) {
164 | printNewline();
165 | print(result.fullName);
166 |
167 | for (var i = 0; i < result.failedExpectations.length; i++) {
168 | var failedExpectation = result.failedExpectations[i];
169 | printNewline();
170 | print(indent(failedExpectation.message, 2));
171 | print(indent(failedExpectation.stack, 2));
172 | }
173 |
174 | printNewline();
175 | }
176 |
177 | function suiteFailureDetails(result) {
178 | for (var i = 0; i < result.failedExpectations.length; i++) {
179 | printNewline();
180 | print(colored('red', 'An error was thrown in an afterAll'));
181 | printNewline();
182 | print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
183 |
184 | }
185 | printNewline();
186 | }
187 | }
188 |
189 | return ConsoleReporter;
190 | };
191 |
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/ironhack-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ironhack-labs/lab-javascript-clue/46137865d8cf2b4709519557bbc3d803e93bf5fd/jasmine/jasmine-2.8.0/ironhack-logo.png
--------------------------------------------------------------------------------
/jasmine/jasmine-2.8.0/jasmine-html.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2017 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | jasmineRequire.html = function(j$) {
24 | j$.ResultsNode = jasmineRequire.ResultsNode();
25 | j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
26 | j$.QueryString = jasmineRequire.QueryString();
27 | j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
28 | };
29 |
30 | jasmineRequire.HtmlReporter = function(j$) {
31 |
32 | var noopTimer = {
33 | start: function() {},
34 | elapsed: function() { return 0; }
35 | };
36 |
37 | function HtmlReporter(options) {
38 | var env = options.env || {},
39 | getContainer = options.getContainer,
40 | createElement = options.createElement,
41 | createTextNode = options.createTextNode,
42 | onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
43 | onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
44 | onRandomClick = options.onRandomClick || function() {},
45 | addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
46 | filterSpecs = options.filterSpecs,
47 | timer = options.timer || noopTimer,
48 | results = [],
49 | specsExecuted = 0,
50 | failureCount = 0,
51 | pendingSpecCount = 0,
52 | htmlReporterMain,
53 | symbols,
54 | failedSuites = [];
55 |
56 | this.initialize = function() {
57 | clearPrior();
58 | htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
59 | createDom('div', {className: 'jasmine-banner'},
60 | createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
61 | createDom('span', {className: 'jasmine-version'}, j$.version)
62 | ),
63 | createDom('ul', {className: 'jasmine-symbol-summary'}),
64 | createDom('div', {className: 'jasmine-labname'}),
65 | createDom('div', {className: 'jasmine-alert'}),
66 | createDom('div', {className: 'jasmine-results'},
67 | createDom('div', {className: 'jasmine-failures'})
68 | )
69 | );
70 | getContainer().appendChild(htmlReporterMain);
71 | };
72 |
73 | var totalSpecsDefined;
74 | this.jasmineStarted = function(options) {
75 | totalSpecsDefined = options.totalSpecsDefined || 0;
76 | timer.start();
77 | };
78 |
79 | var summary = createDom('div', {className: 'jasmine-summary'});
80 |
81 | var topResults = new j$.ResultsNode({}, '', null),
82 | currentParent = topResults;
83 |
84 | this.suiteStarted = function(result) {
85 | currentParent.addChild(result, 'suite');
86 | currentParent = currentParent.last();
87 | };
88 |
89 | this.suiteDone = function(result) {
90 | if (result.status == 'failed') {
91 | failedSuites.push(result);
92 | }
93 |
94 | if (currentParent == topResults) {
95 | return;
96 | }
97 |
98 | currentParent = currentParent.parent;
99 | };
100 |
101 | this.specStarted = function(result) {
102 | currentParent.addChild(result, 'spec');
103 | };
104 |
105 | var failures = [];
106 | this.specDone = function(result) {
107 | if (noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
108 | console.error('Spec \'' + result.fullName + '\' has no expectations.');
109 | }
110 |
111 | if (result.status != 'disabled') {
112 | specsExecuted++;
113 | }
114 |
115 | if (!symbols){
116 | symbols = find('.jasmine-symbol-summary');
117 | }
118 |
119 | symbols.appendChild(createDom('li', {
120 | className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
121 | id: 'spec_' + result.id,
122 | title: result.fullName
123 | }
124 | ));
125 |
126 | if (result.status == 'failed') {
127 | failureCount++;
128 |
129 | var failure =
130 | createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
131 | createDom('div', {className: 'jasmine-description'},
132 | createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
133 | ),
134 | createDom('div', {className: 'jasmine-messages'})
135 | );
136 | var messages = failure.childNodes[1];
137 |
138 | for (var i = 0; i < result.failedExpectations.length; i++) {
139 | var expectation = result.failedExpectations[i];
140 | var stringStart = expectation.stack.indexOf("at UserContext.");
141 | var shortStackTrace = expectation.stack.slice(stringStart);
142 | messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
143 | messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, shortStackTrace));
144 | }
145 |
146 |
147 | failures.push(failure);
148 | }
149 |
150 | if (result.status == 'pending') {
151 | pendingSpecCount++;
152 | }
153 | };
154 |
155 | this.jasmineDone = function(doneResult) {
156 | var banner = find('.jasmine-banner');
157 | var labName = find('.jasmine-labname');
158 | var alert = find('.jasmine-alert');
159 | var order = doneResult && doneResult.order;
160 | labName.appendChild(createDom('img', {src: 'jasmine/jasmine-2.8.0/ironhack-logo.png'}, ''));
161 | labName.appendChild(createDom('span', {}, 'LAB | JS Clue'));
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-clue/46137865d8cf2b4709519557bbc3d803e93bf5fd/jasmine/jasmine-2.8.0/jasmine_favicon.png
--------------------------------------------------------------------------------
/src/clue.js:
--------------------------------------------------------------------------------
1 | // ITERATION 1
2 |
3 | // Suspects Array
4 |
5 | const suspectsArray = [];
6 |
7 | // Rooms Array
8 |
9 | const roomsArray = [];
10 |
11 | // Weapons Array
12 |
13 | const weaponsArray = [];
14 |
15 |
16 | // ITERATION 2
17 |
18 | function selectRandom() {}
19 |
20 | function pickMystery() {}
21 |
22 |
23 | // ITERATION 3
24 |
25 | function revealMystery() {}
26 |
27 |
--------------------------------------------------------------------------------
/tests/clue.spec.js:
--------------------------------------------------------------------------------
1 | describe("Array 'suspectsArray'", () => {
2 | it('should be an array', () => {
3 | expect(Array.isArray(suspectsArray)).toBeTruthy();
4 | });
5 |
6 | it('should have 6 suspects (objects)', () => {
7 | expect(suspectsArray.length).toBe(6);
8 | });
9 |
10 | describe('- Suspect Objects', () => {
11 | beforeAll(() => {
12 | expect(suspectsArray.length).toBeTruthy();
13 | });
14 |
15 | it('should have a string in property "firstName"', () => {
16 | for (let suspect of suspectsArray)
17 | expect(typeof suspect.firstName).toBe('string');
18 | });
19 |
20 | it('should have a string in property "lastName"', () => {
21 | for (let suspect of suspectsArray)
22 | expect(typeof suspect.lastName).toBe('string');
23 | });
24 |
25 | it('should have a string in property "occupation"', () => {
26 | for (let suspect of suspectsArray)
27 | expect(typeof suspect.occupation).toBe('string');
28 | });
29 |
30 | it('should have a number in property "age"', () => {
31 | for (let suspect of suspectsArray)
32 | expect(typeof suspect.age).toBe('number');
33 | });
34 |
35 | it('should have a string in property "description"', () => {
36 | for (let suspect of suspectsArray)
37 | expect(typeof suspect.description).toBe('string');
38 | });
39 |
40 | it('should have a string in property "image"', () => {
41 | for (let suspect of suspectsArray)
42 | expect(typeof suspect.image).toBe('string');
43 | });
44 |
45 | it('should have a string in property "color"', () => {
46 | for (let suspect of suspectsArray)
47 | expect(typeof suspect.color).toBe('string');
48 | });
49 | });
50 | });
51 |
52 | describe("Array 'weaponsArray'", () => {
53 | it('should be an array', () => {
54 | expect(Array.isArray(weaponsArray)).toBeTruthy();
55 | });
56 |
57 | it('should have 9 weapons (objects)', () => {
58 | expect(weaponsArray.length).toBe(9);
59 | });
60 |
61 | describe('- Weapon Objects', () => {
62 | beforeAll(() => {
63 | expect(weaponsArray.length).toBeTruthy();
64 | });
65 |
66 | it('should have a string in property "name"', () => {
67 | for (let weapon of weaponsArray)
68 | expect(typeof weapon.name).toBe('string');
69 | });
70 |
71 | it('should have a number in property "weight"', () => {
72 | for (let weapon of weaponsArray)
73 | expect(typeof weapon.weight).toBe('number');
74 | });
75 | });
76 | });
77 |
78 | describe("Array 'roomsArray'", () => {
79 | it('should be an array', () => {
80 | expect(Array.isArray(roomsArray)).toBeTruthy();
81 | });
82 |
83 | it('should have 15 rooms (objects)', () => {
84 | expect(roomsArray.length).toBe(15);
85 | });
86 |
87 | describe('- Room Objects', () => {
88 | beforeAll(() => {
89 | expect(roomsArray.length).toBeTruthy();
90 | });
91 |
92 | it('should have a string in property "name"', () => {
93 | for (let room of roomsArray) expect(typeof room.name).toBe('string');
94 | });
95 | });
96 | });
97 |
98 | describe('Function "selectRandom" - Find a random element of the array', () => {
99 | it('should be declared', () => {
100 | expect(typeof selectRandom).toBe('function');
101 | });
102 |
103 | it("should return undefined if the array is empty", () => {
104 | expect(selectRandom([])).toBe(undefined);
105 | });
106 |
107 | it("should return the element of a single value array", () => {
108 | expect(selectRandom(["ab"])).toBe("ab");
109 | });
110 |
111 | it('should return an element of the array', () => {
112 | const array = ['ab', 'zz', 'zx', 'zy'];
113 | expect(array.includes(selectRandom(array))).toBeTruthy();
114 | });
115 |
116 | it('should return a random element of the array', () => {
117 | const mathRandomSpy = spyOn(Math, 'random');
118 |
119 | mathRandomSpy.and.returnValue(0.5);
120 |
121 | expect(
122 | selectRandom(['a', 'ab', 'abb', 'aab', 'aaa', 'sda', 'kas'])
123 | ).toEqual('aab');
124 |
125 | mathRandomSpy.and.returnValue(0.1);
126 | expect(
127 | selectRandom(['a', 'ab', 'abb', 'aab', 'aaa', 'sda', 'kas'])
128 | ).toEqual('a');
129 |
130 | mathRandomSpy.and.returnValue(0.9);
131 | expect(
132 | selectRandom(['a', 'ab', 'abb', 'aab', 'aaa', 'sda', 'kas'])
133 | ).toEqual('kas');
134 | });
135 | });
136 |
137 | describe('Function "pickMystery" - Pick a random mystery', () => {
138 | it('should be declared', () => {
139 | expect(typeof pickMystery).toBe('function');
140 | });
141 |
142 | it('should return an object', () => {
143 | const mistery = pickMystery();
144 |
145 | expect(typeof mistery).toEqual('object');
146 | expect(mistery !== null).toBeTruthy();
147 | });
148 |
149 | it('should return an object with 3 properties: `suspect`, `weapon`, `room`', () => {
150 | const mistery = pickMystery();
151 |
152 | expect(Object.keys(mistery).length).toBe(3);
153 |
154 | expect(Object.keys(mistery)).toContain('suspect');
155 | expect(Object.keys(mistery)).toContain('weapon');
156 | expect(Object.keys(mistery)).toContain('room');
157 | });
158 |
159 | it('should return a suspect in the suspect property of the object', () => {
160 | const mistery = pickMystery();
161 | expect(suspectsArray.includes(mistery.suspect)).toBeTruthy();
162 | });
163 |
164 | it('should return a weapon in the weapon property of the object', () => {
165 | const mistery = pickMystery();
166 | expect(weaponsArray.includes(mistery.weapon)).toBeTruthy();
167 | });
168 |
169 | it('should return a room in the room property of the object', () => {
170 | const mistery = pickMystery();
171 | expect(roomsArray.includes(mistery.room)).toBeTruthy();
172 | });
173 | });
174 |
175 | describe('Function "revealMystery" - Reveal the mystery', () => {
176 | it('should define revealMystery', () => {
177 | expect(typeof revealMystery).toBe('function');
178 | });
179 |
180 | it('should return a string', () => {
181 | const message = revealMystery({
182 | suspect: { firstName: 'aa', lastName: 'abc' },
183 | weapon: { name: 'abd' },
184 | room: { name: 'abb' }
185 | });
186 | expect(typeof message).toEqual('string');
187 | });
188 |
189 | it('should return " killed Mr. Boddy using the in the !"', () => {
190 | const message = revealMystery({
191 | suspect: { firstName: 'Victor', lastName: 'Plum' },
192 | weapon: { name: 'poison' },
193 | room: { name: 'Billiard Room' }
194 | });
195 | expect(message).toEqual(
196 | 'Victor Plum killed Mr. Boddy using the poison in the Billiard Room!'
197 | );
198 | });
199 | });
200 |
--------------------------------------------------------------------------------