...
 
Commits (11)
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.json]
indent_size = 2
# Esse exemplo não é muito diferente do que você já viu anteriormente. A
# diferença é que este projeto utiliza módulos para cobertura de código, que
# indicam porcentagem do código coberta pelos testes da aplicação.
# Para que o Gitlab exiba essa informação na interface é necessário editar o
# campo "Test coverage parsing", em <project>/Settings, adicionando expressão
# regular de acordo com o informado pelo programa utilizado no seu projeto
# para cobertura de código.
#
# Para esse programa, a expressão regular é ^Statements\s*:\s*\d+.\d+\%
image: node:4.2
services:
- mongo:latest
before_script:
- npm config set cache /cache/npm
- npm install --silent -g gulp
- npm install --silent
- cp config/example.yaml config/test.yaml
- sed -i 's/database\x3a[ ]*\x27test\x27/database\x3a \x27simmc_test\x27/' config/test.yaml
- sed -i 's/host\x3a[ ]*\x27localhost\x27/host\x3a \x27mongo\x27/' config/test.yaml
check:
stage: test
script:
# Verifica padrão de escrita de código
- gulp lint
# Executa testes unitários
- gulp test
tags:
- node
- mongo
{
"preset": "airbnb",
"validateIndentation": 4,
"requireTrailingComma": false,
"disallowTrailingComma": true,
"requireCurlyBraces": [
"if",
"else",
"for",
"while",
"do",
"try",
"catch"
],
"requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties",
"disallowKeywordsOnNewLine": [],
"maximumLineLength": 80,
"requirePaddingNewLinesAfterBlocks": {
"allExcept": ["inCallExpressions", "inNewExpressions", "inArrayExpressions", "inProperties"]
}
}
{
/*
* ENVIRONMENTS
* =================
*/
// Define globals exposed by modern browsers.
"browser": false,
// Define globals exposed by Node.js.
"node": true,
// Allow ES6.
"esnext": true,
/*
* ENFORCING OPTIONS
* =================
*/
// Prohibit use of == and != in favor of === and !==.
"eqeqeq": true,
// Enforce tab width of 2 spaces.
"indent": 4,
// Prohibit use of a variable before it is defined.
"latedef": false,
// Require capitalized names for constructor functions.
"newcap": true,
// Enforce use of single quotation marks for strings.
"quotmark": "single",
// Prohibit use of explicitly undeclared variables.
"undef": true,
// Warn when variables are defined but never used.
"unused": "vars",
/*
* RELAXING OPTIONS
* =================
*/
// Suppress warnings about == null comparisons.
"eqnull": true,
// Add global variables for Mocha and Chai
"globals": {
"describe": false,
"xdescribe": false,
"ddescribe": false,
"it": false,
"xit": false,
"iit": false,
"beforeEach": false,
"afterEach": false,
"before": false,
"after": false
}
}
This diff is collapsed.
Esse repositório contém exemplos de uso do sistema de integração contínua do
gitlab.
Cada exemplo encontra-se em um ramo diferente, nomeado como
`exemplo/X`, onde X é um inteiro crescente. Normalmente, quanto maior X, mais
funcionalidades são apresentadas.
Para ver o primeiro exemplo mude para o *branch* `exemplo/1` com o comando abaixo e
abra o arquivo `.gitlab-ci.yml`.
```
git checkout -t origin/exemplo/1
```
Todos os *builds* feitos aparecem no item *Builds*, aba *All*, do menu lateral esquerdo
no Gitlab.
Clique no valor sob a coluna *Status* para ver detalhes do *build*. Repare
no campo *Ref*, que indica o *branch* onde a *build* foi executada.
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var FilterParser = require('filter-parser');
var createError = require('http-errors');
module.exports = {
list: list,
index: index,
read: read
};
var filterParser = new FilterParser({
identifierParser: function(ident) {
// convert the identifier id into _id
if (ident === 'id') {
ident = '_id';
}
// only accept a few valid identifiers
if ((ident !== '_id') &&
(ident !== 'name') &&
(ident !== 'adminLevel') &&
(ident !== 'extras.city_code')) {
throw new Error('Invalid identifier ' + ident);
}
return ident;
}
});
function mapLocation(doc) {
return {
id: parseInt(doc.id),
score: doc.score,
name: doc.name,
adminLevel: doc.adminLevel,
border: doc.border,
subDivisions: doc.subDivisions,
extras: doc.extras
};
}
function list(req, res, next) {
var Location = req.db.model('Location');
// retrieve query parameters
var perPage = req.query.per_page || 10;
var page = req.query.page || 1;
var search = req.query.query;
var filters = req.query.filters;
// build the query
var qQuery = {};
var qProjection = { _id: 1, name: 1, adminLevel: 1, extras: 1 };
var qSort = { _id: 1 };
if (filters) {
try {
qQuery = filterParser.parse(filters);
}
catch (err) {
next(createError.BadRequest(
'Invalid filter expression. Check your syntax and try again.'));
return;
}
}
if (search) {
qQuery.$text = { $search: search };
qProjection.score = { $meta: 'textScore' };
qSort = { score: { $meta: 'textScore' } };
}
var q = Location
.find(qQuery, qProjection)
.sort(qSort)
.skip((page - 1) * perPage)
.limit(perPage);
// execute the query
q.exec(function(err, docs) {
if (err) {
req.log.error(err);
next(createError.BadRequest(
'Unfortunately, the request you are making cannot be ' +
'fulfilled by the server.'));
return;
}
var locations = [];
docs.forEach(function(doc) {
locations.push(mapLocation(doc));
});
res.status(200).json(locations);
});
}
function index(req, res, next) {
var Location = req.db.model('Location');
var q = Location
.find({}, { _id: 1, adminLevel: 1, name: 1 })
.sort({ _id: 1 });
// execute the query
q.exec(function(err, docs) {
/* istanbul ignore if */
if (err) {
req.log.error(err);
next(createError.InternalServerError());
return;
}
var result = {
keys: ['adminLevel', 'id', 'name'],
index: {}
};
docs.forEach(function(doc) {
if (!result.index[doc.adminLevel]) {
result.index[doc.adminLevel] = {};
}
result.index[doc.adminLevel][doc.id] = doc.name;
});
res.status(200).json(result);
});
}
function read(req, res, next) {
var Location = req.db.model('Location');
var locationId = req.params.locationId;
var projection = {
_id: 1,
name: 1,
adminLevel: 1,
extras: 1
};
if (req.query.border) {
projection.border = 1;
}
if (req.query.sub_divisions) {
projection.subDivisions = 1;
}
Location.findOne({_id: locationId}, projection, function(err, doc) {
/* istanbul ignore if */
if (err) {
req.log.error(err);
next(createError.InternalServerError());
return;
}
if (!doc) {
next(createError.NotFound(
'Location \'' + locationId + '\' could not be found.'));
return;
}
res.status(200).json(mapLocation(doc));
});
}
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
module.exports = {
list: list,
create: create,
read: read,
update: update,
delete: del
};
function mapUser(doc) {
var user = {
id: String(doc.id),
email: doc.email,
firstname: doc.firstname,
lastname: doc.lastname,
tags: doc.tags,
created_at: doc.created_at,
updated_at: doc.updated_at
};
return user;
}
function list(req, res) {
var User = req.db.model('User');
var perPage = req.query.per_page || 10;
var page = req.query.page || 1;
var offset = (page - 1) * perPage;
var q = User
.find()
.skip(offset)
.limit(perPage);
q.exec(function(err, docs) {
if (err) {
console.error(err);
res.status(500).json({ message: 'Database query failed.' });
return;
}
var users = [];
docs.forEach(function(doc) {
users.push(mapUser(doc));
});
res.json(users);
});
}
function create(req, res) {
var User = req.db.model('User');
var userEmail = req.body.email;
var userPassword = req.body.password;
var userFirstname = req.body.firstname;
var userLastname = req.body.lastname;
var userTags = req.body.tags;
// add comment
var doc = new User();
doc.email = userEmail;
doc.password = userPassword;
doc.firstname = userFirstname;
doc.lastname = userLastname;
doc.tags = userTags;
doc.save(function(err) {
if (err) {
console.error(err);
res.status(500).json({
message: 'Failed to save user to the database.'
});
return;
}
res.status(200).json(mapUser(doc));
});
}
function read(req, res) {
var User = req.db.model('User');
var userId = req.params.userId;
User.findOne({_id: userId}, function(err, doc) {
if (err) {
console.error(err);
res.status(500).json({ message: 'Database query failed.' });
return;
}
if (!doc) {
res.status(404).json({ message: 'User could not be found.' });
return;
}
res.status(200).json(mapUser(doc));
});
}
function update(req, res) {
var User = req.db.model('User');
var userId = req.params.userId;
var userEmail = req.body.email;
var userPassword = req.body.password;
var userFirstname = req.body.firstname;
var userLastname = req.body.lastname;
var userTags = req.body.tags;
User.findOne({_id: userId}, function(err, doc) {
if (err) {
console.error(err);
res.status(500).json({ message: 'Database query failed.' });
return;
}
if (!doc) {
res.status(404).json({ message: 'User could not be found.' });
return;
}
doc.email = userEmail || doc.email;
doc.password = userPassword || doc.password;
doc.firstname = userFirstname || doc.firstname;
doc.lastname = userLastname || doc.lastname;
doc.tags = userTags || doc.tags;
doc.save(function(err) {
if (err) {
console.error(err);
res.status(500).json({
message: 'Failed to save user to the database.'
});
return;
}
res.status(200).json(mapUser(doc));
});
});
}
function del(req, res) {
var User = req.db.model('User');
var userId = req.params.userId;
User.findOne({_id: userId}, function(err, doc) {
if (err) {
console.error(err);
res.status(500).json({ message: 'Database query failed.' });
return;
}
if (!doc) {
res.status(404).json({ message: 'User could not be found.' });
return;
}
doc.remove(function(err) {
if (err) {
console.error(err);
res.status(500).json({ message: 'Database query failed.' });
return;
}
res.status(200).json({ message: 'User sucessufully removed.' });
});
});
}
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var mongoose = require('mongoose');
var glob = require('glob');
var path = require('path');
module.exports = function(config) {
var connectString = 'mongodb://' + config.get('mongodb.host') + ':' +
config.get('mongodb.port') + '/' +
config.get('mongodb.database');
mongoose.connect(connectString);
mongoose.connection.on('error', function(err) {
throw err;
});
glob.sync(path.resolve(__dirname, '../models/*.js'))
.forEach(function(file) {
require(file)();
});
return function(req, res, next) {
req.db = mongoose;
next();
};
};
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var mongoose = require('mongoose');
module.exports = function() {
var locationSchema = mongoose.Schema({
_id: {type: Number, required: true},
name: {type: String, required: true},
adminLevel: {type: Number, required: true},
border: {type: Object, required: true},
subDivisions: {type: Object},
extras: {type: mongoose.Schema.Types.Mixed}
});
// Workaround Alert:
// The following virtual is only needed as a placeholder for the
// calculated score of a text search on this collection. If this virtual
// is ommited, mongoose hides the 'score' field on the final document
// returned on queries.
locationSchema.virtual('score');
locationSchema.index({ adminLevel: 1 });
locationSchema.index({ name: 'text', 'extras.city_code': 'text' },
{ default_language: 'portuguese' });
return mongoose.model('Location', locationSchema);
};
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var BCRYPT_SALT_WORK_FACTOR = 10;
var MAX_NUMBER_OF_TAGS = 256;
module.exports = function() {
var userSchema = mongoose.Schema({
email: {type: String, required: true, unique: true },
password: {type: String, required: true },
firstname: {type: String},
lastname: {type: String},
tags: [String],
created_at: {type: Date },
updated_at: {type: Date }
});
userSchema.pre('save', function(next) {
var _this = this;
var now = new Date();
// set/update the created_at and updated_at fields
_this.updated_at = now;
if (!_this.created_at) {
_this.created_at = now;
}
// hash the password (only if has been modified or is new)
if (!_this.isModified('password')) {
next();
} else {
// generate a salt
bcrypt.genSalt(BCRYPT_SALT_WORK_FACTOR, function(err, salt) {
if (err) {
return next(err);
}
// hash the password along with our new salt
bcrypt.hash(_this.password, salt, function(err, hash) {
if (err) {
return next(err);
}
// override the cleartext password with the hashed one
_this.password = hash;
next();
});
});
}
});
function validateEmail(value) {
if ((value.length < 4) || (value.length > 255)) {
return false;
}
if (!value.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)) {
return false;
}
return true;
}
function validatePassword(value) {
if ((value.length < 8) || (value.length > 256)) {
return false;
}
if (!value.match(/^[a-zA-Z0-9$-\/:-?{-~!\"^_`\[\]]*$/)) {
return false;
}
return true;
}
function validateTags(value) {
if (value.length > MAX_NUMBER_OF_TAGS) {
return false;
}
for (var i = 0; i < value.length; i++) {
if (!value[i].match(/^[A-Za-z]+[A-Za-z0-9.-_]+$/)) {
return false;
}
if (value[i].length > 28) {
return false;
}
}
return true;
}
function validateName(value) {
if ((value.length < 3) || (value.length > 28)) {
return false;
}
return true;
}
userSchema.path('email').validate(validateEmail);
userSchema.path('password').validate(validatePassword);
userSchema.path('tags').validate(validateTags);
userSchema.path('firstname').validate(validateName);
userSchema.path('lastname').validate(validateName);
return mongoose.model('User', userSchema);
};
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var osprey = require('osprey');
// import controllers
var users = require('./controllers/users');
var locations = require('./controllers/locations');
var router = module.exports = osprey.Router();
router.get('/users', users.list);
router.post('/users', users.create);
router.get('/users/{userId}', { userId: { type: 'string' } }, users.read);
router.put('/users/{userId}', { userId: { type: 'string' } }, users.update);
router.delete('/users/{userId}', { userId: { type: 'string' } }, users.delete);
router.get('/locations', locations.list);
router.get('/locations/_index', locations.index);
router.get('/locations/{locationId}',
{ locationId: { type: 'integer' } }, locations.read);
{
"email": "email@something.com",
"password": "somerandompassword",
"firstname": "Name",
"tags": ["SomeProject", "AnotherProject"]
}
[
{
"id": "11",
"name": "RONDÔNIA",
"adminLevel": 4,
"extras": {}
},
{
"id": "14",
"name": "RORAIMA",
"adminLevel": 4,
"extras": {}
},
{
"id": "13",
"name": "AMAZONAS",
"adminLevel": 4,
"extras": {}
},
{
"id": "16",
"name": "AMAPÁ",
"adminLevel": 4,
"extras": {}
}
]
[
{
"id": "5639ff8eeca3b4f8334e9917",
"email": "email@something.com",
"firstname": "Name",
"tags": [
"SomeProject",
"AnotherProject"
],
"created_at": "2015-11-04T12:52:30.781Z",
"updated_at": "2015-11-04T12:52:30.781Z"
},
{
"id": "558acc151806abf713891b6c",
"email": "another@user.me",
"tags": [],
"created_at": "2015-06-24T15:26:13.281Z",
"updated_at": "2015-06-24T15:26:13.281Z"
},
{
"id": "5638a4c39517775d37a506b1",
"email": "yet@another.biz",
"firstname": "John",
"lastname": "Doe",
"tags": [
"SomeProject"
],
"created_at": "2015-11-03T12:12:51.855Z",
"updated_at": "2015-11-03T12:12:51.855Z"
}
]
{
"id": "3528858",
"name": "MARAPOAMA",
"adminLevel": 8,
"extras": {
"city_code": "MARP"
}
}
{
"id": "5639ff8eeca3b4f8334e9917",
"email": "email@something.com",
"firstname": "Name",
"tags": [
"SomeProject",
"AnotherProject"
],
"created_at": "2015-11-04T12:52:30.781Z",
"updated_at": "2015-11-04T12:52:30.781Z"
}
{
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"type": "object",
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
{
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"type": "array",
"items": { "$ref": "file:api/specs/schemas/items/location.json" }
}
{
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"type": "array",
"items": { "$ref": "file:api/specs/schemas/items/user.json" }
}
{
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"adminLevel": {
"type": "integer"
},
"border": {
"type": "object"
},
"subDivisions": {
"type": "array",
"items": {
"type": "object"
}
},
"extras": {
"type": "object"
}
},
"required": ["id", "name", "adminLevel"]
}
{
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"email": {
"type": "string"
},
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
}
},
"required": ["id", "email"]
}
{
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"type": "object",
"properties": {
"id": {
"type": "string",
"required": true
},
"message": {
"type": "string",
"required": true
}
}
}
This diff is collapsed.
mongodb:
host: 'localhost'
port: 27017
database: 'test'
'use strict';
var gulp = require('gulp');
var gutil = require('gulp-util');
var raml = require('gulp-raml');
var rename = require('gulp-rename');
var jshint = require('gulp-jshint');
var size = require('gulp-size');
var jscs = require('gulp-jscs');
var stylish = require('gulp-jscs-stylish');
var mocha = require('gulp-mocha');
var istanbul = require('gulp-istanbul');
var nodemon = require('gulp-nodemon');
var path = require('path');
var raml2html = require('raml2html');
var through = require('through2');
var yaml = require('js-yaml');
var srcFiles = [
'api/**/*.js',
'server.js',
'gulpfile.js',
'lib/**/*.js',
'test/**/*.js'
];
function handleError(err) {
console.error(err.toString());
process.exit(1);
}
function generateDoc(options) {
var simplifyMark = function(mark) {
if (mark) {
mark.buffer = mark.buffer
.split('\n', mark.line + 1)[mark.line]
.trim();
}
};
if (!options) {
options = {};
}
switch (options.type) {
case 'json':
options.config = {
template: function(obj) {
return JSON.stringify(obj, null, 2);
}
};
break;
case 'yaml':
options.config = {
template: function(obj) {
return yaml.safeDump(obj, {
skipInvalid: true
});
}
};
break;
default:
options.type = 'html';
if (!options.config) {
options.config = raml2html.getDefaultConfig(
options.https,
options.template,
options.resourceTemplate,
options.itemTemplate
);
}
}
if (!options.extension) {
options.extension = '.' + options.type;
}
var stream = through.obj(function(file, enc, done) {
var fail = function(message) {
done(new gutil.PluginError('raml2html', message));
};
if (file.isBuffer()) {
var cwd = process.cwd();
process.chdir(path.resolve(path.dirname(file.path)));
raml2html
.render(file.contents, options.config)
.then(function(output) {
process.chdir(cwd);
stream.push(new gutil.File({
base: file.base,
cwd: file.cwd,
path: gutil.replaceExtension(
file.path, options.extension),
contents: new Buffer(output)
}));
done();
},
function(error) {
process.chdir(cwd);
simplifyMark(error.context_mark);
simplifyMark(error.problem_mark);
process.nextTick(function() {
fail(JSON.stringify(error, null, 2));
});
}
);
}
else if (file.isStream()) {
fail('Streams are not supported: ' + file.inspect());
}
else if (file.isNull()) {
fail('Input file is null: ' + file.inspect());
}
});
return stream;
}
gulp.task('raml', function() {
gulp.src('api/specs/*.raml')
.pipe(raml())
.on('error', handleError)
.pipe(raml.reporter('default'));
});
gulp.task('doc', function() {
return gulp.src('api/specs/*.raml')
.pipe(generateDoc())
.on('error', handleError)
.pipe(rename({ extname: '.html' }))
.pipe(gulp.dest('doc/build'));
});
gulp.task('pre-test', function() {
return gulp.src(['api/**/*.js'])
.pipe(istanbul())
.pipe(istanbul.hookRequire());
});
gulp.task('test', ['pre-test'], function() {
return gulp.src('test/api/**/*.spec.js', {read: false})
.pipe(mocha({
require: ['./test/common.js'],
reporter: 'spec',
ui: 'bdd',
recursive: true,
colors: true,
timeout: 60000,
slow: 300,
delay: true
}))
.pipe(istanbul.writeReports())
.once('error', function() {
process.exit(1);
})
.once('end', function() {
process.exit();
});
});
gulp.task('lint', function() {
return gulp.src(srcFiles)
.pipe(jshint())
.pipe(jscs())
.pipe(stylish.combineWithHintResults())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(size());
});
gulp.task('check', ['raml', 'lint', 'test']);
gulp.task('develop', function() {
return nodemon({
script: 'server.js',
ext: 'js',
tasks: ['lint']
});
});
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var fs = require('fs');
var yaml = require('js-yaml');
var _ = require('lodash');
module.exports = {
readFromFile: readFromFile
};
function readFromFile(file) {
if (!fs.existsSync(file)) {
throw new Error('Missing configuration file \'' + file + '\'.');
}
var conf = yaml.safeLoad(fs.readFileSync(file, 'utf8'));
return new Config(conf);
}
function Config(conf) {
this._config = _.defaultsDeep(conf, {
mongodb: {
host: 'localhost',
port: 27017,
database: ''
}
});
this.get = function(path) {
return _.get(this._config, path);
};
this.set = function(path, value) {
_.set(this._config, path, value);
};
}
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var statuses = require('statuses');
module.exports = errorHandler;
function toIdentifier(str) {
return str.split(' ').map(function(token) {
return token.slice(0, 1).toUpperCase() + token.slice(1);
}).join('').replace(/[^ _0-9a-z]/gi, '');
}
function errorHandler(err, req, res, next) {
if (res.headersSent) {
// If headers are already sent, use the default express error
// handler, or else the connection will be closed by express
// and the request will be considered failed.
return next(err);
}
err = formatError(err);
res.status(err.status);
res.json(err);
}
function formatError(err) {
var res = {
status: 500,
id: 'InternalServerError',
message: 'An internal server error has occurred.' +
' Sorry for the inconvenience.'
};
try {
if (typeof err !== 'object') {
return res;
}
if (typeof err.status !== 'undefined') {
res.status = err.status;
}
if (typeof err.id !== 'undefined') {
res.id = err.id;
}
else {
res.id = toIdentifier(statuses[res.status]);
}
if ((err.message) && (err.expose)) {
res.message = err.message;
}
}
catch (err) {
// do nothing
}
return res;
}
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var jsep = require('jsep');
module.exports = FilterParser;
function FilterParser(options) {
options = options || {};
this._parseIdentifier = options.identifierParser ||
this.DefaultIdentifierParser;
this._parseOperator = options.operatorParser ||
this.DefaultOperatorParser;
}
FilterParser.prototype.parse = function(filters) {
var parseTree = jsep(filters);
return this._searchParseTree(parseTree);
};
FilterParser.prototype._searchParseTree = function(elem) {
switch (elem.type) {
case 'BinaryExpression':
var operator = this._parseOperator(elem.operator);
var left = this._searchParseTree(elem.left);
var right = this._searchParseTree(elem.right);
var ret = {};
if ((operator === '$or') || (operator === '$and')) {
ret[operator] = [left, right];
}
else {
ret[left] = {};
ret[left][operator] = right;
}
return ret;
case 'UnaryExpression':
return { $not: this._searchParseTree(elem.argument) };
case 'Identifier':
return this._parseIdentifier(elem.name);
case 'Literal':
return elem.value;
}
};
FilterParser.prototype.DefaultOperatorParser = function(op) {
switch (op) {
case '==': return '$eq';
case '>': return '$gt';
case '>=': return '$gte';
case '<': return '$lt';
case '<=': return '$lte';
case '!=': return '$ne';
case '|': return '$or';
case '&': return '$and';
case '!': return '$not';
default: throw new Error('Unknown operator token: ' + op);
}
};
FilterParser.prototype.DefaultIdentifierParser = function(ident) {
return ident;
};
/*
* Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
* Departamento de Informatica - Universidade Federal do Parana
*
* This file is part of simmc.
*
* simmc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* simmc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with simmc. If not, see <http://www.gnu.org/licenses/>.
*/
var fs = require('fs');
module.exports = {
load: loadFixtures
};
function loadFixtures(model, filename, callback) {
fs.readFile(filename, 'utf8', function(err, data) {
if (err) {
callback(err);
return;
}
try {
var docs = JSON.parse(data);
}
catch (err) {
callback(err);
return;
}
model.remove({}, function(err) {
if (err) {
callback(err);
return;
}