Skip to content

Commit 59cb59c

Browse files
committed
Merge pull request #48 from TheSharpieOne/master
Refactoring, Tests, and More
2 parents 7730996 + ef40dee commit 59cb59c

14 files changed

+1152
-87
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,8 @@ results
5050

5151
npm-debug.log
5252
node_modules
53+
bower_components
54+
build
5355

54-
.tern-project
56+
.tern-project
57+
.idea

.travis.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language: node_js
2+
node_js:
3+
- "0.10"
4+
5+
before_script:
6+
- npm install
7+
- npm install -g gulp
8+
- npm install -g bower
9+
- bower install -F
10+
11+
script:
12+
- gulp build-js
13+
- gulp test-build

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[![Build Status](https://travis-ci.org/janpantel/angular-sails.svg?branch=master)](https://travis-ci.org/janpantel/angular-sails)
2+
13
Angular Sails
24
=============
35

@@ -28,15 +30,24 @@ app.controller("FooController", function ($scope, $sails) {
2830
$scope.bars = [];
2931

3032
(function () {
33+
// Using .success() and .error()
3134
$sails.get("/bars")
32-
.success(function (data) {
35+
.success(function (data, status, headers, jwr) {
3336
$scope.bars = data;
3437
})
35-
.error(function (data) {
38+
.error(function (data, status, headers, jwr) {
3639
alert('Houston, we got a problem!');
3740
});
3841

42+
// Using .then()
43+
$sails.get("/bars")
44+
.then(function(resp){
45+
$scope.bars = resp.data;
46+
}, function(resp){
47+
alert('Houston, we got a problem!');
48+
});
3949

50+
// Watching for updates
4051
$sails.on("bars", function (message) {
4152
if (message.verb === "created") {
4253
$scope.bars.push(message.data);

bower.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@
1818
"license": "MIT",
1919
"homepage": "https://github.com/kyjan/angular-sails",
2020
"dependencies": {
21-
"angular": ">=1.2.*"
21+
"angular": ">=1.2.*",
22+
"sails.io.js": "*"
23+
},
24+
"devDependencies":{
25+
"angular-mocks": ">=1.2.*"
2226
},
2327
"ignore": [
2428
"**/.*",
2529
"gulpfile.js",
2630
"package.json",
2731
"node_modules",
32+
"build",
33+
"mock",
2834
"bower_components",
2935
"app/bower_components",
3036
"test",

dist/angular-sails.js

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ angular.module('ngSails').provider('$sails', function () {
1111

1212
this.url = undefined;
1313
this.interceptors = [];
14+
this.responseHandler = undefined;
1415

1516
this.$get = ['$q', '$timeout', function ($q, $timeout) {
1617
var socket = io.connect(provider.url),
@@ -19,23 +20,45 @@ angular.module('ngSails').provider('$sails', function () {
1920
promise = deferred.promise;
2021

2122
promise.success = function (fn) {
22-
promise.then(fn);
23+
promise.then(function(response) {
24+
fn(response.data, response.status, response.headers);
25+
});
2326
return promise;
2427
};
2528

2629
promise.error = function (fn) {
27-
promise.then(null, fn);
30+
promise.then(null, function(response) {
31+
fn(response.data, response.status, response.headers);
32+
});
2833
return promise;
2934
};
3035

3136
return deferred;
3237
},
33-
resolveOrReject = function (deferred, data) {
34-
// Make sure what is passed is an object that has a status and if that status is no 2xx, reject.
35-
if (data && angular.isObject(data) && data.status && Math.floor(data.status / 100) !== 2) {
36-
deferred.reject(data);
38+
resolveOrReject = this.responseHandler || function (deferred, response) {
39+
var jwr = response;
40+
41+
// backward compatibility with older sails.io (no JWR)
42+
if(!(response instanceof Object && response.constructor.name === "JWR")){
43+
jwr = {
44+
body: response,
45+
headers: response.headers || {},
46+
statusCode: response.statusCode || response.status
47+
};
48+
}
49+
50+
// angular $http returns the 'body' as 'data'.
51+
jwr.data = jwr.body;
52+
53+
// angular $http returns the 'statusCode' as 'status'.
54+
jwr.status = jwr.statusCode;
55+
56+
// TODO: map 'status'/'statusCode' to a 'statusText' to mimic angular $http
57+
58+
if (jwr.error) {
59+
deferred.reject(jwr);
3760
} else {
38-
deferred.resolve(data);
61+
deferred.resolve(jwr);
3962
}
4063
},
4164
angularify = function (cb, data) {
@@ -52,8 +75,8 @@ angular.module('ngSails').provider('$sails', function () {
5275
data = null;
5376
}
5477
deferred.promise.then(cb);
55-
socket['legacy_' + methodName](url, data, function (result) {
56-
resolveOrReject(deferred, result);
78+
socket['legacy_' + methodName](url, data, function (emulatedHTTPBody, jsonWebSocketResponse) {
79+
resolveOrReject(deferred, jsonWebSocketResponse || emulatedHTTPBody);
5780
});
5881
return deferred.promise;
5982
};

dist/angular-sails.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

files.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
var pkg = require('./package.json');
2+
3+
var pkgFiles = {
4+
angular: [
5+
'bower_components/angular/angular.js'
6+
],
7+
karma: [
8+
'bower_components/angular/angular.js',
9+
'bower_components/angular-mocks/angular-mocks.js',
10+
'mock/socket-io.js',
11+
'bower_components/sails.io.js/sails.io.js'
12+
],
13+
'karma-build': [
14+
'@karma',
15+
'build/' + pkg.name + '.js',
16+
'@karma-tests'
17+
],
18+
'karma-min': [
19+
'@karma',
20+
'build/' + pkg.name + '.min.js',
21+
'@karma-tests'
22+
],
23+
'karma-src': [
24+
'@karma',
25+
'@src',
26+
'@karma-tests'
27+
],
28+
'karma-tests': [
29+
'test/**/*.spec.js'
30+
],
31+
src: [
32+
'src/**/*.js',
33+
]
34+
};
35+
36+
if (module.exports) {
37+
module.exports.files = pkgFiles;
38+
module.exports.mergeFilesFor = function() {
39+
var files = [];
40+
41+
Array.prototype.slice.call(arguments, 0).forEach(function(filegroup) {
42+
pkgFiles[filegroup].forEach(function(file) {
43+
// replace @ref
44+
var match = file.match(/^\@(.*)/);
45+
if (match) {
46+
files = files.concat(pkgFiles[match[1]]);
47+
} else {
48+
files.push(file);
49+
}
50+
});
51+
});
52+
53+
return files;
54+
};
55+
}

gulpfile.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,49 @@
1+
'use strict';
2+
13
var gulp = require('gulp'),
24
concat = require('gulp-concat'),
35
uglify = require('gulp-uglify'),
46
header = require('gulp-header'),
5-
footer = require('gulp-footer');
7+
footer = require('gulp-footer'),
8+
ngAnnotate = require('gulp-ng-annotate'),
9+
gulpKarma = require('gulp-karma'),
10+
pkg = require('./package.json'),
11+
files = require('./files');
12+
13+
var karmaTestConfig = gulpKarma({configFile: 'karma.conf.js', action: 'run'});
614

715

816
gulp.task('build-js', function () {
9-
gulp.src(['src/ngSails.js', 'src/**/*.js'])
10-
.pipe(concat('angular-sails.js'))
17+
return gulp.src(files.mergeFilesFor('src'))
18+
.pipe(ngAnnotate())
19+
.pipe(concat(pkg.name+'.js'))
1120
.pipe(header('(function (angular, io) {\n\'use strict\''))
1221
.pipe(footer('}(angular, io));'))
13-
.pipe(gulp.dest('./dist/'))
14-
.pipe(concat('angular-sails.min.js'))
22+
.pipe(gulp.dest('./build/'))
23+
.pipe(concat(pkg.name+'.min.js'))
1524
.pipe(uglify())
16-
.pipe(gulp.dest('./dist/'));
25+
.pipe(gulp.dest('./build/'));
26+
});
27+
28+
gulp.task('dist-js', ['build-js'], function () {
29+
return gulp.src('./build/*.js')
30+
.pipe(gulp.dest('./dist/'));
31+
});
32+
33+
gulp.task('test', function () {
34+
return gulp.src(files.mergeFilesFor('karma-src')).pipe(karmaTestConfig);
35+
});
36+
37+
gulp.task('test-build', ['build-js'], function () {
38+
return gulp.src(files.mergeFilesFor('karma-build')).pipe(karmaTestConfig);
39+
});
40+
41+
gulp.task('test-min', ['build-js'], function () {
42+
return gulp.src(files.mergeFilesFor('karma-min')).pipe(karmaTestConfig);
1743
});
1844

1945
gulp.task('watch', function () {
20-
gulp.watch('src/**/*.js', ['build-js']);
46+
return gulp.watch('src/**/*.js', ['build-js']);
2147
});
2248

2349
gulp.task('default', ['build-js', 'watch']);

karma.conf.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Karma configuration
2+
// Generated on Thu Jan 09 2014 13:59:16 GMT-0500 (EST)
3+
4+
module.exports = function (config) {
5+
config.set({
6+
basePath: './',
7+
8+
frameworks: ['mocha', 'chai-sinon'],
9+
10+
exclude: [],
11+
12+
reporters: ['progress'],
13+
14+
port: 9876,
15+
16+
runnerPort: 9100,
17+
18+
colors: true,
19+
20+
logLevel: config.LOG_INFO,
21+
22+
autoWatch: true,
23+
24+
// Start these browsers, currently available:
25+
// - Chrome
26+
// - ChromeCanary (has to be installed with `npm install karma-chrome-canary-launcher`)
27+
// - Firefox (has to be installed with `npm install karma-firefox-launcher`)
28+
// - Opera (has to be installed with `npm install karma-opera-launcher`)
29+
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
30+
// - PhantomJS
31+
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
32+
browsers: ['PhantomJS'],
33+
34+
captureTimeout: 60000,
35+
36+
singleRun: false
37+
});
38+
};

mock/socket-io.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// fix for phantomjs < 2.0
2+
if (!Function.prototype.bind) {
3+
Function.prototype.bind = function(oThis) {
4+
if (typeof this !== 'function') {
5+
// closest thing possible to the ECMAScript 5
6+
// internal IsCallable function
7+
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
8+
}
9+
10+
var aArgs = Array.prototype.slice.call(arguments, 1),
11+
fToBind = this,
12+
fNOP = function() {},
13+
fBound = function() {
14+
return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
15+
aArgs.concat(Array.prototype.slice.call(arguments)));
16+
};
17+
18+
fNOP.prototype = this.prototype;
19+
fBound.prototype = new fNOP();
20+
21+
return fBound;
22+
};
23+
}
24+
25+
function io() {
26+
var mockSocketObject = createMockSocketObject();
27+
return mockSocketObject.connect();
28+
}
29+
30+
function createMockSocketObject() {
31+
32+
var socket = {
33+
on: function(ev, fn) {
34+
(this._listeners[ev] = this._listeners[ev] || []).push(fn);
35+
},
36+
once: function(ev, fn) {
37+
(this._raw._listeners[ev] = this._raw._listeners[ev] || []).push(fn);
38+
fn._once = true;
39+
},
40+
emit: function(ev, data) {
41+
if (this._listeners[ev]) {
42+
var args = arguments;
43+
this._listeners[ev].forEach(function(listener) {
44+
if (listener._once) {
45+
this.removeListener(ev, listener);
46+
}
47+
listener.apply(null, Array.prototype.slice.call(args, 1));
48+
}.bind(this));
49+
}
50+
},
51+
_listeners: {},
52+
removeListener: function(ev, fn) {
53+
if (fn) {
54+
var index = this._listeners[ev].indexOf(fn);
55+
if (index > -1) {
56+
this._listeners[ev].splice(index, 1);
57+
}
58+
} else {
59+
delete this._listeners[ev];
60+
}
61+
},
62+
removeAllListeners: function(ev) {
63+
if (ev) {
64+
delete this._listeners[ev];
65+
} else {
66+
this._listeners = {};
67+
}
68+
},
69+
disconnect: function() {
70+
this.connected = false;
71+
this.emit('disconnect');
72+
},
73+
connect: function() {
74+
this.connected = true;
75+
this.emit('connect');
76+
return this;
77+
}
78+
};
79+
80+
return socket;
81+
}

0 commit comments

Comments
 (0)