- From: Dave Longley <dlongley@digitalbazaar.com>
- Date: Thu, 19 Jun 2014 12:20:17 -0400
- To: Tomasz Pluskiewicz <tomasz@t-code.pl>
- CC: public-linked-json@w3.org
Hi Tom, There were several problems with the fiddle. I've updated it to something that works [1] with some caveats. So, first, in the original fiddle, there were some trivial problems: 1. Setting jsonld.documentLoader was commented out. 2. The loader did not return anything (it needed to return a promise). Then, there were more complicated problems: The JSON-LD API is asynchronous and, for whatever reason, Jasmine/AngularJS-mocks is not playing nicely with it. This results in a variety of issues: 1. In order for the promise returned by $http.get() to get resolved, you must call $httpBackend.flush() -- but you must only do so *after* $http.get() has been called. Since you don't know which turn of the event loop the document loader will be called on, you can't do this easily. That means either breaking some abstractions and passing $httpBackend to an initialization method on the controller or setting some vars and calling wait functions to watch for them to change. It's a mess. To be clear: when you call promises.expand(), it, in effect, "schedules" the expansion algorithm to be run later and returns immediately. Similarly scheduling occurs with the document loader at some later point. That means that when the TestController constructor returns (and therefore, when beforeEach returns), none of the URL loading/expansion/etc. has been called yet. 2. Promises that are external to Jasmine and AngularJS-mocks don't seem to get resolved. This may be due to whatever Jasmine/AngularJS-mocks tries to do to manage scheduling when various bits of JS are run. Since it doesn't have control over external APIs (eg: JSON-LD), however, this is causing some kind of interference with its normal operation. If you replace the JSON-LD promises API with a callback-based one, as I have in the fiddle link [1], then everything works just fine. I don't know enough about/haven't explored the internals of Jasmine or AngularJS-mocks to figure out exactly what's going on here. It may be that the real solution lies in using some different tools -- either something that is intended to make Jasmine work with promises (see jasmine-as-promised [2]) or with some entirely different test suite that plays more nicely (maybe mocha). Anyway, with some really ugly hacks, that fiddle works now. -Dave [1] http://jsfiddle.net/R5acr/13/ [2] https://www.npmjs.org/package/jasmine-as-promised On 06/19/2014 07:23 AM, Tomasz Pluskiewicz wrote: > On Thu, Jun 19, 2014 at 1:10 AM, Dave Longley > <dlongley@digitalbazaar.com> wrote: >> On 06/18/2014 05:20 PM, Tomasz Pluskiewicz wrote: >>> Hi >>> >>> I'm trying to use the jsonld with Angular and in tests I want to >>> replace the default documentLoader with $http service so that I can >>> mock the responses. >>> >>> I assumed that because $http already returns a promise it would be >>> enough to simply use a function like >>> >>> jsonld.documentLoader = function (url) { >>> return $http.get(url); >>> } >>> >>> as replacement for whatever is currently set. >>> >>> Unfortunately it doesn't work. What's would be correct way to do that? >> >> That's because the value that promise resolves to isn't what is required >> by the JSON-LD API spec. It requires that the promise resolve to a >> "RemoteDocument": >> >> http://www.w3.org/TR/json-ld-api/#idl-def-RemoteDocument >> >> I didn't test this, but it should be pretty close to what you want: >> >> jsonld.documentLoader = function(url) { >> return $http.get(url).then(function(response) { >> return { >> contextUrl: null, >> document: response.data, >> documentUrl: url >> } >> }); >> }; >> >> Hopefully that works for you. >> > > Unfortunately it's not that easy. I'm not very experienced with > JavaScript or Angular. I created a fiddle [1] similar to my failing > code. > > As is, XHR fails, because it's a CORS request. If you uncomment the > two lines two weird things happen (or don't happen). First, $http mock > fails saying there aren't any pending requests and none of the > console.log called in callbacks are invoked. Which is weird, because > it means that even the $http promise is never resolved. I tried to > debug it but I get lost somewhere inside jsonld/angular. Also there > isn't any other exception being caught bu Chrome dev tools. > > Any ideas? Hasn't someone already done that? > > Thanks, > Tom > > [1] http://jsfiddle.net/tpluscode/R5acr/12/ > >> >> -Dave >> >> -- >> Dave Longley >> CTO >> Digital Bazaar, Inc. >> > > -- Dave Longley CTO Digital Bazaar, Inc.
Received on Thursday, 19 June 2014 16:20:43 UTC