SlideShare a Scribd company logo
1 of 149
MODULE

DEVELOPMENT
What is node.js?

“

Node.js is a platform built on
Chrome's JavaScript runtime for
easily building fast, scalable network
applications.

”
./
sourceControl
git	
  init
javascriptFiles
mkdir	
  ./lib
executableFiles
mkdir	
  ./bin
testFiles
mkdir	
  ./test
documentationFiles
mkdir	
  ./doc
mkdir	
  ./example
mkdir	
  ./man
informationalFiles
touch	
  ./README
touch	
  ./LICENSE
touch	
  ./AUTHOR
./bin
./doc
./example
./lib
./man
./test

singularNouns
packageManagement
Package Manager
github: isaacs/npm
install: comes with node
localInstallation
npm install <package>
globalInstallation
npm install <package> --global
-g or --global
dualInstallation
npm install <package> --link
dependencyReferences
npm install <package> --save[-dev]
--save or --save-dev
updateDependencies
npm install
packageInitialization
npm init
$	
  npm	
  init
name: (sample-node) Sample
version: (0.0.0) 0.1.0
description: This is a sample module
entry point: (index.js) _
author:	
  Jay	
  Harris
license:	
  (BSD)	
  BSD
About	
  to	
  write	
  to	
  /Projects/sample-­‐node/package.json:
{
	
  	
  "name":	
  "Sample",
	
  	
  "version":	
  "0.1.0",
	
  	
  "description":	
  "This	
  is	
  a	
  sample	
  module",
	
  	
  "main":	
  "index.js",
	
  	
  "scripts":	
  {
	
  	
  	
  	
  "test":	
  "echo	
  "Error:	
  no	
  test	
  specified"	
  &&	
  exit	
  1"
	
  	
  },
	
  	
  "author":	
  "Jay	
  Harris",
	
  	
  "license":	
  "BSD"
}
Is	
  this	
  ok?	
  (yes)	
  _
./package.json
1 {
"name": "Sample",
2
"version": "0.1.0",
3
"description": "This is a sample module",
4
"main": "index.js",
5
"scripts": {
6
"test": "echo "Error: no tests avail." && exit 1"
7
},
8
"author": "Jay Harris",
9
"license": "BSD"
10
11 }
12
13
14
15
16
npm init is additive not destructive
moduleCreation
module
module.exports
./lib/sample.js
1 module.exports.sayHello = function() {
return "Hello World!";
2
3 }
4
5
6
7
8
9
10
11
12
13
14
15
16
var	
  sample	
  =	
  require("./lib/sample.js");
//	
  Returns	
  'Hello	
  World!'
sample.sayHello();
./lib/person.js
1 function Person(first, last) {
if (!(this instanceof Person)) {
2
return new Person(first, last);
3
}
4
5
this.firstName = first;
6
this.lastName = last;
7
8
return this;
9
10 }
11
12 module.exports = Person;
13
14
15
16
var person = require("./lib/person.js");
// This will return undefined
person.firstName;
// This will return 'Jay'
var jayHarris = new Person('Jay','Harris');
jayHarris.firstName;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

function Person(first, last) {
// ...
}
module.exports = Person;
// This is a public method;
Person.prototype.sayHello = function() {
return _join.call(this, "Hello", this.firstName);
}
// This is a private method
var _join(first, second) {
return first + ' ' + second;
}
var	
  person	
  =	
  require("./lib/person.js");
//	
  This	
  will	
  throw	
  'Has	
  No	
  Method'	
  error
person.sayHello();
//	
  This	
  will	
  return	
  'Hello	
  Jay'
var	
  jayHarris	
  =	
  new	
  Person('Jay','Harris');
jayHarris.sayHello();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

function Person(first, last) {
// ...
}
module.exports = Person;
// This is a static method
module.exports.sayHello = function() {
return "Hello World!";
}
// This is a public instance method;
Person.prototype.sayHello = function() {
return _join.call(this, "Hello", this.firstName);
}
// This is a private method
var _join(first, second) {
return first + ' ' + second;
}
var	
  person	
  =	
  require("./lib/person.js");
//	
  This	
  will	
  return	
  'Hello	
  World!'
person.sayHello();
//	
  This	
  will	
  return	
  'Hello	
  Jay'
var	
  jayHarris	
  =	
  new	
  Person('Jay','Harris');
jayHarris.sayHello();
eventEmitter
var	
  EventEmitter	
  =	
  require('events').EventEmitter;
EventEmitter.call(this);
var	
  util	
  =	
  require('util');
//	
  ...
util.inherits(MyClass,	
  EventEmitter);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var EventEmitter = require('events').EventEmitter
, util = require('util');
function Person(first, last) {
// ...
EventEmitter.call(this);
// ...
}
util.inherits(Person, EventEmitter);
Person.prototype.goToBed = function() {
this.emit("sleep");
}
var	
  person	
  =	
  require("./person.js");
//	
  This	
  will	
  return	
  'Hello	
  Jay'
var	
  jayHarris	
  =	
  new	
  Person('Jay','Harris');
jayHarris.on("sleep",	
  function()	
  {
	
  	
  	
  	
  console.log("Goodnight,	
  Jay");
}
jayHarris.goToBed();
//	
  Output	
  'Goodnight,	
  Jay'
testingNode.js
“

TDD is to coding style as yoga is
to posture. Even when you're not
actively practicing, having done so
colors your whole life healthier.

”

j. kerr
assertingCorrectness
var	
  assert	
  =	
  require('assert');
assert(value)
	
  	
  	
  	
  	
  	
  .ok(value)
	
  	
  	
  	
  	
  	
  .equal(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .deepEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notDeepEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .strictEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notStrictEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .throws(block,	
  [error])
	
  	
  	
  	
  	
  	
  .doesNotThrow(block,	
  [error])
	
  	
  	
  	
  	
  	
  .ifError(value)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var assert = require('assert');
// Will pass
assert.ok(true);
// Will throw an exception
assert.ok(false);
1 var assert = require('assert');
2
3 // Will throw 'false == true' error
4 assert.ok(typeof 'hello' === 'number');
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$	
  node	
  test.js
assert.js:104
	
  	
  throw	
  new	
  assert.AssertionError({
	
  	
  	
  	
  	
  	
  	
  	
  ^
AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  at	
  Object.<anonymous>	
  (my-­‐test.js:7:8)
	
  	
  	
  	
  at	
  Module._compile	
  (module.js:449:26)
	
  	
  	
  	
  at	
  Object.Module._extensions..js	
  (module.js:467:10)
	
  	
  	
  	
  at	
  Module.load	
  (module.js:356:32)
	
  	
  	
  	
  at	
  Function.Module._load	
  (module.js:312:12)
	
  	
  	
  	
  at	
  Module.runMain	
  (module.js:487:10)
	
  	
  	
  	
  at	
  process.startup.processNextTick.process._tick...
$	
  _
Chai Assertion Library
github: chaijs/chai
install: npm install chai
isTrue,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isFalse,
isNull,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotNull,
isUndefined,	
  	
  	
  	
  	
  	
  isDefined,
isFunction,	
  	
  	
  	
  	
  	
  	
  isNotFunction,
isArray,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotArray,
isBoolean,	
  	
  	
  	
  	
  	
  	
  	
  isNotBoolean,
isNumber,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotNumber,
isString,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotString,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  include,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  lengthOf,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  operator,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  closeTo	
  
isObject,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotObject,
typeOf,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  notTypeOf,
instanceOf,	
  	
  	
  	
  	
  	
  	
  notInstanceOf,
match,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  notMatch,
property,	
  	
  	
  	
  	
  	
  	
  	
  	
  notProperty,
deepProperty,	
  	
  	
  	
  	
  notDeepProperty,
propertyVal,	
  	
  	
  	
  	
  	
  propertyNotVal,
deepPropertyVal,	
  	
  deepPropertyNotVal,

additional
assertions
var	
  assert	
  =	
  require('chai').assert;
1 var assert = require('chai').assert;
2
3 // Will throw 'expected 'hello' to be a number'
4 assert.isNumber('hello');
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$	
  node	
  test.js
expected	
  'hello'	
  to	
  be	
  a	
  number
$	
  _
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var chai
= require('chai')
, assert = chai.assert;
chai.Assertion.includeStack = true;
// Will throw and display stack
assert.isNumber('hello');
expectAssertions
assertSyntax
assert.isObject(person);
assert.property(person,	
  "age");
assert.isNumber(person.age);
assert.equals(person.age,	
  34);

expectSyntax
expect(person).to.be.an('object');
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.a('number')
	
  	
  	
  	
  .that.equals(34);
var	
  expect	
  =	
  require('chai').expect;
assertionChains
for readability
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
.to
.be
.been
.is
.that
.and
.have
.with

syntaxSugar
for readability
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
.property

subjectChange
from original object
expect(person)
	
  	
  .that.is.an('object')
	
  	
  .with.property('address')
	
  	
  	
  	
  .that.is.an('object')
	
  	
  	
  	
  .with.property('city')
	
  	
  	
  	
  	
  	
  .that.is.a('string')
	
  	
  	
  	
  	
  	
  .and.equals('Detroit')
testingFramework
mocha

simple, flexible, fun
mocha

github: visionmedia/mocha
install: npm install -g mocha
$	
  npm	
  install	
  -­‐g	
  mocha
$	
  mkdir	
  test
$	
  mocha
	
  	
  
	
  	
  ✔	
  0	
  tests	
  complete	
  (1ms)
$	
  
var	
  mocha	
  =	
  require('mocha');
bddSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
./test/my-test.js
1 var assert = require('assert');
2
3 describe('Assertions', function() {
it('should pass on truthiness', function() {
4
assert.ok(true);
5
});
6
it('should fail on falsiness', function() {
7
assert.ok(false);
8
});
9
10 });
11
12
13
14
15
16
$	
  mocha	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
groupedTests
groupSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  });
});
1 var expect = require('chai').expect;
2
3 describe('Assertions', function() {
describe('on equality', function() {
4
it('should pass on truthiness', function() {
5
expect(true).is.true;
6
});
7
it('should pass on falsiness', function() {
8
expect(false).is.false;
9
});
10
});
11
describe('on type', function() {
12
it('should pass on number', function() {
13
expect(5).is.a('number');
14
});
15
});
16
17 });
18
$	
  mocha	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  of	
  equality
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness	
  
	
  	
  	
  	
  on	
  type
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  number	
  

	
  	
  ✔	
  3	
  tests	
  complete	
  (6ms)
$	
  _
pendingTests
pendingSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff	
  someday');
	
  	
  	
  	
  });
});
1 var assert = require('chai').assert;
2
3 describe('Assertions', function() {
describe('of truthiness', function() {
4
it('should pass on truthiness', function() {
5
expect(true).is.true;
6
});
7
it('should pass on falsiness', function() {
8
expect(false).is.false;
9
});
10
});
11
describe('of type', function() {
12
it('should pass on number', function() {
13
expect(5).is.a('number');
14
});
15
it('should pass on object');
16
});
17
18 });
$	
  mocha	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  number	
  
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  object

	
  	
  ✔	
  4	
  tests	
  complete	
  (6ms)
	
  	
  •	
  1	
  test	
  pending
$	
  _
skippedTests
skipSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  it.skip('should	
  be	
  skipped',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
describe.skip('This	
  entire	
  suite	
  will	
  be	
  skipped',	
  function()	
  {
	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
1 describe('Assertions', function() {
describe('of truthiness', function() {
2
it('should pass on truthiness', function() {
3
assert.isTrue(true);
4
});
5
it('should pass on falsiness', function() {
6
assert.isFalse(false);
7
});
8
});
9
describe('of type', function() {
10
it.skip('should pass on number', function() {
11
assert.isNumber(5);
12
});
13
it('should pass on object');
14
});
15
16 });
17
18
$	
  make	
  test

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness	
  
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  number	
  
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  object

	
  	
  ✔	
  4	
  tests	
  complete	
  (6ms)
	
  	
  •	
  2	
  test	
  pending
$	
  _
setupTeardown
before();
beforeEach();
after();
afterEach();
setupTeardown
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  before(function(){
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  };
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  that	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  	
  	
  	
  	
  afterEach(function(){
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  	
  	
  	
  	
  };
	
  	
  	
  	
  });
});
asynchronousTests
asynchronousSyntax
it('should	
  not	
  error',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  done);
});
asynchronousSyntax
it('should	
  not	
  error',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  done);
});
it('should	
  return	
  2	
  items',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  function(err,	
  res)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  if	
  (err)	
  return	
  done(err);
	
  	
  	
  	
  	
  	
  	
  	
  res.should.have.length(2);
	
  	
  	
  	
  	
  	
  	
  	
  done();
	
  	
  	
  	
  });
});
All Mocha functions accept this callback
1 describe('When searching for Apples', function(done) {
before(function(done){
2
items.save(['fiji apples',
3
'empire apples'], done);
4
});
5
it('should not error', function(done) {
6
search.find("Apples", done);
7
});
8
it('should return 2 items', function(done) {
9
search.find("Apples", function(err, res) {
10
if (err) return done(err);
11
res.should.have.length(2);
12
done();
13
});
14
});
15
16 });
17
18
simplifyExecution
$	
  mocha	
  <args>

should be simplified to
$	
  make	
  test

and

$	
  npm	
  test
./makefile
1 # Makefile for sample module
2
3 test:
mocha --reporter spec --ui bdd
4
5
6
7
8 .PHONY: test
9
10
11
12
13
14
15
16
./makefile
1 # Makefile for sample module
2
3 test:
mocha 
4
--reporter spec 
5
--ui bdd
6
7
8 .PHONY: test
9
10
11
12
13
14
15
16
$	
  make	
  test

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
./package.json
1 {
"name": "sample",
2
"version": "0.1.0",
3
"scripts": {
4
"test": "make test"
5
}
6
7 }
8
9
10
11
12
13
14
15
16
$	
  npm	
  test

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
eliminate global dependency
$	
  npm	
  install	
  mocha	
  -­‐-­‐link
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui bdd
4
5
6 .PHONY: test
7
8
9
10
11
12
13
14
15
16
17
18
update dev dependencies
$	
  npm	
  install	
  mocha	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  chai	
  	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  mocha	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  chai	
  	
  -­‐-­‐save-­‐dev
$	
  git	
  diff	
  package.json	
  
diff	
  -­‐-­‐git	
  a/package.json	
  b/package.json
index	
  439cf44..3609bb9	
  100644
-­‐-­‐-­‐	
  a/package.json
+++	
  b/package.json
@@	
  -­‐1,5	
  +1,7	
  @@
	
  {
	
  	
  	
  "name":	
  "sample",
-­‐	
  	
  "version":	
  "0.1.0"
+	
  	
  "version":	
  "0.1.0",
+	
  	
  "devDependencies":	
  {
+	
  	
  	
  	
  "mocha":	
  "~1.9.0",
+	
  	
  	
  	
  "chai":	
  "~1.6.0"
+	
  	
  }
	
  }
notificationSystems
continuousTesting
mocha --watch
-w or --watch
$	
  mocha	
  -­‐-­‐watch

	
  ✔	
  5	
  tests	
  complete	
  (22ms)
	
  ^	
  watching
Growl
mac: apple app store
win: growlForWindows.com
also: growlNotify
growlNotifications
mocha --growl
-G or --growl
⌘S
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui bdd
4
5
6 watch:
@./node_modules/.bin/mocha 
7
--reporter min 
8
--ui bdd 
9
--growl 
10
--watch
11
12
13 .PHONY: test watch
14
15
16
17
18
mockingObjects
JavaScript ships with a mocking framework
...it’s called JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var me = {firstName: 'Jay'
, lastName: 'Harris'
, getFullName: function() {
return this.firstName +
' ' +
this.lastName; }};
// Returns 'Jay Harris'
me.getFullName();
me.getFullName = function() { return 'John Doe'; };
// Returns 'John Doe'
me.getFullName();
nock

HTTP Mocking Library
nock

github: flatiron/nock
install: npm install nock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var http = require('http');
var reqOptions = {
host: 'api.twitter.com',
path: '/1/statuses/user_timeline.json?' +
'screen_name=jayharris'
};
// ...
http.request(reqOptions, resCallback).end();
// Returns live Twitter data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var nock = require('nock');
var twitter = nock('http://api.twitter.com')
.get('/1/statuses/user_timeline.json?'+
'screen_name=jayharris')
.reply(200, "This worked");
// Returns "This worked"
http.request(reqOptions, resCallback).end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Returns live Twitter data
http.request(reqOptions, resCallback).end();
var nock = require('nock');
var twitter = nock('http://api.twitter.com')
.get('/1/statuses/user_timeline.json?'+
'screen_name=jayharris')
.reply(200, "This worked");
// Returns "This worked"
http.request(reqOptions, resCallback).end();
// Returns live Twitter data
http.request(reqOptions, resCallback).end();
nock

nock.recorder.rec(	
  );
nock.recorder.play(	
  );
Sinon.js

Spies, Stubs, & Mocks
Sinon.js

github: cjohansen/Sinon.JS
install: npm install sinon
versionTesting
nvm

Node Version Manager
nvm

github: creationix/nvm
github: hakobera/nvmw
$	
  nvm	
  list
	
  	
  	
  	
  v0.4.0	
  	
  	
  	
  v0.6.18	
  	
  	
  	
  v0.8.21
	
  	
  	
  	
  v0.4.7	
  	
  	
  	
  	
  v0.8.1	
  	
  	
  	
  v0.10.0
	
  	
  	
  	
  v0.6.0	
  	
  	
  	
  	
  v0.8.8
current:	
  	
  
v0.8.1
10	
  -­‐>	
  0.10.0	
  (-­‐>	
  v0.10.0)
4	
  -­‐>	
  0.4.7	
  (-­‐>	
  v0.4.7)
6	
  -­‐>	
  0.6.18	
  (-­‐>	
  v0.6.18)
8	
  -­‐>	
  0.8.21	
  (-­‐>	
  v0.8.21)
default	
  -­‐>	
  0.10.0	
  (-­‐>	
  v0.10.0)
newest	
  -­‐>	
  0.10.0	
  (-­‐>	
  v0.10.0)
$	
  _
$	
  node	
  -­‐-­‐version
v0.10.0
$	
  nvm	
  install	
  v0.10.6
Now	
  using	
  node	
  v0.10.6
/Users/jayharris/.nvm/v0.10.6/bin/npm
$	
  node	
  -­‐-­‐version
v0.10.6
$	
  _
packageDistribution
Package Manager
filePackaging
./.npmignore
userSetup
npm adduser
$	
  npm	
  adduser
Username:	
  (jayharris)	
  jayharris
Password:
Email:	
  (jay@aranasoft.com)	
  _
$	
  npm	
  whoami
jayharris
$	
  _
packagePublish
npm publish
{	
  name:	
  'morale',
	
  	
  description:	
  'Async	
  API	
  wrapper	
  for	
  Morale',
	
  	
  'dist-­‐tags':	
  {	
  latest:	
  '0.2.0'	
  },
	
  	
  versions:	
  
	
  	
  	
  [	
  '0.1.0',
	
  	
  	
  	
  	
  '0.1.2',
	
  	
  	
  	
  	
  '0.2.0'	
  ],
	
  	
  maintainers:	
  'jayharris	
  <jay@aranasoft.com>',
	
  	
  time:	
  
	
  	
  	
  {	
  '0.1.0':	
  '2012-­‐01-­‐23T03:24:59.824Z',
	
  	
  	
  	
  	
  '0.1.2':	
  '2012-­‐01-­‐25T23:20:52.927Z',
	
  	
  	
  	
  	
  '0.2.0':	
  '2012-­‐08-­‐13T16:23:28.488Z'	
  },
	
  	
  author:	
  'Arana	
  Software	
  <info@aranasoft.com>',
	
  	
  repository:	
  
	
  	
  	
  {	
  type:	
  'git',
	
  	
  	
  	
  	
  url:	
  'git://github.com/aranasoft/morale-­‐node.git'	
  },
	
  	
  users:	
  {	
  fgribreau:	
  true	
  },
	
  	
  version:	
  '0.2.0',
$	
  npm	
  publish
npm	
  http	
  PUT	
  https://registry.npmjs.org/morale
npm	
  http	
  409	
  https://registry.npmjs.org/morale
npm	
  http	
  GET	
  https://registry.npmjs.org/morale
npm	
  http	
  200	
  https://registry.npmjs.org/morale
npm	
  http	
  PUT	
  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest
npm	
  http	
  201	
  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest
npm	
  http	
  GET	
  https://registry.npmjs.org/morale
npm	
  http	
  200	
  https://registry.npmjs.org/morale
npm	
  http	
  PUT	
  https://registry.npmjs.org/morale/-­‐/
morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b
npm	
  http	
  201	
  https://registry.npmjs.org/morale/-­‐/
morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b
+	
  morale@0.2.1
$	
  _
{	
  name:	
  'morale',
	
  	
  description:	
  'Async	
  API	
  wrapper	
  for	
  Morale',
	
  	
  'dist-­‐tags':	
  {	
  latest:	
  '0.2.1'	
  },
	
  	
  versions:	
  
	
  	
  	
  [	
  '0.1.0',
	
  	
  	
  	
  	
  '0.1.2',
	
  	
  	
  	
  	
  '0.2.0',
	
  	
  	
  	
  	
  '0.2.1'	
  ],
	
  	
  maintainers:	
  'jayharris	
  <jay@aranasoft.com>',
	
  	
  time:	
  
	
  	
  	
  {	
  '0.1.0':	
  '2012-­‐01-­‐23T03:24:59.824Z',
	
  	
  	
  	
  	
  '0.1.2':	
  '2012-­‐01-­‐25T23:20:52.927Z',
	
  	
  	
  	
  	
  '0.2.0':	
  '2012-­‐08-­‐13T16:23:28.488Z',
	
  	
  	
  	
  	
  '0.2.1':	
  '2012-­‐08-­‐30T19:10:20.133Z'	
  },
	
  	
  author:	
  'Arana	
  Software	
  <info@aranasoft.com>',
	
  	
  repository:	
  
	
  	
  	
  {	
  type:	
  'git',
	
  	
  	
  	
  	
  url:	
  'git://github.com/aranasoft/morale-­‐node.git'	
  },
privatePackages
{ "private": "true" }
./package.json
1 {
"name": "Sample",
2
"version": "0.1.0",
3
"description": "This is a sample module",
4
"main": "index.js",
5
"scripts": {
6
"test": "echo "Error: no tests avail." && exit 1"
7
},
8
"author": "Jay Harris",
9
"license": "BSD",
10
"private": "true"
11
12 }
13
14
15
16
$	
  npm	
  publish
npm	
  ERR!	
  Error:	
  This	
  package	
  has	
  been	
  marked	
  as	
  private
npm	
  ERR!	
  Remove	
  the	
  'private'	
  field	
  from	
  the	
  package.json	
  to	
  
publish	
  it.
$	
  _
versionLockdown
npm shrinkwrap
$	
  npm	
  shrinkwrap
wrote	
  npm-­‐shrinkwrap.json
$	
  _
1 {
"name": "morale",
2
"version": "0.2.1",
3
"dependencies": {
4
"underscore": {
5
"version": "1.3.3"
6
},
7
"mocha": {
8
"version": "1.3.0",
9
"dependencies": {
10
"commander": {
11
"version": "0.6.1"
12
},
13
"growl": {
14
"version": "1.5.1"
15
},
16
"jade": {
17
"version": "0.26.3",
18
$	
  rm	
  npm-­‐shrinkwrap.json
$	
  npm	
  update
$	
  npm	
  test
$	
  npm	
  shrinkwrap
tellEveryone
Go make some Awesome
jay harris

P R E S I D E N T

jay@aranasoft.com
#nodemoduledev
@jayharris

More Related Content

What's hot

The report of JavaOne2011 about groovy
The report of JavaOne2011 about groovyThe report of JavaOne2011 about groovy
The report of JavaOne2011 about groovy
Yasuharu Nakano
 
C++ Programming - 12th Study
C++ Programming - 12th StudyC++ Programming - 12th Study
C++ Programming - 12th Study
Chris Ohk
 
Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.js
Yandex
 
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, MoscowJavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
Robert Nyman
 

What's hot (20)

The report of JavaOne2011 about groovy
The report of JavaOne2011 about groovyThe report of JavaOne2011 about groovy
The report of JavaOne2011 about groovy
 
Deep dive into Oracle ADF
Deep dive into Oracle ADFDeep dive into Oracle ADF
Deep dive into Oracle ADF
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring Effects
 
Testing with Node.js
Testing with Node.jsTesting with Node.js
Testing with Node.js
 
¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?
 
Modern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlModern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in Perl
 
C++ Programming - 9th Study
C++ Programming - 9th StudyC++ Programming - 9th Study
C++ Programming - 9th Study
 
C++ Programming - 12th Study
C++ Programming - 12th StudyC++ Programming - 12th Study
C++ Programming - 12th Study
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.js
 
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, MoscowJavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Con5623 pdf 5623_001
Con5623 pdf 5623_001Con5623 pdf 5623_001
Con5623 pdf 5623_001
 
Node.js 0.8 features
Node.js 0.8 featuresNode.js 0.8 features
Node.js 0.8 features
 
Haskell is Not For Production and Other Tales
Haskell is Not For Production and Other TalesHaskell is Not For Production and Other Tales
Haskell is Not For Production and Other Tales
 

Viewers also liked

Recomanacions estiu2016 biblioteca
Recomanacions estiu2016 bibliotecaRecomanacions estiu2016 biblioteca
Recomanacions estiu2016 biblioteca
lluís nater
 

Viewers also liked (14)

Nota informativa sobre contaminación luminosa
Nota informativa sobre contaminación luminosaNota informativa sobre contaminación luminosa
Nota informativa sobre contaminación luminosa
 
наталинци 3
наталинци 3наталинци 3
наталинци 3
 
pUBLICIDAD EN REDES SOCIALES
pUBLICIDAD EN REDES SOCIALESpUBLICIDAD EN REDES SOCIALES
pUBLICIDAD EN REDES SOCIALES
 
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
 
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in DesignUCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
 
Objetivos bloom
Objetivos bloomObjetivos bloom
Objetivos bloom
 
Riesgo de la automedicación y tratamientos alternativos.
Riesgo de la automedicación y tratamientos alternativos.Riesgo de la automedicación y tratamientos alternativos.
Riesgo de la automedicación y tratamientos alternativos.
 
Recomanacions estiu2016 biblioteca
Recomanacions estiu2016 bibliotecaRecomanacions estiu2016 biblioteca
Recomanacions estiu2016 biblioteca
 
Pipe Laying Barge
Pipe Laying BargePipe Laying Barge
Pipe Laying Barge
 
DEV208 - ASP.NET MVC 5 新功能探索
DEV208 - ASP.NET MVC 5 新功能探索DEV208 - ASP.NET MVC 5 新功能探索
DEV208 - ASP.NET MVC 5 新功能探索
 
Thematic Analysis
Thematic AnalysisThematic Analysis
Thematic Analysis
 
Graphic aids (2)
Graphic aids (2)Graphic aids (2)
Graphic aids (2)
 
Sepsis y trombocitopenia immune. Caso Clínico Terapéutico
Sepsis y trombocitopenia immune. Caso Clínico TerapéuticoSepsis y trombocitopenia immune. Caso Clínico Terapéutico
Sepsis y trombocitopenia immune. Caso Clínico Terapéutico
 
Y6 华文 单元 4 习写作文
Y6 华文 单元 4 习写作文 Y6 华文 单元 4 习写作文
Y6 华文 单元 4 习写作文
 

Similar to node.js Module Development

Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
archwisp
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
smueller_sandsmedia
 

Similar to node.js Module Development (20)

Fatc
FatcFatc
Fatc
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQUA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for real
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
 
NodeJs
NodeJsNodeJs
NodeJs
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards
 
Test innode
Test innodeTest innode
Test innode
 

More from Jay Harris

More from Jay Harris (6)

Bullets Kill People: Building Effective Presentations
Bullets Kill People: Building Effective PresentationsBullets Kill People: Building Effective Presentations
Bullets Kill People: Building Effective Presentations
 
Dethroning Grunt: Simple and Effective Builds with gulp.js
Dethroning Grunt: Simple and Effective Builds with gulp.jsDethroning Grunt: Simple and Effective Builds with gulp.js
Dethroning Grunt: Simple and Effective Builds with gulp.js
 
OrchardCMS module development
OrchardCMS module developmentOrchardCMS module development
OrchardCMS module development
 
The Geek's Guide to SEO
The Geek's Guide to SEOThe Geek's Guide to SEO
The Geek's Guide to SEO
 
Going for Speed: Testing for Performance
Going for Speed: Testing for PerformanceGoing for Speed: Testing for Performance
Going for Speed: Testing for Performance
 
Dev Basics: The ASP.NET Page Life Cycle
Dev Basics: The ASP.NET Page Life CycleDev Basics: The ASP.NET Page Life Cycle
Dev Basics: The ASP.NET Page Life Cycle
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 

node.js Module Development

  • 2. What is node.js? “ Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. ”
  • 3.
  • 4. ./
  • 16. globalInstallation npm install <package> --global -g or --global
  • 18. dependencyReferences npm install <package> --save[-dev] --save or --save-dev
  • 21. $  npm  init name: (sample-node) Sample version: (0.0.0) 0.1.0 description: This is a sample module entry point: (index.js) _
  • 22. author:  Jay  Harris license:  (BSD)  BSD About  to  write  to  /Projects/sample-­‐node/package.json: {    "name":  "Sample",    "version":  "0.1.0",    "description":  "This  is  a  sample  module",    "main":  "index.js",    "scripts":  {        "test":  "echo  "Error:  no  test  specified"  &&  exit  1"    },    "author":  "Jay  Harris",    "license":  "BSD" } Is  this  ok?  (yes)  _
  • 23. ./package.json 1 { "name": "Sample", 2 "version": "0.1.0", 3 "description": "This is a sample module", 4 "main": "index.js", 5 "scripts": { 6 "test": "echo "Error: no tests avail." && exit 1" 7 }, 8 "author": "Jay Harris", 9 "license": "BSD" 10 11 } 12 13 14 15 16
  • 24. npm init is additive not destructive
  • 28. ./lib/sample.js 1 module.exports.sayHello = function() { return "Hello World!"; 2 3 } 4 5 6 7 8 9 10 11 12 13 14 15 16
  • 29. var  sample  =  require("./lib/sample.js"); //  Returns  'Hello  World!' sample.sayHello();
  • 30. ./lib/person.js 1 function Person(first, last) { if (!(this instanceof Person)) { 2 return new Person(first, last); 3 } 4 5 this.firstName = first; 6 this.lastName = last; 7 8 return this; 9 10 } 11 12 module.exports = Person; 13 14 15 16
  • 31. var person = require("./lib/person.js"); // This will return undefined person.firstName; // This will return 'Jay' var jayHarris = new Person('Jay','Harris'); jayHarris.firstName;
  • 32. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function Person(first, last) { // ... } module.exports = Person; // This is a public method; Person.prototype.sayHello = function() { return _join.call(this, "Hello", this.firstName); } // This is a private method var _join(first, second) { return first + ' ' + second; }
  • 33. var  person  =  require("./lib/person.js"); //  This  will  throw  'Has  No  Method'  error person.sayHello(); //  This  will  return  'Hello  Jay' var  jayHarris  =  new  Person('Jay','Harris'); jayHarris.sayHello();
  • 34. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function Person(first, last) { // ... } module.exports = Person; // This is a static method module.exports.sayHello = function() { return "Hello World!"; } // This is a public instance method; Person.prototype.sayHello = function() { return _join.call(this, "Hello", this.firstName); } // This is a private method var _join(first, second) { return first + ' ' + second; }
  • 35. var  person  =  require("./lib/person.js"); //  This  will  return  'Hello  World!' person.sayHello(); //  This  will  return  'Hello  Jay' var  jayHarris  =  new  Person('Jay','Harris'); jayHarris.sayHello();
  • 37. var  EventEmitter  =  require('events').EventEmitter;
  • 39. var  util  =  require('util'); //  ... util.inherits(MyClass,  EventEmitter);
  • 40. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var EventEmitter = require('events').EventEmitter , util = require('util'); function Person(first, last) { // ... EventEmitter.call(this); // ... } util.inherits(Person, EventEmitter); Person.prototype.goToBed = function() { this.emit("sleep"); }
  • 41. var  person  =  require("./person.js"); //  This  will  return  'Hello  Jay' var  jayHarris  =  new  Person('Jay','Harris'); jayHarris.on("sleep",  function()  {        console.log("Goodnight,  Jay"); } jayHarris.goToBed(); //  Output  'Goodnight,  Jay'
  • 43. “ TDD is to coding style as yoga is to posture. Even when you're not actively practicing, having done so colors your whole life healthier. ” j. kerr
  • 45. var  assert  =  require('assert');
  • 46. assert(value)            .ok(value)            .equal(actual,  expected)            .notEqual(actual,  expected)            .deepEqual(actual,  expected)            .notDeepEqual(actual,  expected)            .strictEqual(actual,  expected)            .notStrictEqual(actual,  expected)            .throws(block,  [error])            .doesNotThrow(block,  [error])            .ifError(value)
  • 47. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var assert = require('assert'); // Will pass assert.ok(true); // Will throw an exception assert.ok(false);
  • 48. 1 var assert = require('assert'); 2 3 // Will throw 'false == true' error 4 assert.ok(typeof 'hello' === 'number'); 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  • 49. $  node  test.js assert.js:104    throw  new  assert.AssertionError({                ^ AssertionError:  false  ==  true        at  Object.<anonymous>  (my-­‐test.js:7:8)        at  Module._compile  (module.js:449:26)        at  Object.Module._extensions..js  (module.js:467:10)        at  Module.load  (module.js:356:32)        at  Function.Module._load  (module.js:312:12)        at  Module.runMain  (module.js:487:10)        at  process.startup.processNextTick.process._tick... $  _
  • 52. isTrue,                      isFalse, isNull,                      isNotNull, isUndefined,            isDefined, isFunction,              isNotFunction, isArray,                    isNotArray, isBoolean,                isNotBoolean, isNumber,                  isNotNumber, isString,                  isNotString,                                    include,                                    lengthOf,                                    operator,                                    closeTo   isObject,                  isNotObject, typeOf,                      notTypeOf, instanceOf,              notInstanceOf, match,                        notMatch, property,                  notProperty, deepProperty,          notDeepProperty, propertyVal,            propertyNotVal, deepPropertyVal,    deepPropertyNotVal, additional assertions
  • 53. var  assert  =  require('chai').assert;
  • 54. 1 var assert = require('chai').assert; 2 3 // Will throw 'expected 'hello' to be a number' 4 assert.isNumber('hello'); 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  • 55. $  node  test.js expected  'hello'  to  be  a  number $  _
  • 56. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var chai = require('chai') , assert = chai.assert; chai.Assertion.includeStack = true; // Will throw and display stack assert.isNumber('hello');
  • 59. var  expect  =  require('chai').expect;
  • 61. expect(person).to.exist        .and.be.an('object')        .with.property('age')        .that.is.to.exist        .and.is.a('number')        .and.equals(34);
  • 63. expect(person).to.exist        .and.be.an('object')        .with.property('age')        .that.is.to.exist        .and.is.a('number')        .and.equals(34);
  • 64. expect(person).to.exist        .and.be.an('object')        .with.property('age')        .that.is.to.exist        .and.is.a('number')        .and.equals(34);
  • 66. expect(person)    .that.is.an('object')    .with.property('address')        .that.is.an('object')        .with.property('city')            .that.is.a('string')            .and.equals('Detroit')
  • 70. $  npm  install  -­‐g  mocha $  mkdir  test $  mocha        ✔  0  tests  complete  (1ms) $  
  • 71. var  mocha  =  require('mocha');
  • 72. bddSyntax describe('Testing  out  this  thing',  function()  {        it('should  do  stuff',  function()  {                //  Assertion  tests        }); });
  • 73. ./test/my-test.js 1 var assert = require('assert'); 2 3 describe('Assertions', function() { it('should pass on truthiness', function() { 4 assert.ok(true); 5 }); 6 it('should fail on falsiness', function() { 7 assert.ok(false); 8 }); 9 10 }); 11 12 13 14 15 16
  • 74. $  mocha  -­‐-­‐reporter  spec    Assertions        ✓  should  pass  on  truthiness          1)  should  fail  on  falsiness    ✖  1  of  2  tests  failed:    1)  Assertions  should  fail  on  falsiness:              AssertionError:  false  ==  true            at  (stack  trace  omitted  for  brevity) $  _
  • 76. groupSyntax describe('Testing  out  this  thing',  function()  {        describe('with  a  subset  of  this  other  thing',  function()  {                it('should  do  stuff',  function()  {                        //  Assertion  tests                });        }); });
  • 77. 1 var expect = require('chai').expect; 2 3 describe('Assertions', function() { describe('on equality', function() { 4 it('should pass on truthiness', function() { 5 expect(true).is.true; 6 }); 7 it('should pass on falsiness', function() { 8 expect(false).is.false; 9 }); 10 }); 11 describe('on type', function() { 12 it('should pass on number', function() { 13 expect(5).is.a('number'); 14 }); 15 }); 16 17 }); 18
  • 78. $  mocha  -­‐-­‐reporter  spec    Assertions        of  equality            ✓  should  pass  on  truthiness              ✓  should  pass  on  falsiness          on  type            ✓  should  pass  on  number      ✔  3  tests  complete  (6ms) $  _
  • 80. pendingSyntax describe('Testing  out  this  thing',  function()  {        describe('with  a  subset  of  this  other  thing',  function()  {                it('should  do  stuff  someday');        }); });
  • 81. 1 var assert = require('chai').assert; 2 3 describe('Assertions', function() { describe('of truthiness', function() { 4 it('should pass on truthiness', function() { 5 expect(true).is.true; 6 }); 7 it('should pass on falsiness', function() { 8 expect(false).is.false; 9 }); 10 }); 11 describe('of type', function() { 12 it('should pass on number', function() { 13 expect(5).is.a('number'); 14 }); 15 it('should pass on object'); 16 }); 17 18 });
  • 82. $  mocha  -­‐-­‐reporter  spec    Assertions        of  truthiness            ✓  should  pass  on  truthiness            ✓  should  pass  on  falsiness        of  type            ✓  should  pass  on  number              -­‐  should  pass  on  object    ✔  4  tests  complete  (6ms)    •  1  test  pending $  _
  • 84. skipSyntax describe('Testing  out  this  thing',  function()  {        it.skip('should  be  skipped',  function()  {                //  Assertion  tests        }); }); describe.skip('This  entire  suite  will  be  skipped',  function()  {        it('should  do  stuff',  function()  {                //  Assertion  tests        }); });
  • 85. 1 describe('Assertions', function() { describe('of truthiness', function() { 2 it('should pass on truthiness', function() { 3 assert.isTrue(true); 4 }); 5 it('should pass on falsiness', function() { 6 assert.isFalse(false); 7 }); 8 }); 9 describe('of type', function() { 10 it.skip('should pass on number', function() { 11 assert.isNumber(5); 12 }); 13 it('should pass on object'); 14 }); 15 16 }); 17 18
  • 86. $  make  test    Assertions        of  truthiness            ✓  should  pass  on  truthiness              ✓  should  pass  on  falsiness          of  type            -­‐  should  pass  on  number              -­‐  should  pass  on  object    ✔  4  tests  complete  (6ms)    •  2  test  pending $  _
  • 89. setupTeardown describe('Testing  out  this  thing',  function()  {        before(function(){                //  ...        };        describe('with  a  subset  of  that  thing',  function()  {                it('should  do  stuff',  function()  {                        //  Assertion  tests                });                afterEach(function(){                        //  ...                };        }); });
  • 91. asynchronousSyntax it('should  not  error',  function(done)  {        search.find("Apples",  done); });
  • 92. asynchronousSyntax it('should  not  error',  function(done)  {        search.find("Apples",  done); }); it('should  return  2  items',  function(done)  {        search.find("Apples",  function(err,  res)  {                if  (err)  return  done(err);                res.should.have.length(2);                done();        }); });
  • 93. All Mocha functions accept this callback
  • 94. 1 describe('When searching for Apples', function(done) { before(function(done){ 2 items.save(['fiji apples', 3 'empire apples'], done); 4 }); 5 it('should not error', function(done) { 6 search.find("Apples", done); 7 }); 8 it('should return 2 items', function(done) { 9 search.find("Apples", function(err, res) { 10 if (err) return done(err); 11 res.should.have.length(2); 12 done(); 13 }); 14 }); 15 16 }); 17 18
  • 96. $  mocha  <args> should be simplified to $  make  test and $  npm  test
  • 97. ./makefile 1 # Makefile for sample module 2 3 test: mocha --reporter spec --ui bdd 4 5 6 7 8 .PHONY: test 9 10 11 12 13 14 15 16
  • 98. ./makefile 1 # Makefile for sample module 2 3 test: mocha 4 --reporter spec 5 --ui bdd 6 7 8 .PHONY: test 9 10 11 12 13 14 15 16
  • 99. $  make  test    Assertions        ✓  should  pass  on  truthiness          1)  should  fail  on  falsiness    ✖  1  of  2  tests  failed:    1)  Assertions  should  fail  on  falsiness:              AssertionError:  false  ==  true            at  (stack  trace  omitted  for  brevity) $  _
  • 100. ./package.json 1 { "name": "sample", 2 "version": "0.1.0", 3 "scripts": { 4 "test": "make test" 5 } 6 7 } 8 9 10 11 12 13 14 15 16
  • 101. $  npm  test    Assertions        ✓  should  pass  on  truthiness          1)  should  fail  on  falsiness    ✖  1  of  2  tests  failed:    1)  Assertions  should  fail  on  falsiness:              AssertionError:  false  ==  true            at  (stack  trace  omitted  for  brevity) $  _
  • 102. eliminate global dependency $  npm  install  mocha  -­‐-­‐link
  • 103. 1 test: @./node_modules/.bin/mocha 2 --reporter spec 3 --ui bdd 4 5 6 .PHONY: test 7 8 9 10 11 12 13 14 15 16 17 18
  • 104. update dev dependencies $  npm  install  mocha  -­‐-­‐save-­‐dev $  npm  install  chai    -­‐-­‐save-­‐dev
  • 105. $  npm  install  mocha  -­‐-­‐save-­‐dev $  npm  install  chai    -­‐-­‐save-­‐dev $  git  diff  package.json   diff  -­‐-­‐git  a/package.json  b/package.json index  439cf44..3609bb9  100644 -­‐-­‐-­‐  a/package.json +++  b/package.json @@  -­‐1,5  +1,7  @@  {      "name":  "sample", -­‐    "version":  "0.1.0" +    "version":  "0.1.0", +    "devDependencies":  { +        "mocha":  "~1.9.0", +        "chai":  "~1.6.0" +    }  }
  • 108. $  mocha  -­‐-­‐watch  ✔  5  tests  complete  (22ms)  ^  watching
  • 109. Growl
  • 110. mac: apple app store win: growlForWindows.com also: growlNotify
  • 112. ⌘S
  • 113. 1 test: @./node_modules/.bin/mocha 2 --reporter spec 3 --ui bdd 4 5 6 watch: @./node_modules/.bin/mocha 7 --reporter min 8 --ui bdd 9 --growl 10 --watch 11 12 13 .PHONY: test watch 14 15 16 17 18
  • 115. JavaScript ships with a mocking framework ...it’s called JavaScript
  • 116. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var me = {firstName: 'Jay' , lastName: 'Harris' , getFullName: function() { return this.firstName + ' ' + this.lastName; }}; // Returns 'Jay Harris' me.getFullName(); me.getFullName = function() { return 'John Doe'; }; // Returns 'John Doe' me.getFullName();
  • 119. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var http = require('http'); var reqOptions = { host: 'api.twitter.com', path: '/1/statuses/user_timeline.json?' + 'screen_name=jayharris' }; // ... http.request(reqOptions, resCallback).end(); // Returns live Twitter data
  • 120. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var nock = require('nock'); var twitter = nock('http://api.twitter.com') .get('/1/statuses/user_timeline.json?'+ 'screen_name=jayharris') .reply(200, "This worked"); // Returns "This worked" http.request(reqOptions, resCallback).end();
  • 121. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Returns live Twitter data http.request(reqOptions, resCallback).end(); var nock = require('nock'); var twitter = nock('http://api.twitter.com') .get('/1/statuses/user_timeline.json?'+ 'screen_name=jayharris') .reply(200, "This worked"); // Returns "This worked" http.request(reqOptions, resCallback).end(); // Returns live Twitter data http.request(reqOptions, resCallback).end();
  • 128. $  nvm  list        v0.4.0        v0.6.18        v0.8.21        v0.4.7          v0.8.1        v0.10.0        v0.6.0          v0.8.8 current:     v0.8.1 10  -­‐>  0.10.0  (-­‐>  v0.10.0) 4  -­‐>  0.4.7  (-­‐>  v0.4.7) 6  -­‐>  0.6.18  (-­‐>  v0.6.18) 8  -­‐>  0.8.21  (-­‐>  v0.8.21) default  -­‐>  0.10.0  (-­‐>  v0.10.0) newest  -­‐>  0.10.0  (-­‐>  v0.10.0) $  _
  • 129. $  node  -­‐-­‐version v0.10.0 $  nvm  install  v0.10.6 Now  using  node  v0.10.6 /Users/jayharris/.nvm/v0.10.6/bin/npm $  node  -­‐-­‐version v0.10.6 $  _
  • 134. $  npm  adduser Username:  (jayharris)  jayharris Password: Email:  (jay@aranasoft.com)  _
  • 137. {  name:  'morale',    description:  'Async  API  wrapper  for  Morale',    'dist-­‐tags':  {  latest:  '0.2.0'  },    versions:        [  '0.1.0',          '0.1.2',          '0.2.0'  ],    maintainers:  'jayharris  <jay@aranasoft.com>',    time:        {  '0.1.0':  '2012-­‐01-­‐23T03:24:59.824Z',          '0.1.2':  '2012-­‐01-­‐25T23:20:52.927Z',          '0.2.0':  '2012-­‐08-­‐13T16:23:28.488Z'  },    author:  'Arana  Software  <info@aranasoft.com>',    repository:        {  type:  'git',          url:  'git://github.com/aranasoft/morale-­‐node.git'  },    users:  {  fgribreau:  true  },    version:  '0.2.0',
  • 138. $  npm  publish npm  http  PUT  https://registry.npmjs.org/morale npm  http  409  https://registry.npmjs.org/morale npm  http  GET  https://registry.npmjs.org/morale npm  http  200  https://registry.npmjs.org/morale npm  http  PUT  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest npm  http  201  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest npm  http  GET  https://registry.npmjs.org/morale npm  http  200  https://registry.npmjs.org/morale npm  http  PUT  https://registry.npmjs.org/morale/-­‐/ morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b npm  http  201  https://registry.npmjs.org/morale/-­‐/ morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b +  morale@0.2.1 $  _
  • 139. {  name:  'morale',    description:  'Async  API  wrapper  for  Morale',    'dist-­‐tags':  {  latest:  '0.2.1'  },    versions:        [  '0.1.0',          '0.1.2',          '0.2.0',          '0.2.1'  ],    maintainers:  'jayharris  <jay@aranasoft.com>',    time:        {  '0.1.0':  '2012-­‐01-­‐23T03:24:59.824Z',          '0.1.2':  '2012-­‐01-­‐25T23:20:52.927Z',          '0.2.0':  '2012-­‐08-­‐13T16:23:28.488Z',          '0.2.1':  '2012-­‐08-­‐30T19:10:20.133Z'  },    author:  'Arana  Software  <info@aranasoft.com>',    repository:        {  type:  'git',          url:  'git://github.com/aranasoft/morale-­‐node.git'  },
  • 141. ./package.json 1 { "name": "Sample", 2 "version": "0.1.0", 3 "description": "This is a sample module", 4 "main": "index.js", 5 "scripts": { 6 "test": "echo "Error: no tests avail." && exit 1" 7 }, 8 "author": "Jay Harris", 9 "license": "BSD", 10 "private": "true" 11 12 } 13 14 15 16
  • 142. $  npm  publish npm  ERR!  Error:  This  package  has  been  marked  as  private npm  ERR!  Remove  the  'private'  field  from  the  package.json  to   publish  it. $  _
  • 144. $  npm  shrinkwrap wrote  npm-­‐shrinkwrap.json $  _
  • 145. 1 { "name": "morale", 2 "version": "0.2.1", 3 "dependencies": { 4 "underscore": { 5 "version": "1.3.3" 6 }, 7 "mocha": { 8 "version": "1.3.0", 9 "dependencies": { 10 "commander": { 11 "version": "0.6.1" 12 }, 13 "growl": { 14 "version": "1.5.1" 15 }, 16 "jade": { 17 "version": "0.26.3", 18
  • 146. $  rm  npm-­‐shrinkwrap.json $  npm  update $  npm  test $  npm  shrinkwrap
  • 148. Go make some Awesome
  • 149. jay harris P R E S I D E N T jay@aranasoft.com #nodemoduledev @jayharris