Skip to content

Commit 1f5db76

Browse files
committed
Merge pull request #32 from hdgarrood/node-support
node.js support, via npm package 'xmlhttprequest'
2 parents 58d9282 + 13d196f commit 1f5db76

File tree

4 files changed

+62
-15
lines changed

4 files changed

+62
-15
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ install:
1313
- npm install && bower install
1414
script:
1515
- gulp
16+
- node ./test-server.js &
17+
- node tmp/test.js

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"gulp-plumber": "^1.0.0",
88
"gulp-purescript": "^0.5.0",
99
"express": "^4.13.1",
10-
"body-parser": "^1.13.2"
10+
"body-parser": "^1.13.2",
11+
"xmlhttprequest": "^1.7.0"
1112
}
1213
}

src/Network/HTTP/Affjax.js

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,52 @@
1-
/* jshint browser: true */
21
/* global exports */
2+
/* global XMLHttpRequest */
3+
/* global require */
4+
/* global module */
35
"use strict";
46

57
// module Network.HTTP.Affjax
68

79
// jshint maxparams: 5
810
exports._ajax = function (mkHeader, options, canceler, errback, callback) {
11+
var platformSpecific = { };
12+
if (typeof module !== "undefined" && module.exports) {
13+
// We are on node.js
14+
platformSpecific.newXHR = function () {
15+
var XHR = require("xmlhttprequest").XMLHttpRequest;
16+
return new XHR();
17+
};
18+
19+
platformSpecific.fixupUrl = function (url) {
20+
var urllib = require("url");
21+
var u = urllib.parse(url);
22+
u.protocol = u.protocol || "http:";
23+
u.hostname = u.hostname || "localhost";
24+
return urllib.format(u);
25+
};
26+
27+
platformSpecific.getResponse = function (xhr) {
28+
// the node package 'xmlhttprequest' does not support xhr.response.
29+
return xhr.responseText;
30+
};
31+
} else {
32+
// We are in the browser
33+
platformSpecific.newXHR = function () {
34+
return new XMLHttpRequest();
35+
};
36+
37+
platformSpecific.fixupUrl = function (url) {
38+
return url || "/";
39+
};
40+
41+
platformSpecific.getResponse = function (xhr) {
42+
return xhr.response;
43+
};
44+
}
45+
946
return function () {
10-
var xhr = new XMLHttpRequest();
11-
xhr.open(options.method || "GET", options.url || "/", true, options.username, options.password);
47+
var xhr = platformSpecific.newXHR();
48+
var fixedUrl = platformSpecific.fixupUrl(options.url);
49+
xhr.open(options.method || "GET", fixedUrl, true, options.username, options.password);
1250
if (options.headers) {
1351
for (var i = 0, header; (header = options.headers[i]) != null; i++) {
1452
xhr.setRequestHeader(header.field, header.value);
@@ -28,7 +66,7 @@ exports._ajax = function (mkHeader, options, canceler, errback, callback) {
2866
var i = header.indexOf(":");
2967
return mkHeader(header.substring(0, i))(header.substring(i + 2));
3068
}),
31-
response: xhr.response
69+
response: platformSpecific.getResponse(xhr)
3270
})();
3371
};
3472
xhr.responseType = options.responseType;

test/Main.purs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,41 +55,47 @@ assertEq x y = if x == y
5555
typeIs :: forall e a. a -> Assert e Unit
5656
typeIs = const (return unit)
5757

58-
main = runAff throwException (const $ log "affjax: All good!") $ do
58+
main = runAff (\e -> print e >>= \_ -> throwException e) (const $ log "affjax: All good!") $ do
5959
let ok200 = StatusCode 200
6060
let notFound404 = StatusCode 404
6161

62-
A.log "GET /does-not-exists: should be 404 Not found after retries"
63-
(attempt $ retry (Just 5000) affjax $ defaultRequest { url = "/does-not-exist" }) >>= assertRight >>= \res -> do
62+
-- A complete URL is necessary for tests to work on Node.js
63+
let prefix = append "http://localhost:3838"
64+
let mirror = prefix "/mirror"
65+
let doesNotExist = prefix "/does-not-exist"
66+
let notJson = prefix "/not-json"
67+
68+
A.log "GET /does-not-exist: should be 404 Not found after retries"
69+
(attempt $ retry (Just 5000) affjax $ defaultRequest { url = doesNotExist }) >>= assertRight >>= \res -> do
6470
typeIs (res :: AffjaxResponse String)
6571
assertEq notFound404 res.status
6672

6773
A.log "GET /mirror: should be 200 OK"
68-
(attempt $ affjax $ defaultRequest { url = "/mirror" }) >>= assertRight >>= \res -> do
74+
(attempt $ affjax $ defaultRequest { url = mirror }) >>= assertRight >>= \res -> do
6975
typeIs (res :: AffjaxResponse Foreign)
7076
assertEq ok200 res.status
7177

7278
A.log "GET /does-not-exist: should be 404 Not found"
73-
(attempt $ affjax $ defaultRequest { url = "/does-not-exist" }) >>= assertRight >>= \res -> do
79+
(attempt $ affjax $ defaultRequest { url = doesNotExist }) >>= assertRight >>= \res -> do
7480
typeIs (res :: AffjaxResponse String)
7581
assertEq notFound404 res.status
7682

7783
A.log "GET /not-json: invalid JSON with Foreign response should throw an error"
78-
assertLeft =<< attempt (get "/not-json" :: Affjax _ Foreign)
84+
assertLeft =<< attempt (get doesNotExist :: Affjax _ Foreign)
7985

8086
A.log "GET /not-json: invalid JSON with String response should be ok"
81-
(attempt $ get "/not-json") >>= assertRight >>= \res -> do
87+
(attempt $ get notJson) >>= assertRight >>= \res -> do
8288
typeIs (res :: AffjaxResponse String)
8389
assertEq ok200 res.status
8490

8591
A.log "POST /mirror: should use the POST method"
86-
(attempt $ post "/mirror" "test") >>= assertRight >>= \res -> do
92+
(attempt $ post mirror "test") >>= assertRight >>= \res -> do
8793
assertEq ok200 res.status
8894
assertEq "POST" (_.method $ unsafeFromForeign res.response)
8995

9096
A.log "PUT with a request body"
9197
let content = "the quick brown fox jumps over the lazy dog"
92-
(attempt $ put "/mirror" content) >>= assertRight >>= \res -> do
98+
(attempt $ put mirror content) >>= assertRight >>= \res -> do
9399
typeIs (res :: AffjaxResponse Foreign)
94100
assertEq ok200 res.status
95101
let mirroredReq = unsafeFromForeign res.response
@@ -103,6 +109,6 @@ main = runAff throwException (const $ log "affjax: All good!") $ do
103109
-- assertEq (Just "test=test") (lookupHeader "Set-Cookie" res.headers)
104110

105111
A.log "Testing cancellation"
106-
canceler <- forkAff (post_ "/mirror" "do it now")
112+
canceler <- forkAff (post_ mirror "do it now")
107113
canceled <- canceler `cancel` error "Pull the cord!"
108114
assertMsg "Should have been canceled" canceled

0 commit comments

Comments
 (0)