mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2025-12-12 04:12:13 +00:00
added js version of Gilded Rose from git@github.com:guyroyse/gilded-rose-javascript.git
This commit is contained in:
parent
2e7e36eda1
commit
4bb9659190
3
GildedRose/js/.gitignore
vendored
Normal file
3
GildedRose/js/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.swp
|
||||
*~
|
||||
*.bak
|
||||
61
GildedRose/js/README.md
Normal file
61
GildedRose/js/README.md
Normal file
@ -0,0 +1,61 @@
|
||||
If you want to get cracking on the JavaScript source then do this:
|
||||
|
||||
git clone git@github.com:guyroyse/gilded-rose-javascript.git
|
||||
|
||||
Hi and welcome to team Gilded Rose.
|
||||
|
||||
As you know, we are a small inn with a prime location in a prominent city ran
|
||||
by a friendly innkeeper named Allison. We also buy and sell only the finest
|
||||
goods. Unfortunately, our goods are constantly degrading in quality as they
|
||||
approach their sell by date.
|
||||
|
||||
We have a system in place that updates our inventory for us. It was developed
|
||||
by a no-nonsense type named Leeroy, who has moved on to new adventures. Your
|
||||
task is to add the new feature to our system so that we can begin selling a
|
||||
new category of items.
|
||||
|
||||
First an introduction to our system:
|
||||
|
||||
- All items have a *sell_in* value which denotes the number of days we have to
|
||||
sell the item
|
||||
|
||||
- All items have a *quality* value which denotes how valuable the item is
|
||||
|
||||
- At the end of each day our system lowers both values for every item
|
||||
|
||||
Pretty simple, right? Well this is where it gets interesting:
|
||||
|
||||
- Once the *sell_in* days is less then zero, *quality* degrades twice as fast
|
||||
|
||||
- The *quality* of an item is never negative
|
||||
|
||||
- "Aged Brie" actually increases in *quality* the older it gets
|
||||
|
||||
- The *quality* of an item is never more than 50
|
||||
|
||||
- "Sulfuras", being a legendary item, never has to be sold nor does it
|
||||
decrease in *quality*
|
||||
|
||||
- "Backstage passes", like aged brie, increases in *quality* as it's *sell_in*
|
||||
value decreases; *quality* increases by 2 when there are 10 days or less
|
||||
and by 3 when there are 5 days or less but *quality* drops to 0 after the
|
||||
concert
|
||||
|
||||
We have recently signed a supplier of conjured items. This requires an update
|
||||
to our system:
|
||||
|
||||
- "Conjured" items degrade in *quality* twice as fast as normal items
|
||||
|
||||
Feel free to make any changes to the *update_quality* method and add any new
|
||||
code as long as everything still works correctly. However, do not alter the
|
||||
*Item* class or *items* property as those belong to the goblin in the corner
|
||||
who will insta-rage and one-shot you as he doesn't believe in shared code
|
||||
ownership.
|
||||
|
||||
Just for clarification, an item can never have its *quality* increase above 50,
|
||||
however "Sulfuras" is a legendary item and as such its *quality* is 80 and it
|
||||
never alters.
|
||||
|
||||
Sources:
|
||||
<http://www.iamnotmyself.com/2011/02/13/RefactorThisTheGildedRoseKata.aspx>
|
||||
<https://github.com/professor/GildedRose>
|
||||
56
GildedRose/js/SpecRunner.html
Normal file
56
GildedRose/js/SpecRunner.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<title>Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.1.0/jasmine_favicon.png">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0/jasmine-html.js"></script>
|
||||
<script type="text/javascript" src="lib/jquery-1.7.1/jquery-1.7.1.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-jquery-1.3.1/jasmine-jquery-1.3.1.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-ajax/mock-ajax.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/gilded_rose.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/gilded_rose_spec.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
jasmine.getFixtures().fixturesPath = 'spec'
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
20
GildedRose/js/lib/jasmine-1.1.0/MIT.LICENSE
Normal file
20
GildedRose/js/lib/jasmine-1.1.0/MIT.LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
Copyright (c) 2008-2011 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
190
GildedRose/js/lib/jasmine-1.1.0/jasmine-html.js
Normal file
190
GildedRose/js/lib/jasmine-1.1.0/jasmine-html.js
Normal file
@ -0,0 +1,190 @@
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
return this.document.location;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
||||
166
GildedRose/js/lib/jasmine-1.1.0/jasmine.css
Normal file
166
GildedRose/js/lib/jasmine-1.1.0/jasmine.css
Normal file
@ -0,0 +1,166 @@
|
||||
body {
|
||||
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.jasmine_reporter a:visited, .jasmine_reporter a {
|
||||
color: #303;
|
||||
}
|
||||
|
||||
.jasmine_reporter a:hover, .jasmine_reporter a:active {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.run_spec {
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-size: .8em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jasmine_reporter {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
color: #303;
|
||||
background-color: #fef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
font-size: 1.1em;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.logo .version {
|
||||
font-size: .6em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.runner.running {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
|
||||
.options {
|
||||
text-align: right;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.suite {
|
||||
border: 1px outset gray;
|
||||
margin: 5px 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.suite .suite {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.suite.passed {
|
||||
background-color: #dfd;
|
||||
}
|
||||
|
||||
.suite.failed {
|
||||
background-color: #fdd;
|
||||
}
|
||||
|
||||
.spec {
|
||||
margin: 5px;
|
||||
padding-left: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.spec.failed, .spec.passed, .spec.skipped {
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.spec.failed {
|
||||
background-color: #fbb;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.spec.passed {
|
||||
background-color: #bfb;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.spec.skipped {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.messages {
|
||||
border-left: 1px dashed gray;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.passed {
|
||||
background-color: #cfc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: #fbb;
|
||||
}
|
||||
|
||||
.skipped {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*.resultMessage {*/
|
||||
/*white-space: pre;*/
|
||||
/*}*/
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.resultMessage .mismatch {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
white-space: pre;
|
||||
font-size: .8em;
|
||||
margin-left: 10px;
|
||||
max-height: 5em;
|
||||
overflow: auto;
|
||||
border: 1px inset red;
|
||||
padding: 1em;
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.finished-at {
|
||||
padding-left: 1em;
|
||||
font-size: .6em;
|
||||
}
|
||||
|
||||
.show-passed .passed,
|
||||
.show-skipped .skipped {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#jasmine_content {
|
||||
position:fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.runner {
|
||||
border: 1px solid gray;
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
2476
GildedRose/js/lib/jasmine-1.1.0/jasmine.js
Normal file
2476
GildedRose/js/lib/jasmine-1.1.0/jasmine.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
GildedRose/js/lib/jasmine-1.1.0/jasmine_favicon.png
Normal file
BIN
GildedRose/js/lib/jasmine-1.1.0/jasmine_favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 905 B |
207
GildedRose/js/lib/jasmine-ajax/mock-ajax.js
Normal file
207
GildedRose/js/lib/jasmine-ajax/mock-ajax.js
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
Jasmine-Ajax : a set of helpers for testing AJAX requests under the Jasmine
|
||||
BDD framework for JavaScript.
|
||||
|
||||
Supports both Prototype.js and jQuery.
|
||||
|
||||
http://github.com/pivotal/jasmine-ajax
|
||||
|
||||
Jasmine Home page: http://pivotal.github.com/jasmine
|
||||
|
||||
Copyright (c) 2008-2010 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// Jasmine-Ajax interface
|
||||
var ajaxRequests = [];
|
||||
|
||||
function mostRecentAjaxRequest() {
|
||||
if (ajaxRequests.length > 0) {
|
||||
return ajaxRequests[ajaxRequests.length - 1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearAjaxRequests() {
|
||||
ajaxRequests = [];
|
||||
}
|
||||
|
||||
// Fake XHR for mocking Ajax Requests & Responses
|
||||
function FakeXMLHttpRequest() {
|
||||
var extend = Object.extend || $.extend;
|
||||
extend(this, {
|
||||
requestHeaders: {},
|
||||
|
||||
open: function() {
|
||||
this.method = arguments[0];
|
||||
this.url = arguments[1];
|
||||
this.readyState = 1;
|
||||
},
|
||||
|
||||
setRequestHeader: function(header, value) {
|
||||
this.requestHeaders[header] = value;
|
||||
},
|
||||
|
||||
abort: function() {
|
||||
this.readyState = 0;
|
||||
},
|
||||
|
||||
readyState: 0,
|
||||
|
||||
onreadystatechange: function(isTimeout) {
|
||||
},
|
||||
|
||||
status: null,
|
||||
|
||||
send: function(data) {
|
||||
this.params = data;
|
||||
this.readyState = 2;
|
||||
},
|
||||
|
||||
getResponseHeader: function(name) {
|
||||
return this.responseHeaders[name];
|
||||
},
|
||||
|
||||
getAllResponseHeaders: function() {
|
||||
var responseHeaders = [];
|
||||
for (var i in this.responseHeaders) {
|
||||
if (this.responseHeaders.hasOwnProperty(i)) {
|
||||
responseHeaders.push(i + ': ' + this.responseHeaders[i]);
|
||||
}
|
||||
}
|
||||
return responseHeaders.join('\r\n');
|
||||
},
|
||||
|
||||
responseText: null,
|
||||
|
||||
response: function(response) {
|
||||
this.status = response.status;
|
||||
this.responseText = response.responseText || "";
|
||||
this.readyState = 4;
|
||||
this.responseHeaders = response.responseHeaders ||
|
||||
{"Content-type": response.contentType || "application/json" };
|
||||
// uncomment for jquery 1.3.x support
|
||||
// jasmine.Clock.tick(20);
|
||||
|
||||
this.onreadystatechange();
|
||||
},
|
||||
responseTimeout: function() {
|
||||
this.readyState = 4;
|
||||
jasmine.Clock.tick(jQuery.ajaxSettings.timeout || 30000);
|
||||
this.onreadystatechange('timeout');
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
jasmine.Ajax = {
|
||||
|
||||
isInstalled: function() {
|
||||
return jasmine.Ajax.installed == true;
|
||||
},
|
||||
|
||||
assertInstalled: function() {
|
||||
if (!jasmine.Ajax.isInstalled()) {
|
||||
throw new Error("Mock ajax is not installed, use jasmine.Ajax.useMock()")
|
||||
}
|
||||
},
|
||||
|
||||
useMock: function() {
|
||||
if (!jasmine.Ajax.isInstalled()) {
|
||||
var spec = jasmine.getEnv().currentSpec;
|
||||
spec.after(jasmine.Ajax.uninstallMock);
|
||||
|
||||
jasmine.Ajax.installMock();
|
||||
}
|
||||
},
|
||||
|
||||
installMock: function() {
|
||||
if (typeof jQuery != 'undefined') {
|
||||
jasmine.Ajax.installJquery();
|
||||
} else if (typeof Prototype != 'undefined') {
|
||||
jasmine.Ajax.installPrototype();
|
||||
} else {
|
||||
throw new Error("jasmine.Ajax currently only supports jQuery and Prototype");
|
||||
}
|
||||
jasmine.Ajax.installed = true;
|
||||
},
|
||||
|
||||
installJquery: function() {
|
||||
jasmine.Ajax.mode = 'jQuery';
|
||||
jasmine.Ajax.real = jQuery.ajaxSettings.xhr;
|
||||
jQuery.ajaxSettings.xhr = jasmine.Ajax.jQueryMock;
|
||||
|
||||
},
|
||||
|
||||
installPrototype: function() {
|
||||
jasmine.Ajax.mode = 'Prototype';
|
||||
jasmine.Ajax.real = Ajax.getTransport;
|
||||
|
||||
Ajax.getTransport = jasmine.Ajax.prototypeMock;
|
||||
},
|
||||
|
||||
uninstallMock: function() {
|
||||
jasmine.Ajax.assertInstalled();
|
||||
if (jasmine.Ajax.mode == 'jQuery') {
|
||||
jQuery.ajaxSettings.xhr = jasmine.Ajax.real;
|
||||
} else if (jasmine.Ajax.mode == 'Prototype') {
|
||||
Ajax.getTransport = jasmine.Ajax.real;
|
||||
}
|
||||
jasmine.Ajax.reset();
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
jasmine.Ajax.installed = false;
|
||||
jasmine.Ajax.mode = null;
|
||||
jasmine.Ajax.real = null;
|
||||
},
|
||||
|
||||
jQueryMock: function() {
|
||||
var newXhr = new FakeXMLHttpRequest();
|
||||
ajaxRequests.push(newXhr);
|
||||
return newXhr;
|
||||
},
|
||||
|
||||
prototypeMock: function() {
|
||||
return new FakeXMLHttpRequest();
|
||||
},
|
||||
|
||||
installed: false,
|
||||
mode: null
|
||||
}
|
||||
|
||||
|
||||
// Jasmine-Ajax Glue code for Prototype.js
|
||||
if (typeof Prototype != 'undefined' && Ajax && Ajax.Request) {
|
||||
Ajax.Request.prototype.originalRequest = Ajax.Request.prototype.request;
|
||||
Ajax.Request.prototype.request = function(url) {
|
||||
this.originalRequest(url);
|
||||
ajaxRequests.push(this);
|
||||
};
|
||||
|
||||
Ajax.Request.prototype.response = function(responseOptions) {
|
||||
return this.transport.response(responseOptions);
|
||||
};
|
||||
}
|
||||
288
GildedRose/js/lib/jasmine-jquery-1.3.1/jasmine-jquery-1.3.1.js
Normal file
288
GildedRose/js/lib/jasmine-jquery-1.3.1/jasmine-jquery-1.3.1.js
Normal file
@ -0,0 +1,288 @@
|
||||
var readFixtures = function() {
|
||||
return jasmine.getFixtures().proxyCallTo_('read', arguments);
|
||||
};
|
||||
|
||||
var preloadFixtures = function() {
|
||||
jasmine.getFixtures().proxyCallTo_('preload', arguments);
|
||||
};
|
||||
|
||||
var loadFixtures = function() {
|
||||
jasmine.getFixtures().proxyCallTo_('load', arguments);
|
||||
};
|
||||
|
||||
var setFixtures = function(html) {
|
||||
jasmine.getFixtures().set(html);
|
||||
};
|
||||
|
||||
var sandbox = function(attributes) {
|
||||
return jasmine.getFixtures().sandbox(attributes);
|
||||
};
|
||||
|
||||
var spyOnEvent = function(selector, eventName) {
|
||||
jasmine.JQuery.events.spyOn(selector, eventName);
|
||||
}
|
||||
|
||||
jasmine.getFixtures = function() {
|
||||
return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
|
||||
};
|
||||
|
||||
jasmine.Fixtures = function() {
|
||||
this.containerId = 'jasmine-fixtures';
|
||||
this.fixturesCache_ = {};
|
||||
this.fixturesPath = 'spec/javascripts/fixtures';
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.set = function(html) {
|
||||
this.cleanUp();
|
||||
this.createContainer_(html);
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.preload = function() {
|
||||
this.read.apply(this, arguments);
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.load = function() {
|
||||
this.cleanUp();
|
||||
this.createContainer_(this.read.apply(this, arguments));
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.read = function() {
|
||||
var htmlChunks = [];
|
||||
|
||||
var fixtureUrls = arguments;
|
||||
for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
|
||||
htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
|
||||
}
|
||||
|
||||
return htmlChunks.join('');
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.clearCache = function() {
|
||||
this.fixturesCache_ = {};
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.cleanUp = function() {
|
||||
jQuery('#' + this.containerId).remove();
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.sandbox = function(attributes) {
|
||||
var attributesToSet = attributes || {};
|
||||
return jQuery('<div id="sandbox" />').attr(attributesToSet);
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.createContainer_ = function(html) {
|
||||
var container;
|
||||
if(html instanceof jQuery) {
|
||||
container = jQuery('<div id="' + this.containerId + '" />');
|
||||
container.html(html);
|
||||
} else {
|
||||
container = '<div id="' + this.containerId + '">' + html + '</div>'
|
||||
}
|
||||
jQuery('body').append(container);
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
|
||||
if (typeof this.fixturesCache_[url] == 'undefined') {
|
||||
this.loadFixtureIntoCache_(url);
|
||||
}
|
||||
return this.fixturesCache_[url];
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
|
||||
var self = this;
|
||||
var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
|
||||
jQuery.ajax({
|
||||
async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
|
||||
cache: false,
|
||||
dataType: 'html',
|
||||
url: url,
|
||||
success: function(data) {
|
||||
self.fixturesCache_[relativeUrl] = data;
|
||||
},
|
||||
error: function(jqXHR, status, errorThrown) {
|
||||
throw Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
|
||||
return this[methodName].apply(this, passedArguments);
|
||||
};
|
||||
|
||||
|
||||
jasmine.JQuery = function() {};
|
||||
|
||||
jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
|
||||
return jQuery('<div/>').append(html).html();
|
||||
};
|
||||
|
||||
jasmine.JQuery.elementToString = function(element) {
|
||||
return jQuery('<div />').append(element.clone()).html();
|
||||
};
|
||||
|
||||
jasmine.JQuery.matchersClass = {};
|
||||
|
||||
(function(namespace) {
|
||||
var data = {
|
||||
spiedEvents: {},
|
||||
handlers: []
|
||||
};
|
||||
|
||||
namespace.events = {
|
||||
spyOn: function(selector, eventName) {
|
||||
var handler = function(e) {
|
||||
data.spiedEvents[[selector, eventName]] = e;
|
||||
};
|
||||
jQuery(selector).bind(eventName, handler);
|
||||
data.handlers.push(handler);
|
||||
},
|
||||
|
||||
wasTriggered: function(selector, eventName) {
|
||||
return !!(data.spiedEvents[[selector, eventName]]);
|
||||
},
|
||||
|
||||
cleanUp: function() {
|
||||
data.spiedEvents = {};
|
||||
data.handlers = [];
|
||||
}
|
||||
}
|
||||
})(jasmine.JQuery);
|
||||
|
||||
(function(){
|
||||
var jQueryMatchers = {
|
||||
toHaveClass: function(className) {
|
||||
return this.actual.hasClass(className);
|
||||
},
|
||||
|
||||
toBeVisible: function() {
|
||||
return this.actual.is(':visible');
|
||||
},
|
||||
|
||||
toBeHidden: function() {
|
||||
return this.actual.is(':hidden');
|
||||
},
|
||||
|
||||
toBeSelected: function() {
|
||||
return this.actual.is(':selected');
|
||||
},
|
||||
|
||||
toBeChecked: function() {
|
||||
return this.actual.is(':checked');
|
||||
},
|
||||
|
||||
toBeEmpty: function() {
|
||||
return this.actual.is(':empty');
|
||||
},
|
||||
|
||||
toExist: function() {
|
||||
return this.actual.size() > 0;
|
||||
},
|
||||
|
||||
toHaveAttr: function(attributeName, expectedAttributeValue) {
|
||||
return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
|
||||
},
|
||||
|
||||
toHaveId: function(id) {
|
||||
return this.actual.attr('id') == id;
|
||||
},
|
||||
|
||||
toHaveHtml: function(html) {
|
||||
return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
|
||||
},
|
||||
|
||||
toHaveText: function(text) {
|
||||
if (text && jQuery.isFunction(text.test)) {
|
||||
return text.test(this.actual.text());
|
||||
} else {
|
||||
return this.actual.text() == text;
|
||||
}
|
||||
},
|
||||
|
||||
toHaveValue: function(value) {
|
||||
return this.actual.val() == value;
|
||||
},
|
||||
|
||||
toHaveData: function(key, expectedValue) {
|
||||
return hasProperty(this.actual.data(key), expectedValue);
|
||||
},
|
||||
|
||||
toBe: function(selector) {
|
||||
return this.actual.is(selector);
|
||||
},
|
||||
|
||||
toContain: function(selector) {
|
||||
return this.actual.find(selector).size() > 0;
|
||||
},
|
||||
|
||||
toBeDisabled: function(selector){
|
||||
return this.actual.is(':disabled');
|
||||
},
|
||||
|
||||
// tests the existence of a specific event binding
|
||||
toHandle: function(eventName) {
|
||||
var events = this.actual.data("events");
|
||||
return events && events[eventName].length > 0;
|
||||
},
|
||||
|
||||
// tests the existence of a specific event binding + handler
|
||||
toHandleWith: function(eventName, eventHandler) {
|
||||
var stack = this.actual.data("events")[eventName];
|
||||
var i;
|
||||
for (i = 0; i < stack.length; i++) {
|
||||
if (stack[i].handler == eventHandler) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var hasProperty = function(actualValue, expectedValue) {
|
||||
if (expectedValue === undefined) {
|
||||
return actualValue !== undefined;
|
||||
}
|
||||
return actualValue == expectedValue;
|
||||
};
|
||||
|
||||
var bindMatcher = function(methodName) {
|
||||
var builtInMatcher = jasmine.Matchers.prototype[methodName];
|
||||
|
||||
jasmine.JQuery.matchersClass[methodName] = function() {
|
||||
if (this.actual instanceof jQuery) {
|
||||
var result = jQueryMatchers[methodName].apply(this, arguments);
|
||||
this.actual = jasmine.JQuery.elementToString(this.actual);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (builtInMatcher) {
|
||||
return builtInMatcher.apply(this, arguments);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
for(var methodName in jQueryMatchers) {
|
||||
bindMatcher(methodName);
|
||||
}
|
||||
})();
|
||||
|
||||
beforeEach(function() {
|
||||
this.addMatchers(jasmine.JQuery.matchersClass);
|
||||
this.addMatchers({
|
||||
toHaveBeenTriggeredOn: function(selector) {
|
||||
this.message = function() {
|
||||
return [
|
||||
"Expected event " + this.actual + " to have been triggered on" + selector,
|
||||
"Expected event " + this.actual + " not to have been triggered on" + selector
|
||||
];
|
||||
};
|
||||
return jasmine.JQuery.events.wasTriggered(selector, this.actual);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.getFixtures().cleanUp();
|
||||
jasmine.JQuery.events.cleanUp();
|
||||
});
|
||||
9266
GildedRose/js/lib/jquery-1.7.1/jquery-1.7.1.js
vendored
Normal file
9266
GildedRose/js/lib/jquery-1.7.1/jquery-1.7.1.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
GildedRose/js/spec/gilded_rose_spec.js
Normal file
7
GildedRose/js/spec/gilded_rose_spec.js
Normal file
@ -0,0 +1,7 @@
|
||||
describe("Gilded Rose", function() {
|
||||
|
||||
it("should do something", function() {
|
||||
update_quality
|
||||
});
|
||||
|
||||
});
|
||||
62
GildedRose/js/src/gilded_rose.js
Normal file
62
GildedRose/js/src/gilded_rose.js
Normal file
@ -0,0 +1,62 @@
|
||||
function Item(name, sell_in, quality) {
|
||||
this.name = name;
|
||||
this.sell_in = sell_in;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
var items = []
|
||||
|
||||
items.push(new Item('+5 Dexterity Vest', 10, 20));
|
||||
items.push(new Item('Aged Brie', 2, 0));
|
||||
items.push(new Item('Elixir of the Mongoose', 5, 7));
|
||||
items.push(new Item('Sulfuras, Hand of Ragnaros', 0, 80));
|
||||
items.push(new Item('Backstage passes to a TAFKAL80ETC concert', 15, 20));
|
||||
items.push(new Item('Conjured Mana Cake', 3, 6));
|
||||
|
||||
function update_quality() {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].name != 'Aged Brie' && items[i].name != 'Backstage passes to a TAFKAL80ETC concert') {
|
||||
if (items[i].quality > 0) {
|
||||
if (items[i].name != 'Sulfuras, Hand of Ragnaros') {
|
||||
items[i].quality = items[i].quality - 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (items[i].quality < 50) {
|
||||
items[i].quality = items[i].quality + 1
|
||||
if (items[i].name == 'Backstage passes to a TAFKAL80ETC concert') {
|
||||
if (items[i].sell_in < 11) {
|
||||
if (items[i].quality < 50) {
|
||||
items[i].quality = items[i].quality + 1
|
||||
}
|
||||
}
|
||||
if (items[i].sell_in < 6) {
|
||||
if (items[i].quality < 50) {
|
||||
items[i].quality = items[i].quality + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (items[i].name != 'Sulfuras, Hand of Ragnaros') {
|
||||
items[i].sell_in = items[i].sell_in - 1;
|
||||
}
|
||||
if (items[i].sell_in < 0) {
|
||||
if (items[i].name != 'Aged Brie') {
|
||||
if (items[i].name != 'Backstage passes to a TAFKAL80ETC concert') {
|
||||
if (items[i].quality > 0) {
|
||||
if (items[i].name != 'Sulfuras, Hand of Ragnaros') {
|
||||
items[i].quality = items[i].quality - 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items[i].quality = items[i].quality - items[i].quality
|
||||
}
|
||||
} else {
|
||||
if (items[i].quality < 50) {
|
||||
items[i].quality = items[i].quality + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user