I'm pretty sure this won't work, but…
I have been trying to get Sinon.js-like stubbing working in Dart. I wonder if I can simply use Sinon.js via js-interop? I have the feeling that this will not work in Dartium (or
content_shell from the command line) because Dart is directly using the native implementation of HttpRequest built into the browser.Still, it seems worth a shot.
So I grab the latest sinon.js and install it in Hipster MVC's
test directory:➜ test git:(http-test-server) wget http://sinonjs.org/releases/sinon-1.7.3.js 2013-07-10 21:16:52 (109 KB/s) - `sinon-1.7.3.js' saved [132684/132684]I will need js-interop, which now involves two changes: installation via Dart Pub and updating the test's web page context to support it.
Installing js-interop via pub is a simple matter of updating my pubspec.yaml to include
js as a dependency, which… Hipster MVC already includes:name: hipster_mvc version: 0.2.6 description: Dart-based MVC framework author: Chris Strom <chris@eeecomputes.com> homepage: https://github.com/eee-c/hipster-mvc dependencies: unittest: any dirty: any uuid: any js: anyThat should probably be
browser: any instead of js: any. Up until this point, I have not included js-interop in Hipster MVC. My guess is that I included the js package from back before it was js-interop (I am not sure if that was ever actually the case) or if I mistakenly included it in an effort to get the browser library, which aids in Dart support in browsers that do not support Dart natively. Anyhow, I update my
pubspec.yaml to explicitly depend on browser:name: hipster_mvc version: 0.2.6 description: Dart-based MVC framework author: Chris StromAnd then pub install:homepage: https://github.com/eee-c/hipster-mvc dependencies: browser: any unittest: any dirty: any uuid: any js: any
➜ hipster-mvc git:(http-test-server) ✗ pub update Resolving dependencies........... Dependencies updated!That should change nothing since the js library depends on browser. I just prefer to be explicit about my dependencies.
The other change that I need for js-interop is to include the iterop.js file which is, oddly enough, included in the browser package. I add the
<script> tag for browser/interop to my test/index.html context page, along with sinon.js:<html>
<head>
<title>Hipster Test Suite</title>
<script type="application/dart" src="hipster_mvc_test.dart"></script>
<script type='text/javascript'>
// Code to notify the test runner when all tests are done....
</script>
<script src="packages/browser/dart.js"></script>
<script src="packages/browser/interop.js"></script>
<script src="sinon-1.7.3.js"></script>
</head>
<body>
</body>
</html>I next need to import the js-interop library into my test script:library hipster_mvc_test; import 'package:unittest/unittest.dart'; import 'dart:html'; import 'dart:async'; import 'dart:json' as JSON; import 'package:js/js.dart' as js; //...That will allow me to reference JavaScript files under the
js. prefix in Dart. I do so in the setUp() block of my test: group("HTTP get", (){
var server;
setUp(() {
server = js.context.sinon.fakeServer.create();
server.respondWith(
'[{ "id": 12, "comment": "Hey there" }]'
);
});
// test here...
});I am explicitly using the string response version of Sinon's fake server to avoid the need to convert Dart HashMaps and Lists to JavaScript objects and arrays. If I get this working with the simplest approach, then I will worry about that. In JavaScript, the above would replace the XMLHttpRequest object with a fake version that will respond to all requests with the specified JSON string. To see if Dart is using that same XMLHttpRequest object, I write my test as:
group("HTTP get", (){
var server;
setUp(() { /* ... */ });
test("it can parse responses", (){
var model = new FakeModel()
..url = '/test';
HipsterSync.
call('get', model).
then(
expectAsync1((response) {
expect(response, containsPair('comment', 'Hey there'));
})
);
server.respond();
});
});This code works when hitting against a real server. The only change here is the addition of Sinon's server.respond(), which will respond to all XHR requests that have been made in my test.Unfortunately, this does not work.
I never do see that response come back. I play around a bit with Sinon options. I set
autoRespond to true. I set the URL to an http:// version instead. I even add console.log() statements directly to my copy of sinon.js. But I get no joy.I can verify that the JavaScript XMLHttpRequest object is replaced:

But, Dart is, it would seem, by-passing this object to get to the native XHR object. That's good for Dart, but it stinks for my purposes tonight.
Just for giggles, I try compiling my test to JavaScript and running it from a normal Chrome browser. I get the following stacktrace:
FAIL: Hipster Sync HTTP get it can parse responses Caught NoSuchMethodError : method not found: 'Object #<JSUnknown> has no method '$$dom_addEventListener$3'' Receiver: "" Arguments: [] TypeError: Object #<JSUnknown> has no method '$$dom_addEventListener$3' $.$$dom_addEventListener$3$x file:///home/chris/repos/hipster-mvc/test/hipster_mvc_test.dart.js 18979:39 hipster_sync_tests___closure6.call$0 file:///home/chris/repos/hipster-mvc/test/hipster_mvc_test.dart.js 13852:9 TestCase.testFunction$0 file:///home/chris/repos/hipster-mvc/test/hipster_mvc_test.dart.js 16052:30I try passing a Dart callback to Sinon's
respondWith() on the off chance that this is what it is “JSUnknown”: setUp(() {
server = js.context.sinon.fakeServer.create();
var cb = new js.Callback.once((req) {
req.respond(200, [], '{ "id": 12, "comment": "Hey there" }');
});
server.respondWith(cb);
});But that has no effect upon recompilation. Ah well, it was a long shot to begin with. With definitive proof that overriding JavaScript's XMLHttpRequest will have no effect on my Dart tests, I can move onto other avenues of exploration. Tomorrow.
Day #808
No comments:
Post a Comment