private static void MyMethod2(Deferred<string, string> deferred, string obj) { Console.WriteLine(obj); Thread.Sleep(500); Console.WriteLine("thread awake"); deferred.Resolve(obj); }
static void Main(string[] args) { var promise = new Deferred<string, string>(MyMethod, "my promise").Promise().Done(SuccessCallback).Fail(FailCallback).Always(AlwaysCallback); var promise2 = new Deferred<string, string>(MyMethod2, "my promise").Promise().Done(SuccessCallback).Always(AlwaysCallback).Fail(FailCallback); Console.WriteLine("waiting a second ..."); Thread.Sleep(1000); promise2.Always((result) => { Console.WriteLine("deferred always"); }); Console.ReadLine(); }
static Promise<int>customProgressPromise(bool autoStart = false) { var deferred = new Deferred<int>(); deferred.action = () => { Thread.Sleep(500); var progress = 0f; while (progress < 1f) { progress += 0.01f; progress = Math.Min(1f, progress); deferred.Progress(progress); Thread.Sleep(7); } return 0; }; return autoStart ? deferred.RunAsync() : deferred.promise; }
private static void MyMethod(Deferred<string, string> deferred, string obj) { Console.WriteLine(obj); throw new Exception("real test exception"); deferred.Reject(new Exception("test exception")); }
void when_using_rescue() { Promise<string> promise = null; string eventResult = null; before = () => eventResult = null; after = () => promise.Await(); it["rescues failed promise"] = () => { promise = TestHelper.PromiseWithError<string>("error 42", delay).Rescue(error => "rescue"); promise.OnFulfilled += result => eventResult = result; promise.Await(); promise.state.should_be(PromiseState.Fulfilled); promise.progress.should_be(1f); promise.result.should_be("rescue"); promise.error.should_be_null(); eventResult.should_be("rescue"); }; it["fulfills when no error"] = () => { promise = TestHelper.PromiseWithResult("42", delay).Rescue(error => "rescue"); promise.OnFulfilled += result => eventResult = result; promise.Await(); Thread.SpinWait(0); promise.state.should_be(PromiseState.Fulfilled); promise.progress.should_be(1f); promise.result.should_be("42"); promise.error.should_be_null(); eventResult.should_be("42"); }; context["progress"] = () => { Deferred<string> deferred = null; var progressCalled = 0; var eventProgress = 0f; before = () => { eventProgress = 0f; progressCalled = 0; deferred = new Deferred<string>(); deferred.Progress(0.1f); promise = deferred.Rescue(error => "43"); promise.OnProgressed += progress => { eventProgress = progress; progressCalled++; }; }; it["forwards progress"] = () => { deferred.Progress(0.3f); deferred.Progress(0.6f); deferred.Fulfill("42"); eventProgress.should_be(1f); promise.progress.should_be(1f); progressCalled.should_be(3); }; it["has initial progress"] = () => { promise.progress.should_be(0.1f); deferred.Fulfill("42"); }; }; it["calculates correct progress when concatenating with then"] = () => { Func<string, string> p = result => { Thread.Sleep(delay); return "42"; }; Func<Exception, string> r = error => { Thread.Sleep(delay); return "error"; }; promise = TestHelper.PromiseWithResult("42", delay) .Then(p) .Then(p) .Then(p).Rescue(r); int eventCalled = 0; var expectedProgresses = new [] { 0.25f, 0.5f, 0.75f, 1f }; promise.OnProgressed += progress => { progress.should_be(expectedProgresses[eventCalled]); eventCalled++; }; promise.Await(); eventCalled.should_be(expectedProgresses.Length); }; }
void when_running_an_expensive_action() { Promise<string> promise = null; string eventResult = null; Exception eventError = null; float eventProgress = 0f; bool fulfilledCalled = false, failedCalled = false, progressCalled = false; before = () => { eventResult = null; eventError = null; eventProgress = -1f; fulfilledCalled = failedCalled = progressCalled = false; }; after = () => promise.Await(); context["before action finished"] = () => { before = () => { promise = TestHelper.PromiseWithResult("42", delay); promise.OnFulfilled += result => { eventResult = result; fulfilledCalled = true; }; promise.OnFailed += error => { eventError = error; failedCalled = true; }; promise.OnProgressed += progress => { eventProgress = progress; eventProgress = progress; }; }; it["is unfulfilled"] = () => promise.state.should_be(PromiseState.Unfulfilled); it["has progressed 0%"] = () => promise.progress.should_be(0f); it["has no result"] = () => promise.result.should_be_null(); it["has no error"] = () => promise.error.should_be_null(); it["has a background thread assigned"] = () => { promise.thread.should_not_be_null(); promise.thread.should_not_be(Thread.CurrentThread); promise.thread.IsBackground.should_be_true(); }; context["await"] = () => { it["blocks until finished"] = () => { promise.Await(); promise.thread.should_be_null(); promise.state.should_be(PromiseState.Fulfilled); }; it["does nothing when promise already finished"] = () => { promise.Await(); promise.Await(); true.should_be_true(); }; }; context["events"] = () => { it["doesn't call OnFulfilled"] = () => fulfilledCalled.should_be_false(); it["doesn't call OnFail"] = () => failedCalled.should_be_false(); it["doesn't call OnProgress"] = () => progressCalled.should_be_false(); }; context["when action finished"] = () => { before = () => promise.Await(); it["is fulfilled"] = () => promise.state.should_be(PromiseState.Fulfilled); it["has progressed 100%"] = () => promise.progress.should_be(1f); it["has result"] = () => promise.result.should_be("42"); it["has no error"] = () => promise.error.should_be_null(); it["has no thread assigned"] = () => promise.thread.should_be_null(); context["events"] = () => { it["calls OnFulfilled"] = () => eventResult.should_be("42"); it["calls OnFulfilled when adding callback"] = () => { string lateResult = null; promise.OnFulfilled += result => lateResult = result; lateResult.should_be("42"); }; it["doesn't call OnFailed"] = () => failedCalled.should_be_false(); it["doesn't call OnFailed when adding callback"] = () => { var called = false; promise.OnFailed += error => called = true; called.should_be_false(); }; it["calls OnProgress"] = () => eventProgress.should_be(1f); }; }; }; context["when action throws an exception"] = () => { before = () => { promise = TestHelper.PromiseWithError<string>("error 42", delay); promise.OnFulfilled += result => { eventResult = result; fulfilledCalled = true; }; promise.OnFailed += error => { eventError = error; failedCalled = true; }; promise.OnProgressed += progress => { eventProgress = progress; eventProgress = progress; }; promise.Await(); }; it["failed"] = () => promise.state.should_be(PromiseState.Failed); it["has progressed 0%"] = () => promise.progress.should_be(0f); it["has no result"] = () => promise.result.should_be_null(); it["has error"] = () => promise.error.Message.should_be("error 42"); it["has no thread assigned"] = () => promise.thread.should_be_null(); context["events"] = () => { it["doesn't call OnFulfilled"] = () => fulfilledCalled.should_be_false(); it["doesn't call OnFulfilled when adding callback"] = () => { var called = false; promise.OnFulfilled += result => called = true; called.should_be_false(); }; it["calls OnFailed"] = () => eventError.Message.should_be("error 42"); it["calls OnFailed when adding callback"] = () => { Exception lateError = null; promise.OnFailed += error => lateError = error; lateError.Message.should_be("error 42"); }; it["doesn't call OnProgress"] = () => progressCalled.should_be_false(); }; }; context["when creating a custom promise with Deferred"] = () => { Deferred<string> deferred = null; int progressEventCalled = 0; before = () => { deferred = new Deferred<string>(); progressEventCalled = 0; deferred.OnProgressed += progress => { eventProgress = progress; progressEventCalled++; }; }; it["progresses"] = () => { deferred.Progress(0.3f); deferred.Progress(0.6f); deferred.Progress(0.9f); deferred.Progress(1f); eventProgress.should_be(1f); deferred.promise.progress.should_be(1f); progressEventCalled.should_be(4); }; it["doesn't call OnProgressed when setting equal progress"] = () => { deferred.Progress(0.3f); deferred.Progress(0.3f); deferred.Progress(0.3f); deferred.Progress(0.6f); eventProgress.should_be(0.6f); deferred.promise.progress.should_be(0.6f); progressEventCalled.should_be(2); }; it["doesn't call OnProgressed when adding callback when progress is less than 100%"] = () => { deferred.Progress(0.3f); var called = false; deferred.OnProgressed += progress => called = true; called.should_be_false(); }; it["calls OnProgressed when adding callback when progress is 100%"] = () => { deferred.Progress(1f); var called = false; deferred.OnProgressed += progress => called = true; called.should_be_true(); }; }; context["wrap"] = () => { Promise<object> wrapped = null; context["when wrapped promise fulfills"] = () => { before = () => { }; it["forwards fulfill"] = () => { promise = TestHelper.PromiseWithResult("42", delay); wrapped = promise.Wrap<object>(); wrapped.Await(); wrapped.state.should_be(PromiseState.Fulfilled); }; it["forwards fail"] = () => { promise = TestHelper.PromiseWithError<string>("error 42", delay); wrapped = promise.Wrap<object>(); wrapped.Await(); wrapped.state.should_be(PromiseState.Failed); }; it["forwards progress"] = () => { var deferred = new Deferred<string>(); wrapped = deferred.Wrap<object>(); deferred.Progress(0.5f); wrapped.progress.should_be(0.5f); }; it["has initial progress"] = () => { var deferred = new Deferred<string>(); deferred.Progress(0.5f); wrapped = deferred.Wrap<object>(); wrapped.progress.should_be(0.5f); }; }; }; context["toString"] = () => { it["returns description of unfulfilled promise"] = () => { var deferred = new Deferred<string>(); deferred.Progress(0.1234567890f); deferred.promise.ToString().should_be("[Promise<String>: state = Unfulfilled, progress = 0,123]"); }; it["returns description of fulfilled promise"] = () => { promise = TestHelper.PromiseWithResult("42"); promise.Await(); promise.ToString().should_be("[Promise<String>: state = Fulfilled, result = 42]"); }; it["returns description of failed promise"] = () => { promise = TestHelper.PromiseWithError<string>("error 42"); promise.Await(); promise.ToString().should_be("[Promise<String>: state = Failed, progress = 0, error = error 42]"); }; }; }