<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<title>Metadata-Helper Specs</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/mocha/2.0.1/mocha.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1><a href="index.html">Metadata-Helper</a></h1>
<div id="mocha"></div>
<!-- testharness:js -->
<script src="//cdnjs.cloudflare.com/ajax/libs/chai/1.10.0/chai.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/mocha/2.0.1/mocha.js"></script>
<script>
expect = chai.expect;
mocha.setup('bdd');
</script>
<!-- Breeze -->
<script src="https://rawgit.com/Breeze/breeze.js/master/build/breeze.debug.js"></script>
<script src="https://rawgit.com/Breeze/breeze.js.labs/master/breeze.metadata-helper.js"></script>
<!-- Tests -->
<script src="tests.js"></script>
<!-- CCJS Metadata in DocCode ... copy-and-pasted into ccjs.model.metadata.js in this plunker
<script src="https://rawgit.com/Breeze/breeze.js.samples/master/net/DocCode/DocCode/tests/helpers/ccjs.model.metadata.js"></script>
-->
<script src="ccjs.model.metadata.js"></script>
<script>
mocha.run();
</script>
</body>
</html>
/*
* Using Mocha and Chai BDD (expect) assertions: http://chaijs.com/api/bdd/
*/
describe('When client-defined CCJS metadata', function () {
'use strict';
var manager;
beforeEach(function(){
var dataService = new breeze.DataService({
serviceName: '< no_server >',
hasServerMetadata: false
});
var metadataStore = new breeze.MetadataStore();
metadataStore.addDataService(dataService);
docCode.testFns.ccjsFillMetadataStore(metadataStore);
manager = new breeze.EntityManager({
dataService: dataService,
metadataStore: metadataStore
});
});
it("can create a Session", function () {
var session = manager.createEntity('Session', {
title: "Metadata by Hand with Metadata-Helper",
description: "Learn how to write Breeze metadata on the client with the Metadata-Helper"
});
expectAddedEntity(session);
});
it("can create a Session with a Speaker (Person)", function () {
var person = manager.createEntity('Person', {
firstName: 'Ward',lastName: 'Bell'
});
var session = manager.createEntity('Session', {
title: "Metadata by Hand with Metadata-Helper",
description: "Learn how to write Breeze metadata on the client with the Metadata-Helper",
speaker: person
});
expectAddedEntity(session);
expect(session.speaker.id).to.equal(person.id,
"Session's speaker should be same as the person created");
});
it("can create a Speaker (Person) with multiple Sessions", function () {
var person = manager.createEntity('Person', {
firstName: 'Ward',lastName: 'Bell'
});
var session1 = manager.createEntity('Session', {
title: "Metadata by Hand with Metadata-Helper",
description: "Learn how to write Breeze metadata on the client with the Metadata-Helper",
speaker: person
});
var session2 = manager.createEntity('Session', {
title: "Breeze: our gift to the world",
description: "Learn how Breeze solves world peace and cures diseases",
speaker: person
});
// get those sessions by navigating from the person w/ `sessions` property
var navSessions = person.speakerSessions;
expect(navSessions.length).to.equal(2, "person should have two related sessions");
expect(navSessions.indexOf(session1)).to.be.above(-1,
'should include session1');
expect(navSessions.indexOf(session2)).to.be.above(-1,
'should include session2');
});
////////////////
function expectAddedEntity(entity, entityName) {
var entityState = entity.entityAspect.entityState;
entityName = entityName || "'"+entity.entityType.shortName + "'";
expect(entityState.isAdded()).to.equal(true,
"a created '" + entityName +
"' should have 'Added' state; its entityState is '" +
entityState + "'.");
}
});
// Define this global for ccjs.model.metadata.js which expects it to be predefined.
docCode = window.docCode || {testFns: {}};
body {
padding-left: 4px;
font: 20px/1.5 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
#mocha {margin: 0;}
#Breeze Metadata By Hand with Metadata-Helper
The Breeze documentation page,
["*Metadata By Hand*"](http://www.getbreezenow.com/documentation/metadata-by-hand),
describes why and how you can write Breeze metadata on the client
with help from the
[Breeze Labs Metadata-Helper](https://github.com/Breeze/breeze.js.labs/blob/master/breeze.metadata-helper.js).
This plunker demonstrates through Mocha/Chai tests that you can use such metadata
in your application.
The metadata in this example are in the "*ccjs.model.metadata.js*" file.
They describe the Code Camper model in John Papa's
PluralSight Course
["Building Data-Centric Single Page Applications with Breeze"](http://www.pluralsight.com/courses/table-of-contents/building-single-page-applications-breeze).
This model consists of Sessions,
Persons (speakers), Rooms, Tracks, and TimeSlots.
These tests are based on tests in the "metadataOnClientTests.js" in the
[Breeze DocCode sample](http://www.getbreezenow.com/samples/doccode).
/**
* CCJS Model Metadata by hand from John Papa's PluralSight Course
* "Building Data-Centric Single Page Applications with Breeze"
* http://www.pluralsight.com/courses/table-of-contents/building-single-page-applications-breeze
*
* Copied from
* https://rawgit.com/Breeze/breeze.js.samples/master/net/DocCode/DocCode/tests/helpers/ccjs.model.metadata.js
*/
// ReSharper disable InconsistentNaming
(function (testFns) {
'use strict';
testFns.ccjsFillMetadataStore = fillMetadataStore;
/////// Create and configure a Metadata-Helper instance //////////
// 'Identity' is the default key generation strategy for this app
var keyGen = breeze.AutoGeneratedKeyType.Identity;
// namespace of the corresponding classes on the server
var namespace = 'CC.Model';
// Breeze Labs: breeze.metadata.helper.js
// https://github.com/IdeaBlade/Breeze/blob/master/Breeze.Client/Scripts/Labs/breeze.metadata-helper.js
// The helper reduces data entry by applying common conventions
// and converting common abbreviations (e.g., 'type' -> 'dataType')
var helper = new breeze.config.MetadataHelper(namespace, keyGen);
/////////////////
function fillMetadataStore(store) {
// DataTypes
var DT = breeze.DataType;
var BOOL = DT.Boolean;
var DATE = DT.DateTime;
var ID = DT.Int32;
// type order is irrelevant
addPerson();
addSession();
addRoom();
addTimeSlot();
addTrack();
// addType - make it easy to add the type to the store using the helper
function addType(type) {
helper.addTypeToStore(store, type);
}
function addPerson() {
addType({
name: 'Person',
dataProperties: {
id: { type: ID },
firstName: { max: 50, required: true },
lastName: { max: 50, required: true },
// could add validators here; let model.validation add them
email: { max: 400 },
blog: { max: 400 },
twitter: { max: 400 },
gender: { max: 1 },
imageSource: { max: 400 },
// could let Breeze add unmapped but we do so to lock in the Boolean data type
isPartial: { type: BOOL, required: true, isUnmapped: true },
isSpeaker: { type: BOOL, required: true, isUnmapped: true }
},
navigationProperties: {
speakerSessions: { type: 'Session', hasMany: true }
}
});
}
function addSession() {
addType({
name: 'Session',
dataProperties: {
id: { type: ID },
title: { max: 50, required: true },
code: { max: 10 },
description: { max: 4000 },
level: { max: 30 },
tags: { max: 4000 },
roomId: { type: ID, required: true },
speakerId: { type: ID, required: true },
timeSlotId: { type: ID, required: true },
trackId: { type: ID, required: true },
isPartial: { type: BOOL, required: true, isUnmapped: true }
},
// Let model.validation add the requireReferenceEntity validators
navigationProperties: {
room: 'Room',
speaker: 'Person',
timeSlot: 'TimeSlot',
track: 'Track'
}
});
}
function addRoom() {
addType({
name: 'Room',
dataProperties: {
id: { type: ID },
name: { max: 50, required: true }
}
});
}
function addTimeSlot() {
addType({
name: 'TimeSlot',
dataProperties: {
id: { type: ID },
start: { type: DATE, required: true },
isSessionSlot: { type: BOOL, required: true },
duration: { type: ID, required: true }
}
});
}
function addTrack() {
addType({
name: 'Track',
dataProperties: {
id: { type: ID },
name: { max: 50, required: true }
}
});
}
}
})(docCode.testFns);