Skip to content

Commit

Permalink
Lots of documentation improvements.
Browse files Browse the repository at this point in the history
Added DSLocalStorageAdapter.
  • Loading branch information
jmdobry committed May 18, 2014
1 parent 87a9652 commit f1c1228
Show file tree
Hide file tree
Showing 18 changed files with 715 additions and 73 deletions.
251 changes: 216 additions & 35 deletions dist/angular-data.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/angular-data.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions guide/angular-data-mocks/overview.doc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
@name Overview
@description

Angular-data is a fake angular-data implementation suitable for unit testing angular applications that use the `angular-data.DS` module.
Angular-data-mocks is a fake angular-data implementation suitable for unit testing angular applications that use the `angular-data.DS` module.

__Version:__ 0.3.0
__Version:__ 0.3.2

__angular-data-mocks requires [sinon](http://sinonjs.org/) to be loaded in order to work.__

Expand Down
33 changes: 32 additions & 1 deletion guide/angular-data-mocks/setup.doc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@
@name Setting Up
@description

TODO: Explain how to set up angular tests to use angular-data-mocks.
Angular-data-mocks works just like [angular-mocks](https://docs.angularjs.org/api/ngMock). Angular-data-mocks simply needs
to be loaded after angular, angular-mocks, and angular-data in your tests. After you declare your test module, and before
you create the injector, activate angular-data-mocks by calling `module('angular-data.mocks')`.

## Example (Mocha)
`karma.start.js`

```js
var DS, DSHttpAdapter;

angular.module('myApp', ['angular-data.DS']);

beforeEach(function () {
angular.mocks.module('myApp');
});

beforeEach(function () {
angular.mocks.module('angular-data.mocks');
});

beforeEach(function (done) {
inject(function (_DS_, _DSHttpAdapter_) {
DS = _DS_;
DSHttpAdapter = _DSHttpAdapter_;

done();
});
});
```

If you're using [KarmaJS](http://karma-runner.github.io/0.12/index.html) to test your app, look through the tests in the
[angular-data-mocks repo](https://github.com/jmdobry/angular-data-mocks) for an example Karma setup.

Refer to the [angular-data-mocks API](/documentation/api/angular-data-mocks/angular-data-mocks) for more detailed information.
57 changes: 56 additions & 1 deletion guide/angular-data-mocks/testing.doc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,61 @@
@name Testing
@description

TODO: Explain how to use angular-data-mocks in angular tests.
Once you're setup to test using angular-data-mocks you can use it much like `$httpBackend`. For the asynchronous methods
you declare expectations and then flush pending requests.

## Example:
`app.js`:

```js
angular.module('testApp', ['angular-data.DS'])
.controller('MyCtrl', function ($scope, DS) {
'use strict';
DS.find('post', 45);

$scope.update = function (attrs) {
return DS.update('post', 45, attrs);
}
});
```

`test.js`:

```js
describe('test', function () {
var MyCtrl, $scope;

beforeEach(function (done) {
$scope = $rootScope.$new();

DS.expectFind('post', 45).respond({
author: 'John Anderson',
id: 5
});

inject(function ($controller) {
MyCtrl = $controller('MyCtrl', {
$scope: $scope,
DS: DS
});

DS.flush();

done();
});
});

it('should update the post', function () {
DS.expectUpdate('post', 45, { author: 'Sally' })
.respond({ id: 5, author: 'Sally' });

$scope.update().then(function (post) {
assert.deepEqual(post, { id: 5, author: 'Sally' });
});

DS.flush();
});
});
```

Refer to the [angular-data-mocks API](/documentation/api/angular-data-mocks/angular-data-mocks) for more detailed information.
34 changes: 34 additions & 0 deletions guide/angular-data/adapters/adapters.doc
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,37 @@
@id overview
@name Overview of adapters
@description

Angular-data ships with a `DSHttpAdapter` and a `DSLocalStorageAdapter`. This is default adapter
used for `DS.findAll`, `DS.update`, etc.

Register a custom adapter:
```js
DS.adapters.myCustomAdapter = { ... };
```

Other available adapters:

- [DSLocalStorageAdapter](https://github.com/jmdobry/angular-data/blob/master/src/adapters/localStorage.js)
- [DSLocalForageAdapter](https://github.com/jmdobry/angular-data-localForage)

The default adapter can be set globally:

```js
DSProvider.defaults.defaultAdapter = 'DSHttpAdapter';
```

per resource:

```js
DS.defineResource({
name: 'user',
defaultAdapter: 'DSLocalForageAdapter'
});
``

per method

```js
DS.update('post', 45, { author: 'Sally' }, { adapter: 'DSLocalForageAdapter' });
```
4 changes: 3 additions & 1 deletion guide/angular-data/asynchronous.doc
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ The asynchronous methods return Promises produced by Angular's `$q` service.
Example:

```js
// synchronous
DS.get('document', 45); // undefined

// asynchronous
DS.find('document', 45).then(function (document) {
document; // { title: 'How to Cook', id: 45 }

Expand Down Expand Up @@ -40,4 +42,4 @@ DS.save('document', 45).then(function (document) {
DS.get('document', 45); // { title: 'How to Cook', id: 45 }
```

See the [API](/documentation/api/api/index) for more information.
See the [DS API](/documentation/api/angular-data/DS) for more information.
34 changes: 31 additions & 3 deletions guide/angular-data/how.doc
Original file line number Diff line number Diff line change
@@ -1,22 +1,50 @@
@doc overview
@id how
@name How do I...?
@name How do I?
@description

#### How do I serialize data before it's saved?
Before the data store sends date to an adapter, you may need to transform it to a custom request object of yours.

Define a global serialization method:
```js
DSHttpAdapter.defaults.serialize = function (data) {
DSProvider.defaults.serialize = function (resourceName, data) {
// custom payload format
return {
payload: data
};
};
```

Define a serialization method for a specific resource:
```js
DS.defineResource({
name: 'user',
serialize: function (resourceName, user) {
return {
payload: user
};
}
});
```

#### How do I deserialize data?
When an adapter returns data to the data store from the server, for example, you may need to extract data from a custom response object of yours.

Define a global deserialization method:
```js
DSHttpAdapter.defaults.deserialize = function (data) {
DSProvider.defaults.deserialize = function (resourceName, data) {
// extract data from custom payload format
return data ? data.payload : data;
};
```

Define a deserialization method for a specific resource:
```js
DS.defineResource({
name: 'user',
deserialize: function (resourceName, data) {
return data.data.embedded;
}
});
```
31 changes: 18 additions & 13 deletions guide/angular-data/overview.doc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
@description

Angular-data is an in-browser data store for [Angular.js](http://angularjs.org).
[Synchronous methods](/documentation/guide/synchronous/index) work only with data already in the data store, and
[asynchronous methods](/documentation/guide/asynchronous/index) work with a persistence layer.
[Synchronous methods](/documentation/guide/angular-data/synchronous) work only with data already in the data store, and
[Asynchronous methods](/documentation/guide/angular-data/asynchronous) work with a persistence layer.

<p>
<img src="/resources/img/chart.png" width="940">
Expand All @@ -15,7 +15,7 @@ Angular-data is an in-browser data store for [Angular.js](http://angularjs.org).
```js
angular.module('myApp', ['angular-data.DS'])
.config(function (DSProvider) {
DSProvider.defaults.baseUrl = 'https://example.com/api';
DSProvider.defaults.baseUrl = '/api';
})
.run(function (DS) {
DS.defineResource({
Expand All @@ -25,16 +25,21 @@ angular.module('myApp', ['angular-data.DS'])
});
})
.controller('PostCtrl', function ($scope, DS) {
var query = {
query: {
where: {
author: 'John Anderson'
}
}
};
var params = {
query: {
where: {
author: {
'==': 'John Anderson'
}
}
}
};

DS.findAll('post', query);
DS.findAll('post', params);

DS.bindAll($scope', 'posts', 'post', params);

// Verbose way of doing the bindAll() above, but gives more control
$scope.$watch(function () {
return DS.lastModified('post');
}, function () {
Expand All @@ -54,7 +59,7 @@ $scope.posts; // [{ id: 1, author: 'John Anderson', title: 'How to cook' },

You define _resources_ and register them with the data store. A _resource definition_ tells angular-data
about a particular resource, like what its root endpoint is and which attribute refers to the primary key of the
resource. A _resource definition_ can also specify validation functions to be executed during model lifecycle operations.
resource. A _resource definition_ can also specify functions to be executed during model lifecycle operations.

```js
DS.defineResource({
Expand All @@ -71,7 +76,7 @@ DS.defineResource({
});
```

`validate` will be executed at the beginning of the lifecycle initiated by a call to `DS.create` or `DS.save`.
`validate` will be executed at the beginning of the lifecycle initiated by a calls to `DS.create`, `DS.save`, etc.
```js
DS.create('post', { author: 'Sally', title: 'Angular gotchas' })
.then(function (post) {
Expand Down
8 changes: 4 additions & 4 deletions guide/angular-data/synchronous.doc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $scope.$watch(function () {
// Here we are watching the "lastModified" timestamp maintained by the data store for this particular document

return DS.lastModified('document', 45);
}, function (lastModifiedTimestamp) {
}, function () {
// When this callback is executed, it means that the data store thinks the item changed

// Retrieve the updated item from the data store's cache
Expand All @@ -35,7 +35,7 @@ To make things simpler, angular-data has some bind methods to help with this:
DS.bindOne($scope, 'myDoc', 'document', 45');
```

The above example shows how to bind an item in the data store to the stop. Whenever that item changes it will be updated
The above example shows how to bind an item in the data store to the $scope. Whenever that item changes it will be updated
on the $scope.

When the app starts up, the calls to `lastModified()` and `get()` will both returned undefined, because the item isn't in
Expand Down Expand Up @@ -66,6 +66,6 @@ DS.eject('document', 45); // synchronously eject document from the store
```

User #2 doesn't need to destroy document 45, because it's already been deleted on the server by user #1. User #2 just
needs to kick document 45 out of the data store and be done with it.
needs to kick document #45 out of the data store and be done with it.

See the [API](/documentation/api/api/index) for more information.
See the [DS API](/documentation/api/angular-data/DS) for more information.
12 changes: 8 additions & 4 deletions karma.start.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Setup global test variables
var $rootScope, $q, $log, DSProvider, DSHttpAdapterProvider, DS, DSHttpAdapter, app, $httpBackend, p1, p2, p3, p4, p5;
var $rootScope, $q, $log, DSHttpAdapterProvider, DSProvider, DSLocalStorageAdapter, DS, DSUtils, DSHttpAdapter, app, $httpBackend, p1, p2, p3, p4, p5;

var lifecycle = {};

Expand Down Expand Up @@ -86,8 +86,6 @@ beforeEach(function (done) {
return query;
};
module('app', function (_DSProvider_, _DSHttpAdapterProvider_) {
DSHttpAdapterProvider = _DSHttpAdapterProvider_;
DSHttpAdapterProvider.defaults.queryTransform = lifecycle.queryTransform;
DSProvider = _DSProvider_;
DSProvider.defaults.baseUrl = 'http://test.angular-cache.com';
DSProvider.defaults.beforeValidate = lifecycle.beforeValidate;
Expand All @@ -103,13 +101,19 @@ beforeEach(function (done) {
DSProvider.defaults.afterInject = lifecycle.afterInject;
DSProvider.defaults.serialize = lifecycle.serialize;
DSProvider.defaults.deserialize = lifecycle.deserialize;
DSHttpAdapterProvider = _DSHttpAdapterProvider_;
DSHttpAdapterProvider.defaults.queryTransform = lifecycle.queryTransform;

});
inject(function (_$rootScope_, _$q_, _$httpBackend_, _DS_, _$log_, _DSHttpAdapter_) {
inject(function (_$rootScope_, _$q_, _$httpBackend_, _DS_, _$log_, _DSUtils_, _DSHttpAdapter_, _DSLocalStorageAdapter_) {
// Setup global mocks
localStorage.clear();
$q = _$q_;
$rootScope = _$rootScope_;
DS = _DS_;
DSUtils = _DSUtils_;
DSHttpAdapter = _DSHttpAdapter_;
DSLocalStorageAdapter = _DSLocalStorageAdapter_;
$httpBackend = _$httpBackend_;
DS.defineResource({
name: 'post',
Expand Down
4 changes: 0 additions & 4 deletions src/adapters/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,6 @@ function DSHttpAdapterProvider() {
*/
create: create,

createMany: function () {
throw new Error('Not yet implemented!');
},

/**
* @doc method
* @id DSHttpAdapter.methods:update
Expand Down
Loading

1 comment on commit f1c1228

@jmdobry
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#63

Please sign in to comment.