├── .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
└── viking.js
└── tests
└── viking.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 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
12 | # onlyLabels:
13 | # - TestLabel
14 |
15 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
16 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
17 | daysUntilClose: 7
18 |
19 | # Label to use when marking as stale
20 | staleLabel: stale
21 |
22 | # Comment to post when marking as stale. Set to `false` to disable
23 | markComment: >
24 | 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
25 | for your contributions.
26 | closeComment: >
27 | This pull request is closed. Thank you.
28 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # LAB | JS Vikings
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 | - Run predefined tests in Jasmine to verify that the program meets the technical requirements.
17 | - Identify expected code behavior by reading and understanding test results and errors.
18 | - Define a `class` and use it to create objects (instances).
19 | - Create a subclass that extends a parent class using `extends` and `super()` to inherit properties and methods.
20 | - Define class methods that use the `this` keyword to access object properties.
21 | - Add or remove items from an array using the array methods (`push`, `pop`, `shift`, `unshift`, and `splice`).
22 | - Iterate over arrays using the `for` and `forEach` loops.
23 | - Pass values as arguments to functions.
24 | - Use the `return` keyword to return a value from a function.
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## Introduction
32 |
33 | We have learned Object-oriented programming and how `class` and inheritance work in JavaScript. Now let's work with our Viking friends, applying the concepts we have just learned.
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 and submit your assignment
55 |
56 |
57 |
58 |
59 |
60 | ## Test Your Code
61 |
62 | 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/viking.spec.js` file.
63 |
64 | 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.
65 |
66 | 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).
67 |
68 |
69 |
70 | ## Instructions
71 |
72 | You will work on the `src/viking.js` file.
73 |
74 | Your task is to write the correct code in the `src/viking.js` file to make the tests pass. In this file, you will find the following starter code:
75 |
76 | ```javascript
77 | // Soldier
78 | class Soldier {}
79 |
80 | // Viking
81 | class Viking {}
82 |
83 | // Saxon
84 | class Saxon {}
85 |
86 | // War
87 | class War {}
88 | ```
89 |
90 |
91 | ### Iteration 0: First test
92 |
93 | Let's have a look at the first test case together to get you started.
94 |
95 | The first test case says that "_Soldier class >> should receive 2 arguments (health & strength)_", so we have to write the correct code to pass this test. Let's make the `Soldier` class receive two arguments:
96 |
97 | ```javascript
98 | // Soldier
99 | class Soldier {
100 | constructor(health, strength) {}
101 | }
102 |
103 | // Viking
104 | class Viking {}
105 |
106 | // Saxon
107 | class Saxon {}
108 |
109 | // War
110 | class War {}
111 | ```
112 |
113 |
114 |
115 |
116 | ### Iteration 1: Soldier
117 |
118 | Modify the `Soldier` class and add 2 methods to it: `attack()`, and `receiveDamage()`.
119 |
120 | #### class
121 |
122 | - should receive **2 arguments** (health & strength)
123 | - should receive the **`health` property** as its **1st argument**
124 | - should receive the **`strength` property** as its **2nd argument**
125 |
126 | #### `attack()` method
127 |
128 | - should be a function
129 | - should receive **0 arguments**
130 | - should return **the `strength` property of the `Soldier`**
131 |
132 | #### `receiveDamage()` method
133 |
134 | - should be a function
135 | - should receive **1 argument** (the damage)
136 | - should remove the received damage from the `health` property
137 | - **shouldn't return** anything
138 |
139 |
140 |
141 | ### Iteration 2: Viking
142 |
143 | A `Viking` is a `Soldier` with an additional property, their `name`. They also have a different `receiveDamage()` method and a new method, `battleCry()`.
144 |
145 | Modify the `Viking` class, have it inherit from `Soldier`, re-implement the `receiveDamage()` method for `Viking`, and add a new `battleCry()` method.
146 |
147 | #### inheritance
148 |
149 | - `Viking` should **extend** `Soldier`
150 |
151 | #### class
152 |
153 | - should receive **3 arguments** (name, health & strength)
154 | - should receive the **`name` property** as its **1st argument**
155 | - should receive the **`health` property** as its **2nd argument**
156 | - should receive the **`strength` property** as its **3rd argument**
157 |
158 | #### `attack()` method
159 |
160 | (This method should be **inherited** from `Soldier`, no need to re-implement it.)
161 |
162 | - should be a function
163 | - should receive **0 arguments**
164 | - should return **the `strength` property of the `Viking`**
165 |
166 | #### `receiveDamage()` method
167 |
168 | This method needs to be **re-implemented** for `Viking` because the `Viking` version needs to have different return values.
169 |
170 | - should be a function
171 | - should receive **1 argument** (the damage)
172 | - should remove the received damage from the `health` property
173 | - **if the `Viking` is still alive**, it should return **"NAME has received DAMAGE points of damage"**
174 | - **if the `Viking` dies**, it should return **"NAME has died in act of combat"**
175 |
176 | #### `battleCry()` method
177 |
178 | [Learn more about battle cries](http://www.artofmanliness.com/2015/06/08/battle-cries/).
179 |
180 | - should be a function
181 | - should receive **0 arguments**
182 | - should return **"Odin Owns You All!"**
183 |
184 |
185 |
186 | ### Iteration 3: Saxon
187 |
188 | A `Saxon` is a weaker kind of `Soldier`. Unlike a `Viking`, a `Saxon` has no name. Their `receiveDamage()` method will also be different than the original `Soldier` version.
189 |
190 | Modify the `Saxon`, constructor function, have it inherit from `Soldier` and re-implement the `receiveDamage()` method for `Saxon`.
191 |
192 | #### inheritance
193 |
194 | - `Saxon` should extend `Soldier`
195 |
196 | #### class
197 |
198 | - You don't have to include a constructor method since this class will inherit perfectly from the parents class, both the health and the strength (it `extends` Soldier class :wink: )
199 |
200 | #### `attack()` method
201 |
202 | This method should be **inherited** from `Soldier`, no need to re-implement it.
203 |
204 | - should be a function
205 | - should receive **0 arguments**
206 | - should return **the `strength` property of the `Saxon`**
207 |
208 | #### `receiveDamage()` method
209 |
210 | This method needs to be **re-implemented** for `Saxon` because the `Saxon` version needs to have different return values.
211 |
212 | - should be a function
213 | - should receive **1 argument** (the damage)
214 | - should remove the received damage from the `health` property
215 | - **if the Saxon is still alive**, it should return **_"A Saxon has received DAMAGE points of damage"_**
216 | - **if the Saxon dies**, it should return **_"A Saxon has died in combat"_**
217 |
218 |
219 |
220 | ### BONUS - Iteration 4: War
221 |
222 | Now we get to the good stuff: WAR! Our `War` class will allow us to have a `Viking` army and a `Saxon` army that battle each other.
223 |
224 | Modify the `War` class and add 5 methods to its `class`:
225 |
226 | - `addViking()`
227 | - `addSaxon()`
228 | - `vikingAttack()`
229 | - `saxonAttack()`
230 | - `showStatus()`
231 |
232 | #### class
233 |
234 | When we first create a `War`, the armies should be empty. We will add soldiers to the armies later.
235 |
236 | - should receive **0 arguments**
237 | - should assign an empty array to the **`vikingArmy` property**
238 | - should assign an empty array to the **`saxonArmy` property**
239 |
240 | #### `addViking()` method
241 |
242 | Adds 1 `Viking` to the `vikingArmy`. If you want a 10 `Viking` army, you need to call this 10 times.
243 |
244 | - should be a function
245 | - should receive **1 argument** (a `Viking` object)
246 | - should add the received `Viking` to the army
247 | - **shouldn't return** anything
248 |
249 | #### `addSaxon()` method
250 |
251 | The `Saxon` version of `addViking()`.
252 |
253 | - should be a function
254 | - should receive **1 argument** (a `Saxon` object)
255 | - should add the received `Saxon` to the army
256 | - **shouldn't return** anything
257 |
258 | #### `vikingAttack()` method
259 |
260 | A `Saxon` (chosen at random) has their `receiveDamage()` method called with the damage equal to the `strength` of a `Viking` (also chosen at random). This should only perform a single attack and the `Saxon` doesn't get to attack back.
261 |
262 | - should be a function
263 | - should receive **0 arguments**
264 | - should make a `Saxon` `receiveDamage()` equal to the `strength` of a `Viking`
265 | - should remove dead Saxons from the army
266 | - should return **result of calling `receiveDamage()` of a `Saxon`** with the `strength` of a `Viking`
267 |
268 | #### `saxonAttack()` method
269 |
270 | The `Saxon` version of `vikingAttack()`. A `Viking` receives damage equal to the `strength` of a `Saxon`.
271 |
272 | - should be a function
273 | - should receive **0 arguments**
274 | - should make a `Viking` `receiveDamage()` equal to the `strength` of a `Saxon`
275 | - should remove dead Vikings from the army
276 | - should return **result of calling `receiveDamage()` of a `Viking`** with the `strength` of a `Saxon`
277 |
278 |
279 |
280 | ### BONUS - Iteration 5
281 |
282 | Since there is a lot of repetitive code in the previous two iterations, methods _vikingAttack()_ and _saxonAttack()_, try to create one _generic_ method and call it in the case of _vikingAttack_ and in the case of _saxonAttack_ instead of using almost the same code for both methods. (This iteration doesn't have the test, so ask your TAs and your instructor to give you feedback on the quality of your code after the refactor.)
283 |
284 | #### `showStatus()` method
285 |
286 | Returns the current status of the `War` based on the size of the armies.
287 | - should be a function
288 | - should receive **0 arguments**
289 | - **if the `Saxon` array is empty**, should return **_"Vikings have won the war of the century!"_**
290 | - **if the `Viking` array is empty**, should return **_"Saxons have fought for their lives and survived another day..."_**
291 | - **if there are at least 1 `Viking` and 1 `Saxon`**, should return **_"Vikings and Saxons are still in the thick of battle."_**
292 |
293 |
294 |
295 | **Happy Coding!** :heart:
296 |
297 |
298 |
299 | ## FAQs
300 |
301 |
302 |
303 |
304 | I am stuck in the exercise and don't know how to solve the problem or where to start.
305 |
306 |
307 | 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.
308 |
309 |
310 | 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.
311 |
312 |
313 | Once you have a clear understanding of the problem, you will be able to start working toward the solution.
314 |
315 | [Back to top](#faqs)
316 |
317 |
318 |
319 |
320 | All of the Jasmine tests are failing and in red. Why did this happen?
321 |
322 |
323 | 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.
324 |
325 | 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.
326 |
327 | 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.
328 |
329 | [Back to top](#faqs)
330 |
331 |
332 |
333 |
334 | How do I loop over an array using the forEach() method?
335 |
336 |
337 | 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.
338 |
339 | The syntax of the `forEach()` method is as follows:
340 |
341 | ```js
342 | array.forEach( function(element) {
343 | // code to be executed for each element
344 | });
345 | ```
346 |
347 | Here is an example that uses the `forEach()` method to log each element and its index in an array to the console:
348 |
349 | ```js
350 | const fruits = ['apple', 'banana', 'cherry'];
351 |
352 | fruits.forEach( function(element, index) {
353 | console.log(`${index}: ${element}`);
354 | });
355 | ```
356 |
357 | You can also use an arrow function as the callback function for `forEach()`:
358 |
359 | ```js
360 | fruits.forEach((element, index) => {
361 | console.log(`${index}: ${element}`);
362 | });
363 | ```
364 |
365 | [Back to top](#faqs)
366 |
367 |
368 |
369 |
370 | How do I remove an element from an array?
371 |
372 |
373 | You should use the `splice()` method to remove an array element at a specified index. The `splice()` method modifies the original array and returns an array containing the removed elements.
374 |
375 | Syntax:
376 |
377 | ```js
378 | array.splice(start, deleteCount, item1, item2, ... )
379 | ```
380 |
381 | - **`start`**: The index of the first element to be removed.
382 | - **`deleteCount`**: The number of elements to be removed.
383 | - **`item1, item2, ...`**: (optional) The elements to add to the array, starting at the `start` index.
384 |
385 |
386 |
387 | For example, to remove an array element at index `2` (which is `"c"`):
388 |
389 | ```js
390 | let numbers = ["a", "b", "c", "d", "e"];
391 |
392 | // Remove 1 element starting at index 2 (removes "c")
393 | let removed = numbers.splice(2, 1);
394 |
395 | console.log(numbers); // Output: ["a", "b", "d", "e"]
396 | console.log(removed); // Output: ["c"]
397 | ```
398 |
399 | For more information, check: [MDN: splice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
400 |
401 |
402 | [Back to top](#faqs)
403 |
404 |
405 |
406 |
407 | How can I extend a class and reuse methods through inheritance?
408 |
409 |
410 | In JavaScript, you can use the `extends` keyword to create a *subclass* that extends a *superclass* (also called a base class).
411 |
412 | The subclass inherits methods and properties from the superclass and can also have its own methods and properties.
413 |
414 | Here is an example of extending a class and reusing its methods in JavaScript:
415 |
416 | ```js
417 | class Dog {
418 | constructor (name) {
419 | this.name = name;
420 | }
421 |
422 | bark() {
423 | console.log(`${this.name} is barking.`);
424 | }
425 | }
426 |
427 | class Labradoodle extends Dog {
428 | constructor (name, color) {
429 | super(name);
430 | this.color = color;
431 | }
432 | }
433 |
434 | const dog1 = new Labradoodle("Daisy", "white");
435 | dog1.bark(); // Output: "Daisy is barking."
436 | ```
437 |
438 | In this example, the `Labradoodle` class *extends* the `Dog` class and inherits the `name` property and the `bark()` method. The `Labradoodle` class also defines its own property `color`.
439 |
440 | When the `bark()` method is called on the `dog1` object, it uses the method `bark()` coming from the `Dog` class, because the `Labradoodle` class extends the `Dog` class and inherits its methods and properties.
441 |
442 | [Back to top](#faqs)
443 |
444 |
445 |
446 |
447 | I am unable to push changes to the repository. What should I do?
448 |
449 |
450 | There are a couple of possible reasons why you may be unable to *push* changes to a Git repository:
451 |
452 | 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:
453 | ```bash
454 | git add .
455 | git commit -m "Your commit message"
456 | git push
457 | ```
458 | 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.
459 | To check which remote repository you have cloned, run the following terminal command from the project folder:
460 | ```bash
461 | git remote -v
462 | ```
463 | 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.
464 |
465 | **Note**: You should make a copy of your local code to avoid losing it in the process.
466 |
467 | [Back to top](#faqs)
468 |
469 |
470 |
471 |
--------------------------------------------------------------------------------
/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-vikings/39e27c44d3d0427b9ec29ad73aeee4cee7d88412/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 Vikings'));
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-vikings/39e27c44d3d0427b9ec29ad73aeee4cee7d88412/jasmine/jasmine-2.8.0/jasmine_favicon.png
--------------------------------------------------------------------------------
/src/viking.js:
--------------------------------------------------------------------------------
1 | // Soldier
2 | class Soldier {}
3 |
4 | // Viking
5 | class Viking {}
6 |
7 | // Saxon
8 | class Saxon {}
9 |
10 | // War
11 | class War {}
12 |
--------------------------------------------------------------------------------
/tests/viking.spec.js:
--------------------------------------------------------------------------------
1 |
2 | describe('Soldier', () => {
3 | let soldier;
4 | const strength = 150;
5 | const health = 300;
6 |
7 | beforeEach(() => {
8 | soldier = new Soldier(health, strength);
9 | });
10 |
11 | describe('class', () => {
12 | it('should receive 2 arguments (health & strength)', () => {
13 | expect(Soldier.length).toEqual(2);
14 | });
15 |
16 | it('should receive the health property as its 1st argument', () => {
17 | expect(soldier.health).toEqual(health);
18 | });
19 |
20 | it('should receive the strength property as its 2nd argument', () => {
21 | expect(soldier.strength).toEqual(strength);
22 | });
23 | });
24 |
25 | describe('attack() method', () => {
26 | it('should be a declared', () => {
27 | expect(typeof soldier.attack).toBe('function');
28 | });
29 |
30 | it('should receive 0 arguments', () => {
31 | expect(soldier.attack.length).toEqual(0);
32 | });
33 |
34 | it('should return the strength property of the Soldier', () => {
35 | expect(soldier.attack()).toEqual(strength);
36 | });
37 | });
38 |
39 | describe('receiveDamage() method', () => {
40 | it('should be a declared', () => {
41 | expect(typeof soldier.receiveDamage).toBe('function');
42 | });
43 |
44 | it('should receive 1 argument (the damage)', () => {
45 | expect(soldier.receiveDamage.length).toEqual(1);
46 | });
47 |
48 | it('should remove the received damage from the health property', () => {
49 | soldier.receiveDamage(50);
50 | expect(soldier.health).toEqual(health - 50);
51 | });
52 |
53 | it("shouldn't return anything", () => {
54 | expect(soldier.receiveDamage(50)).toEqual(undefined);
55 | });
56 | });
57 | });
58 |
59 | describe('Viking', () => {
60 | let viking;
61 | const name = 'Harald';
62 | const strength = 150;
63 | const health = 300;
64 |
65 | beforeEach(() => {
66 | viking = new Viking(name, health, strength);
67 | });
68 |
69 | it('should inherit from Soldier', () => {
70 | expect(viking instanceof Soldier).toEqual(true);
71 | });
72 |
73 | describe('class', () => {
74 | it('should receive 3 arguments (name, health & strength)', () => {
75 | expect(Viking.length).toEqual(3);
76 | });
77 |
78 | it('should receive the name property as its 1st argument', () => {
79 | expect(viking.name).toEqual(name);
80 | });
81 |
82 | it('should receive the health property as its 2nd argument', () => {
83 | expect(viking.health).toEqual(health);
84 | });
85 |
86 | it('should receive the strength property as its 3rd argument', () => {
87 | expect(viking.strength).toEqual(strength);
88 | });
89 | });
90 |
91 | describe('attack() method', () => {
92 | it('should be a declared', () => {
93 | expect(typeof viking.attack).toBe('function');
94 | });
95 |
96 | it('should receive 0 arguments', () => {
97 | expect(viking.attack.length).toEqual(0);
98 | });
99 |
100 | it('should return the strength property of the Viking', () => {
101 | expect(viking.attack()).toEqual(strength);
102 | });
103 | });
104 |
105 | describe('receiveDamage() method', () => {
106 | it('should be a declared', () => {
107 | expect(typeof viking.receiveDamage).toBe('function');
108 | });
109 |
110 | it('should receive 1 argument (the damage)', () => {
111 | expect(viking.receiveDamage.length).toEqual(1);
112 | });
113 |
114 | it('should remove the received damage from the health property', () => {
115 | viking.receiveDamage(50);
116 | expect(viking.health).toEqual(health - 50);
117 | });
118 |
119 | it('should return "NAME has received DAMAGE points of damage", if the Viking is still alive', () => {
120 | expect(viking.receiveDamage(50)).toEqual(
121 | `${name} has received 50 points of damage`
122 | );
123 |
124 | expect(viking.receiveDamage(75)).toEqual(
125 | `${name} has received 75 points of damage`
126 | );
127 | });
128 |
129 | it('should return "NAME has died in act of combat", if the Viking dies', () => {
130 | expect(viking.receiveDamage(health)).toEqual(
131 | `${name} has died in act of combat`
132 | );
133 | });
134 | });
135 |
136 | describe('battleCry() method', () => {
137 | it('should be a declared', () => {
138 | expect(typeof viking.battleCry).toBe('function');
139 | });
140 |
141 | it('should receive 0 arguments', () => {
142 | expect(viking.battleCry.length).toEqual(0);
143 | });
144 |
145 | it('should return "Odin Owns You All!"', () => {
146 | expect(viking.battleCry()).toEqual('Odin Owns You All!');
147 | });
148 | });
149 | });
150 |
151 | describe('Saxon', () => {
152 | let saxon;
153 | const health = 60;
154 | const strength = 25;
155 |
156 | beforeEach(() => {
157 | saxon = new Saxon(health, strength);
158 | });
159 |
160 | it('should inherit from Soldier', () => {
161 | expect(saxon instanceof Soldier).toEqual(true);
162 | });
163 |
164 | describe('class', () => {
165 | it('should receive the health property as its 1st argument', () => {
166 | expect(saxon.health).toEqual(health);
167 | });
168 |
169 | it('should receive the strength property as its 2nd argument', () => {
170 | expect(saxon.strength).toEqual(strength);
171 | });
172 | });
173 |
174 | describe('attack() method', () => {
175 | it('should be a declared', () => {
176 | expect(typeof saxon.attack).toBe('function');
177 | });
178 |
179 | it('should receive 0 arguments', () => {
180 | expect(saxon.attack.length).toEqual(0);
181 | });
182 |
183 | it('should return the strength property of the Saxon', () => {
184 | expect(saxon.attack()).toEqual(strength);
185 | });
186 | });
187 |
188 | describe('receiveDamage() method', () => {
189 | it('should be a declared', () => {
190 | expect(typeof saxon.receiveDamage).toBe('function');
191 | });
192 |
193 | it('should receive 1 argument (the damage)', () => {
194 | expect(saxon.receiveDamage.length).toEqual(1);
195 | });
196 |
197 | it('should remove the received damage from the health property', () => {
198 | saxon.receiveDamage(50);
199 | expect(saxon.health).toEqual(health - 50);
200 | });
201 |
202 | it('should return "A Saxon has received DAMAGE points of damage", if the Saxon is still alive', () => {
203 | expect(saxon.receiveDamage(45)).toEqual(
204 | 'A Saxon has received 45 points of damage'
205 | );
206 | expect(saxon.receiveDamage(10)).toEqual(
207 | 'A Saxon has received 10 points of damage'
208 | );
209 | });
210 |
211 | it('should return "A Saxon has died in combat", if the Saxon dies', () => {
212 | expect(saxon.receiveDamage(health)).toEqual('A Saxon has died in combat');
213 | });
214 | });
215 | });
216 |
217 | describe('War', () => {
218 | let viking, saxon, war;
219 |
220 | function generateViking() {
221 | const name = 'Harald';
222 | const strength = 150;
223 | const health = 300;
224 | return new Viking(name, health, strength);
225 | }
226 |
227 | function generateSaxon() {
228 | const health = 60;
229 | const strength = 25;
230 | return new Saxon(health, strength);
231 | }
232 |
233 | beforeEach(() => {
234 | viking = generateViking();
235 | saxon = generateSaxon();
236 | war = new War();
237 | });
238 |
239 | describe('class', () => {
240 | it('should receive 0 arguments', () => {
241 | expect(War.length).toEqual(0);
242 | });
243 |
244 | it('should assign an empty array to the vikingArmy property', () => {
245 | expect(war.vikingArmy).toEqual([]);
246 | });
247 |
248 | it('should assign an empty array to the saxonArmy property', () => {
249 | expect(war.saxonArmy).toEqual([]);
250 | });
251 | });
252 |
253 | describe('addViking() method', () => {
254 | it('should be a declared', () => {
255 | expect(typeof war.addViking).toBe('function');
256 | });
257 |
258 | it('should receive 1 argument (a Viking object)', () => {
259 | expect(war.addViking.length).toEqual(1);
260 | });
261 |
262 | it('should add the received Viking to the army', () => {
263 | war.addViking(viking);
264 | expect(war.vikingArmy).toEqual([viking]);
265 | });
266 |
267 | it("shouldn't return anything", () => {
268 | expect(war.addViking(viking)).toEqual(undefined);
269 | });
270 | });
271 |
272 | describe('addSaxon() method', () => {
273 | it('should be a declared', () => {
274 | expect(typeof war.addSaxon).toBe('function');
275 | });
276 |
277 | it('should receive 1 argument (a Saxon object)', () => {
278 | expect(war.addSaxon.length).toEqual(1);
279 | });
280 |
281 | it('should add the received Saxon to the army', () => {
282 | war.addSaxon(saxon);
283 | expect(war.saxonArmy).toEqual([saxon]);
284 | });
285 |
286 | it("shouldn't return anything", () => {
287 | expect(war.addSaxon(saxon)).toEqual(undefined);
288 | });
289 | });
290 |
291 | describe('Armies Attack', () => {
292 | beforeEach(() => {
293 | war.addViking(viking);
294 | war.addSaxon(saxon);
295 | });
296 |
297 | describe('vikingAttack() method', () => {
298 | it('should be a declared', () => {
299 | expect(typeof war.vikingAttack).toBe('function');
300 | });
301 |
302 | it('should receive 0 arguments', () => {
303 | expect(war.vikingAttack.length).toEqual(0);
304 | });
305 |
306 | it('should make Saxon receiveDamage() equal to the strength of a Viking', () => {
307 | let oldHealth = saxon.health;
308 | war.vikingAttack();
309 | expect(saxon.health).toEqual(oldHealth - viking.strength);
310 | });
311 |
312 | it('should remove dead saxons from the army', () => {
313 | war.vikingAttack();
314 | expect(war.saxonArmy.length).toEqual(0);
315 | });
316 |
317 | it('should return result of calling receiveDamage() of a Saxon with the strength of a Viking', () => {
318 | expect(war.vikingAttack()).toEqual('A Saxon has died in combat');
319 | });
320 | });
321 |
322 | describe('saxonAttack() method', () => {
323 | it('should be a declared', () => {
324 | expect(typeof war.saxonAttack).toBe('function');
325 | });
326 |
327 | it('should receive 0 arguments', () => {
328 | expect(war.saxonAttack.length).toEqual(0);
329 | });
330 |
331 | it('should make a Viking receiveDamage() equal to the strength of a Saxon', () => {
332 | let oldHealth = viking.health;
333 | war.saxonAttack();
334 | expect(viking.health).toEqual(oldHealth - saxon.strength);
335 | });
336 |
337 | it('should remove dead vikings from the army', () => {
338 | for (let i = 0; i < 12; i++) {
339 | war.saxonAttack();
340 | }
341 | expect(war.vikingArmy.length).toEqual(0);
342 | });
343 |
344 | it('should return result of calling receiveDamage() of a Viking with the strength of a Saxon', () => {
345 | expect(war.saxonAttack()).toEqual(
346 | `${viking.name} has received ${saxon.strength} points of damage`
347 | );
348 | });
349 | });
350 |
351 | describe('showStatus() method', () => {
352 | it('should be a declared', () => {
353 | expect(typeof war.showStatus).toBe('function');
354 | });
355 |
356 | it('should receive 0 arguments', () => {
357 | expect(war.showStatus.length).toEqual(0);
358 | });
359 |
360 | it('should return "Vikings have won the war of the century!", if the Saxons array is empty', () => {
361 | war.vikingAttack();
362 | expect(war.showStatus()).toEqual(
363 | 'Vikings have won the war of the century!'
364 | );
365 | });
366 |
367 | it('should return "Saxons have fought for their lives and survived another day...", if the Vikings array is empty', () => {
368 | for (let i = 0; i < 12; i++) {
369 | war.saxonAttack();
370 | }
371 | expect(war.showStatus()).toEqual(
372 | 'Saxons have fought for their lives and survived another day...'
373 | );
374 | });
375 |
376 | it('should return "Vikings and Saxons are still in the thick of battle.", if there are still both Vikings and Saxons', () => {
377 | expect(war.showStatus()).toEqual(
378 | 'Vikings and Saxons are still in the thick of battle.'
379 | );
380 | });
381 | });
382 | });
383 | });
384 |
--------------------------------------------------------------------------------