blob: c7f39f9ef46fa949c7082a2a4b7e9ed2c7bff056 [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library swarm_tests;
import 'dart:html';
import 'dart:async';
import 'package:expect/expect.dart';
import 'package:unittest/html_config.dart';
import 'package:unittest/unittest.dart';
import '../swarmlib.dart';
import '../swarm_ui_lib/base/base.dart';
import '../swarm_ui_lib/util/utilslib.dart';
// TODO(jmesserly): these would probably be easier to debug if they were written
// in the WebKit layout test style, so we could easy compare that the DOM is
// what we expect it to be after performing some simulated user actions.
void main() {
useHtmlConfiguration();
Swarm swarm = new Swarm(useCannedData: true);
UIStateProxy state = new UIStateProxy(swarm.sections);
swarm.state = state;
swarm.run();
// TODO(jmesserly): should be adding the full stylesheet here
Dom.addStyle('''
.story-content {
-webkit-column-width: 300px;
-webkit-column-gap: 26px; /* 2em */
}''');
getStoryNode() => swarm.frontView.storyView.node;
getView(Section section) {
return CollectionUtils.find(
swarm.frontView.sections.childViews, (view) => view.section == section);
}
getHistory(Article article) {
final feed = article.dataSource;
return {
'section': CollectionUtils
.find(swarm.sections, (s) => s.feeds.indexOf(feed, 0) >= 0)
.id,
'feed': feed.id,
'article': article.id
};
}
test('BackButton', () {
_serialInvokeAsync([
() {
Expect.equals(null, swarm.frontView.storyView); // verify initial state
// Make sure we've transitioned to the section
// In the real app, this isn't needed because ConveyorView fires the
// transition end event before we can click a story.
SectionView section = getView(swarm.sections[0]);
section.showSources();
},
() {
final item = swarm.sections[0].feeds[2].articles[1];
state.loadFromHistory(getHistory(item));
Expect.equals(item, state.currentArticle.value);
Expect.isFalse(getStoryNode().classes.contains(CSS.HIDDEN_STORY));
state.loadFromHistory({});
Expect.equals(null, state.currentArticle.value);
Expect.isTrue(getStoryNode().classes.contains(CSS.HIDDEN_STORY));
}
]);
});
test('StoryView', () {
state.clearHistory();
Expect.isTrue(getStoryNode().classes.contains(CSS.HIDDEN_STORY));
final dataSourceView =
swarm.frontView.currentSection.dataSourceView.getSubview(0);
final itemView = dataSourceView.itemsView.getSubview(0);
// TODO(jacobr): remove this null check. This is likely due to tests
// running without the correct CSS to size the window so that some items
// are visible.
if (itemView != null) {
click(itemView.node);
state.expectHistory([getHistory(itemView.item)]);
}
});
test('SliderMenu', () {
Expect.equals(getView(swarm.sections[0]), swarm.frontView.currentSection);
// Find the first slider menu item, and click on the one next after it.
click(document.querySelectorAll('.${CSS.SM_ITEM}')[1]);
Expect.equals(getView(swarm.sections[1]), swarm.frontView.currentSection);
// Find the first menu item again and click on it.
click(document.querySelector('.${CSS.SM_ITEM}'));
Expect.equals(getView(swarm.sections[0]), swarm.frontView.currentSection);
});
}
/** Triggers the click event, like [http://api.jquery.com/click/] */
click(Element element) {
// TODO(rnystrom): This should be on the DOM API somewhere.
MouseEvent event = new MouseEvent('click');
element.dispatchEvent(event);
}
/** A proxy so we can intercept history calls */
class UIStateProxy extends SwarmState {
List<Map<String, String>> history;
UIStateProxy(Sections dataModel) : super(dataModel) {
clearHistory();
}
void pushToHistory() {
history.add(toHistory());
super.pushToHistory();
}
void clearHistory() {
history = new List<Map<String, String>>();
}
void expectHistory(List<Map<String, String>> entries) {
Expect.equals(entries.length, history.length);
for (int i = 0; i < entries.length; i++) {
Map e = entries[i];
Map h = history[i];
Expect.equals(e['article'], h['article']);
}
clearHistory();
}
}
void _serialInvokeAsync(List closures) {
final length = closures.length;
if (length > 0) {
int i = 0;
void invokeNext() {
closures[i]();
i++;
if (i < length) {
Timer.run(expectAsync(invokeNext));
}
}
Timer.run(expectAsync(invokeNext));
}
}