Skip to content

Run tests on the command line #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# todo-backend-js-spec

Executable specs in javascript for the Todo-Backend API.

## Run in the browser

Start a static web server, eg.:
`python3 -m http.server`

## Run on the command line

Install packages:
```
npm install -g mocha
cd todo-backend-js-spec
npm install
```

Suppose the implementation you want to test is at http://localhost:5000
Windows:
`SET TARGET_ADDRESS=http://localhost:5000 && npm test`

Linux:
`export TARGET_ADDRESS=http://localhost:5000 && npm test`
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ <h2>these tests are targeting: <span class="target-url"/></h2>
<script src="js/lib/chai-as-promised.js"></script>
<script src="js/lib/mocha.js"></script>

<script src="js/browser-util.js"></script>
<script src="js/specs.js"></script>

<script src="js/setup.js"></script>
Expand Down
44 changes: 44 additions & 0 deletions js/browser-util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function interpretXhrFail(httpMethod,url,xhr){
var failureHeader = "\n\n"+httpMethod+" "+url+"\nFAILED\n\n";
if( xhr.status == 0 ){
return Error(
failureHeader
+ "The browser failed entirely when make an AJAX request.\n"
+ "Either there is a network issue in reaching the url, or the\n"
+ "server isn't doing the CORS things it needs to do.\n"
+ "Ensure that you're sending back: \n"
+ " - an `access-control-allow-origin: *` header for all requests\n"
+ " - an `access-control-allow-headers` header which lists headers such as \"Content-Type\"\n"
+ "\n"
+ "Also ensure you are able to respond to OPTION requests appropriately. \n"
+ "\n"
);
}else{
return Error(
failureHeader
+ xhr.status + ": " + xhr.statusText + " (" + xhr.responseText.replace(/\n*$/, "") + ")"
+ "\n\n"
);
}
}

function ajax(httpMethod, url, options){
var ajaxOptions = _.defaults( (options||{}), {
type: httpMethod,
url: url,
contentType: "application/json",
dataType: "text", // so we can explicitly parse JSON and fail with more detail than jQuery usually would give us
timeout: 30000 // so that we don't fail while waiting on a heroku dyno to spin up
});

var xhr = $.ajax( ajaxOptions );

return Q.promise( function(resolve, reject){
xhr.success( function(){
return resolve(xhr);
});
xhr.fail( function(){
reject(interpretXhrFail(httpMethod,url,xhr));
});
});
};
19 changes: 19 additions & 0 deletions js/cli-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
_ = require("underscore");
Q = require("q");
chai = require("chai")
expect = chai.expect;
chaiAsPromised = require("chai-as-promised");
request = require('request');

chai.use(chaiAsPromised);

var node_util = require("./node-util.js");
var specs = require("./specs.js");

ajax = node_util.ajax

var address = process.env.TARGET_ADDRESS;
if(typeof(address) == "undefined") {
throw Error ("The environment variable TARGET_ADDRESS is not set. Please set it to the address of the backend to be tested.")
}
specs.defineSpecsFor(address);
57 changes: 57 additions & 0 deletions js/node-util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
function interpretXhrFail(httpMethod,url, error, response, body){
var failureHeader = "\n\n"+httpMethod+" "+url+"\nFAILED\n\n";
if( error ){
return Error(
failureHeader
+ "The browser failed entirely when make an AJAX request.\n"
+ "Either there is a network issue in reaching the url, or the\n"
+ "server isn't doing the CORS things it needs to do.\n"
+ "Ensure that you're sending back: \n"
+ " - an `access-control-allow-origin: *` header for all requests\n"
+ " - an `access-control-allow-headers` header which lists headers such as \"Content-Type\"\n"
+ "\n"
+ "Also ensure you are able to respond to OPTION requests appropriately. \n"
+ "\n"
);
}else{
return Error(
failureHeader
+ response.statusCode + ": " + response.statusMessage + " (" + body.replace(/\n*$/, "") + ")"
+ "\n\n"
);
}
}

function ajax(httpMethod, url, options){

options = options || {};

// Translate properties for request js
if(_.has(options, 'data')) {
options.body = options.data
delete options.data
}

var ajaxOptions = _.defaults( options, {
method: httpMethod,
url: url,
headers: {'Content-Type': 'application/json'},
timeout: 30000 // so that we don't fail while waiting on a heroku dyno to spin up
});

return Q.promise( function(resolve, reject){

request(ajaxOptions, function (error, response, body){

if(error || response.statusCode < 200 || response.statusCode >= 400) {
reject(interpretXhrFail(httpMethod, url, error, response, body));
} else {
resolve(body);
}
});
});
};

module.exports = {
ajax: ajax
}
47 changes: 3 additions & 44 deletions js/specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,49 +231,8 @@ function defineSpecsFor(apiRoot){
throw wrapped;
}
}
}

function interpretXhrFail(httpMethod,url,xhr){
var failureHeader = "\n\n"+httpMethod+" "+url+"\nFAILED\n\n";
if( xhr.status == 0 ){
return Error(
failureHeader
+ "The browser failed entirely when make an AJAX request.\n"
+ "Either there is a network issue in reaching the url, or the\n"
+ "server isn't doing the CORS things it needs to do.\n"
+ "Ensure that you're sending back: \n"
+ " - an `access-control-allow-origin: *` header for all requests\n"
+ " - an `access-control-allow-headers` header which lists headers such as \"Content-Type\"\n"
+ "\n"
+ "Also ensure you are able to respond to OPTION requests appropriately. \n"
+ "\n"
);
}else{
return Error(
failureHeader
+ xhr.status + ": " + xhr.statusText + " (" + xhr.responseText.replace(/\n*$/, "") + ")"
+ "\n\n"
);
}
}

function ajax(httpMethod, url, options){
var ajaxOptions = _.defaults( (options||{}), {
type: httpMethod,
url: url,
contentType: "application/json",
dataType: "text", // so we can explicitly parse JSON and fail with more detail than jQuery usually would give us
timeout: 30000 // so that we don't fail while waiting on a heroku dyno to spin up
});

var xhr = $.ajax( ajaxOptions );

return Q.promise( function(resolve, reject){
xhr.success( function(){
return resolve(xhr);
});
xhr.fail( function(){
reject(interpretXhrFail(httpMethod,url,xhr));
});
});
};
module.exports = {
defineSpecsFor: defineSpecsFor
}
Loading