Chromium Code Reviews| Index: test/firebase_collection_test.dart |
| diff --git a/test/firebase_collection_test.dart b/test/firebase_collection_test.dart |
| index 8881ccb13ca74536811399293e3aeb5f632d84c5..dd23bc541163a29f544fe1c3e253e07ec3c190c5 100644 |
| --- a/test/firebase_collection_test.dart |
| +++ b/test/firebase_collection_test.dart |
| @@ -11,192 +11,256 @@ import 'package:polymer_elements/firebase_collection.dart'; |
| import 'package:web_components/web_components.dart'; |
| import 'package:test/test.dart'; |
| import 'common.dart'; |
| +import 'firebase_test_helpers.dart'; |
| main() async { |
| await initWebComponents(); |
| - group('<firebase-collection>', () { |
| + group('firebase-collection', () { |
| FirebaseCollection firebase; |
| - group('collection manipulation', () { |
| - DomBind domBind; |
| - var dom; |
| + tearDown(() { |
| + if (firebase != null) removeFirebase(firebase); |
| + }); |
| + |
| + group('basic usage', () { |
| + var numberOfItems; |
| setUp(() { |
| - dom = fixture('BoundCollection'); |
| - domBind = dom.querySelector('[is=dom-bind]'); |
| - firebase = dom.querySelector('firebase-collection'); |
| + numberOfItems = 3; |
| + firebase = |
| + fixtureFirebase('TrivialCollection', arrayOfObjects(numberOfItems)); |
| + return wait(1); |
| }); |
| - test('added values reflect 1-to-1 in the DOM', () { |
| - return firebase.on['firebase-value'].first.then((_) { |
| - var done = firebase.on['firebase-child-added'].first.then((_) { |
| - expect(dom.querySelectorAll('div').length, firebase.data.length); |
| - }); |
| - domBind.insert('data', 0, {'value': 'blah'}); |
| - domBind.render(); |
| - return done; |
| - }); |
| + test('exposes data as an array', () { |
| + expect(firebase.data is List, isTrue); |
| + expect(firebase.data.length, numberOfItems); |
| }); |
| - }, skip: 'https://github.com/dart-lang/polymer_elements/issues/62'); |
| - group('basic usage', () { |
| - setUp(() { |
| - firebase = fixture('TrivialCollection'); |
| + test('receives data from Firebase location', () { |
| + expect(firebase.data[0]['value'] is num, isTrue); |
| }); |
| + }); |
| - tearDown(() { |
| - firebase.disconnect(); |
| + group('ordered primitives', () { |
| + var numberOfItems; |
| + |
| + setUp(() { |
| + numberOfItems = 5; |
| + firebase = fixtureFirebase( |
| + 'TrivialCollection', arrayOfPrimitives(numberOfItems)); |
| + firebase.orderByValue = true; |
| }); |
| - test('exposes data as an array', () { |
| - return firebase.on['firebase-child-added'].first.then((_) { |
| - expect(firebase.data is List, isTrue); |
| - }); |
| + test('converts primitives into objects with a value key', () { |
| + expect(firebase.data[0] is JsObject, isTrue); |
| }); |
| - test('receives data from Firebase location', () { |
| - return firebase.on['data-changed'].first.then((_) { |
| - expect(firebase.data[0]['value'], true); |
| + test('orders primitives by value', () { |
| + var lastValue = -1; |
| + |
| + expect(firebase.data.length, numberOfItems); |
| + |
| + firebase.data.forEach((datum) { |
| + expect(datum['value'], isNot(lessThan(lastValue))); |
| + lastValue = datum['value']; |
| }); |
| }); |
| }); |
| - group('ordered primitives', () { |
| + group('removing a value locally', () { |
| + var numberOfItems; |
| setUp(() { |
| - firebase = fixture('PrimitiveCollection'); |
| + numberOfItems = 3; |
| + firebase = |
| + fixtureFirebase('TrivialCollection', arrayOfObjects(numberOfItems)); |
| }); |
| - tearDown(() { |
| - firebase.disconnect(); |
| + test('works for data-bound changes', () { |
| + firebase.removeAt('data', 0); |
| + expect(firebase.data.length, numberOfItems - 1); |
| }); |
| - test('converts primitives into objects with a value key', () { |
| - return firebase.on['firebase-child-added'].first.then((_) { |
| - expect(firebase.data[0], isNotNull); |
| - }); |
| + test('can be done with `remove`', () { |
| + var objectToBeRemoved = firebase.data[0]; |
| + firebase.removeItem(objectToBeRemoved); |
| + |
| + expect(firebase.data.length, numberOfItems - 1); |
| + expect(firebase.data.indexOf(objectToBeRemoved), -1); |
| }); |
| + }); |
| - test('orders primitives by value', () { |
| - return firebase.on['firebase-value'].first.then((_) { |
| - var lastValue = -1.0 / 0; |
| - expect(firebase.data.length, greaterThan(0)); |
| - firebase.data.forEach((item) { |
| - expect(item['value'], greaterThanOrEqualTo(lastValue)); |
| - lastValue = item['value']; |
| - }); |
| - }); |
| + group('adding a value locally', () { |
| + setUp(() { |
| + firebase = fixtureFirebase('TrivialCollection'); |
| }); |
| - group('adding a value locally', () { |
| - setUp(() { |
| - return firebase.on['firebase-value'].first; |
| - }); |
| + test('works for data-bound changes', () { |
| + var done = new Completer(); |
| + var intendedValue = randomInt(); |
| + // Can't call `add` since it is overridden |
| + var index = |
| + firebase.jsElement.callMethod('push', ['data', intendedValue]) - 1; |
|
Siggi Cherem (dart-lang)
2015/10/28 22:35:16
should `push` be exposed in the Dart API? Is it pa
jakemac
2015/10/29 16:07:29
I guess what should really happen here is changing
|
| + |
| + // NOTE(cdata): See polymer/polymer#2491. |
| + firebase.async(() { |
| + expect(firebase.data[index]['value'], isNotNull); |
| + expect(firebase.data[index]['value'], intendedValue); |
| + done.complete(); |
| + }, waitTime: 1); |
| + |
| + return done.future; |
| + }); |
| + |
| + test('can be done with `add`', () { |
| + var done = new Completer(); |
| + var object = randomObject(); |
| + var length = firebase.data.length; |
| + var foundObject; |
| + |
| + firebase.add(new JsObject.jsify(object)); |
| - test('can be done with `add`', () { |
| - var length = firebase.data.length; |
| - var newValue = firebase.data[firebase.data.length - 1]['value'] + 1; |
| - var key; |
| - |
| - var done = firebase.on['firebase-child-added'].first.then((_) { |
| - expect(firebase.data.length, length + 1); |
| - expect(firebase.data[firebase.data.length - 1]['value'], newValue); |
| - }).then((_) async { |
| - await wait(1); |
| - firebase.removeByKey(key); |
| + // NOTE(cdata): See polymer/polymer#2491. |
| + firebase.async(() { |
| + expect(firebase.data.length, length + 1); |
| + |
| + firebase.data.forEach((datum) { |
| + if (datum['value'] == object['value']) { |
| + foundObject = datum; |
| + } |
| }); |
| - key = firebase.add(newValue).callMethod('key'); |
| - return done; |
| - }); |
| + expect(foundObject, isNotNull); |
| + expect(foundObject['value'], object['value']); |
| + done.complete(); |
| + }, waitTime: 1); |
| + |
| + return done.future; |
| }); |
| }); |
| - group('a child changes', () { |
| + group('a changing child', () { |
| + var numberOfItems; |
| + var remoteFirebase; |
| + |
| setUp(() { |
| - firebase = fixture('ChangingChildren'); |
| - return firebase.on['firebase-value'].first; |
| + numberOfItems = 3; |
| + firebase = |
| + fixtureFirebase('TrivialCollection', arrayOfObjects(numberOfItems)); |
| + remoteFirebase = new JsObject(context['Firebase'], [firebase.location]); |
| }); |
| test('updates the child key in place with the new value', () { |
| - var childrenKeys = []; |
| + var datum = firebase.data[0]; |
| + var newValue = 99999; |
| + var key = context['Polymer']['Collection'] |
| + .callMethod('get', [firebase.data]).callMethod('getKey', [datum]); |
| - var done = firebase.on['firebase-value'].first.then((_) async { |
| - // Wait for childrenKeys to be populated |
| - await new Future(() {}); |
| - var middleValue = firebase.getByKey(childrenKeys[1]); |
| - var changes; |
| + firebase.set('data.$key.value', newValue); |
| - expect(middleValue['foo'], 1); |
| - expect(middleValue['bar'], 1); |
| + expect(firebase.data[0]['value'], newValue); |
| + }); |
| + }); |
| - changes = firebase.on['firebase-child-changed'].first; |
| + group('syncing collections', () { |
| + var numberOfItems; |
| + var remoteFirebase; |
| - firebase.set('data.${firebase.data.indexOf(middleValue)}.bar', 2); |
| + setUp(() { |
| + numberOfItems = 3; |
| - return changes; |
| - }).then((_) { |
| - var middleValue = firebase.getByKey(childrenKeys[1]); |
| + firebase = fixtureFirebase('TrivialCollection', arrayOfObjects(3)); |
| + firebase.orderValueType = 'number'; |
| + firebase.orderByValue = true; |
| - expect(middleValue['foo'], 1); |
| - expect(middleValue['bar'], 2); |
| - }).then((_) { |
| - childrenKeys.forEach((key) { |
| - firebase.removeByKey(key); |
| - }); |
| - }); |
| + remoteFirebase = new JsObject(context['Firebase'], [firebase.location]); |
| + }); |
| - var index = -1; |
| - childrenKeys = [0, 1, 2].map((value) { |
| - index++; |
| - return firebase |
| - .add(new JsObject.jsify({'foo': value, 'bar': index})) |
| - .callMethod('key'); |
| - }).toList(); |
| + test('sync a new item at the correct index', () { |
| + var firstValue = firebase.data[0]; |
| + var secondValue = firebase.data[1]; |
| + var datum = firebase.data[0]; |
| + var key = context['Polymer']['Collection'] |
|
Siggi Cherem (dart-lang)
2015/10/28 22:35:16
do we want to eventually wrap these static APIs as
jakemac
2015/10/29 16:07:29
These collection apis are not really useful in gen
|
| + .callMethod('get', [firebase.data]).callMethod('getKey', [datum]); |
| + var remoteValue; |
| + |
| + remoteFirebase.callMethod('on', [ |
| + 'value', |
| + (snapshot) { |
| + remoteValue = snapshot.callMethod('val'); |
| + } |
| + ]); |
| - return done; |
| + expect(remoteValue[0]['value'], firebase.data[0]['value']); |
| }); |
| }); |
| - group('syncing collections', () { |
| - FirebaseCollection localFirebase; |
| - FirebaseCollection remoteFirebase; |
| + group('data-bound collection manipulation', () { |
| + var numberOfItems; |
| + var elements; |
| + DomBind domBind; |
| setUp(() { |
| - var children = fixture('SyncingCollections'); |
| - localFirebase = children[0]; |
| - remoteFirebase = children[1]; |
| - return Future.wait([ |
| - localFirebase.on['firebase-value'].first, |
| - remoteFirebase.on['firebase-value'].first |
| - ]); |
| + elements = fixture('BoundCollection'); |
| + domBind = elements.querySelector('[is=dom-bind]'); |
| + firebase = elements.querySelector('firebase-collection'); |
| + firebase.location = fixtureLocation(arrayOfObjects(3)); |
| + numberOfItems = 3; |
| }); |
| - test('syncs a new item at the correct index', () { |
| - var data = {'foo': 100}; |
| - var key; |
| + test('splices reflect in Firebase data', () { |
| + var done = new Completer(); |
| + domBind.removeAt('data', 0); |
| + domBind.add('data', randomObject()); |
| + domBind.removeAt('data', 0); |
| + domBind.addAll('data', arrayOfObjects(2)); |
| - var done = remoteFirebase.on['firebase-value'].first.then((_) async { |
| - await wait(1); |
| - var value = remoteFirebase.getByKey(key); |
| - var lowValue = remoteFirebase.getByKey('lowValue'); |
| - var highValue = remoteFirebase.getByKey('highValue'); |
| + // NOTE(cdata): See polymer/polymer#2491. |
| + firebase.async(() { |
| + expect(firebase.data.length, domBind['data'].length); |
| - var index = remoteFirebase.data.indexOf(value); |
| - var lowIndex = remoteFirebase.data.indexOf(lowValue); |
| - var highIndex = remoteFirebase.data.indexOf(highValue); |
| + for (int i = 0; i < firebase.data.length; i++) { |
| + var datum = firebase.data[i]; |
| + expect(domBind['data'][i]['value'], datum['value']); |
| + } |
| - expect(value, isNotNull); |
| - expect(index, lessThan(highIndex)); |
| - expect(index, greaterThan(lowIndex)); |
| - }).then((_) { |
| - localFirebase.removeByKey(key); |
| - }); |
| - |
| - key = localFirebase.add(new JsObject.jsify(data)).callMethod('key'); |
| + done.complete(); |
| + }, waitTime: 1); |
| - return done; |
| + done.future; |
| }); |
| + |
| + test('splices reflect in the DOM', () { |
| + var divs; |
| + var done = new Completer(); |
| + |
| + firebase.jsElement.callMethod('push', |
| + ['data']..addAll(new JsObject.jsify(arrayOfObjects(3)) as JsArray)); |
| + |
| + firebase.async(() { |
| + divs = elements.querySelectorAll('div'); |
| + expect(divs.length, firebase.data.length); |
| + |
| + domBind.removeAt('data', 2); |
| + domBind.add('data', randomObject()); |
| + |
| + firebase.async(() { |
| + divs = elements.querySelectorAll('div'); |
| + expect(divs.length, firebase.data.length); |
| + |
| + for (int i = 0; i < firebase.data.length; i++) { |
| + var datum = firebase.data[i]; |
| + var divValue = int.parse(divs[i].text); |
| + expect(datum.value, divValue); |
| + } |
| + |
| + done.complete(); |
| + }, waitTime: 1); |
| + }, waitTime: 1); |
| + |
| + return done.future; |
| + }, skip: 'https://github.com/dart-lang/polymer_elements/issues/62'); |
| }); |
| }); |
| } |