Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReactiveCommand doesn't seem to handle inital false state #32

Closed
alski opened this issue Aug 25, 2011 · 6 comments
Closed

ReactiveCommand doesn't seem to handle inital false state #32

alski opened this issue Aug 25, 2011 · 6 comments
Labels

Comments

@alski
Copy link

alski commented Aug 25, 2011

I have a UI where an empty text box prevents an OK button being clicked, but unfortunately it seems to be enabled until after you have set and cleared the textbox. After stripping it down and down I can still recreate the issue with code as simple as

 static void Main(string[] args)
{
    ReactiveCommand cmd = new ReactiveCommand(Observable.Return(false));
    Debug.Assert(cmd.CanExecute(null) == false);
}

Following the ReactiveCommand constructor in the source, it seems to be that the InitialValue is being set to true. Can you remember the reason for this? Is there anyway we can detect an initial value from the observable that we are watching?

@anaisbetts
Copy link
Member

So, the code below isn't surprising if you're outside of a unit test runner because we end up updating things on the Dispatcher - so, if you change something then instantly check for it, it's not up-to-date (in the unit test runner, the default Scheduler is changed so that tests like this are possible to write).

Can you show me your code that tries to do this, it should look something like (coding via Email ahead):

var theCmd = new ReactiveCommand(
this.WhenAny(x => x.TheTextBoxText, x => !String.IsNullOrWhitespace(x.Value)));

One big difference between WhenAny and ObservableForProperty, is that WhenAny sends a notification when you first set it up, so it solves the "initial state" problem, whereas with ObsForProp you would always have to tack on .StartWith(TheProperty)

Paul Betts paul@paulbetts.org

On Thursday, August 25, 2011 at 1:32 PM, alski wrote:

I have a UI where an empty text box prevents an OK button being clicked, but unfortunately it seems to be enabled until after you have set and cleared the textbox. After stripping it down and down I can still recreate the issue with code as simple as

 static void Main(string[] args)
{
 ReactiveCommand cmd = new ReactiveCommand(Observable.Return(false));
 Debug.Assert(cmd.CanExecute(null) == false);
}

Following the ReactiveCommand constructor in the source, it seems to be that the InitialValue is being set to true. Can you remember the reason for this? Is there anyway we can detect an initial value from the observable that we are watching?

Reply to this email directly or view it on GitHub:
https://github.com/xpaulbettsx/ReactiveUI/issues/32

@alski
Copy link
Author

alski commented Aug 26, 2011

OK, l think I might know what's wrong. I'm using nbehave to test with. Is that going to be recognised as a runner?

Just in case, my code is below including the debug Do()s. I'm sure it had a StartWith before :-)

AddCommand = new ReactiveCommand(
this.ObservableForProperty(x => x.NewIntention)
.Do(x=> Console.WriteLine("AddCommand: NewIntetnion={0}|{1}",x.Value,NewIntention))
.Select(x => String.IsNullOrEmpty(x.Value) == false)
.Do(x => Console.WriteLine("AddCommand: NewIntention is not blank {0}", x))
);

@anaisbetts
Copy link
Member

Not currently, but I'll add it. In the meantime, if you put at the top of your test:

RxApp.DeferredScheduler = Scheduler.Immediate;

That should unblock you

Paul Betts

SENT FROM MY COMMODORE 64: RESPONSES MAY BE IN ALL CAPS

On Aug 26, 2011, at 3:45, alskireply@reply.github.com wrote:

OK, l think I might know what's wrong. I'm using nbehave to test with. Is that going to be recognised as a runner?

AddCommand = new ReactiveCommand(
this.ObservableForProperty(x => x.NewIntention)
.Do(x=> Console.WriteLine("AddCommand: NewIntetnion={0}|{1}",x.Value,NewIntention))
.Select(x => String.IsNullOrEmpty(x.Value) == false)
.Do(x => Console.WriteLine("AddCommand: NewIntention is not blank {0}", x))
);

Reply to this email directly or view it on GitHub:
https://github.com/xpaulbettsx/ReactiveUI/issues/32#issuecomment-1911549

@alski
Copy link
Author

alski commented Aug 26, 2011

Ok, so if I add a referenec to nUnit and wrap my existing test code with

using NUnit.Framework;
...
[Test]
public void CanAddWhenNewIntentionIsNotBlank()
{
GivenANewProjectViewModel();
WhenMyProjectViewModelHasANewIntention("Hello world");
ThenMyProjectViewModelShouldBeAbleToAddANewIntention();
WhenMyProjectViewModelHasABlankNewIntention();
ThenMyProjectViewModelShouldNotBeAbleToAddANewIntention();
}

Then I can confirm that the tests pass in an NUnit Gui, via TestDriven.Net's Run Test and NBehave's Run Scenario.
Under TestDriven I get the message
Error: *** Detected Unit Test Runner, setting Scheduler to Immediate ***
Error: If we are not actually in a test runner, please file a bug

When I remove the [Test] everything works (except in nUnit Gui) which can't find a test (still getting the Error under TestDriven)

When I remove the [TestFixture] nBehave RunScenario fails independant of the fact the nUnit assemblies are still referenced. Would that imply because nUnit isn't actually used its not been loaded?

@alski alski closed this as completed Aug 26, 2011
@alski alski reopened this Aug 26, 2011
@alski
Copy link
Author

alski commented Aug 26, 2011

Could it be as simple as changing the code under RxApp.InUnitTestRunner() ? I agree with your comment, I can't think of a better way either.

@anaisbetts
Copy link
Member

Yes, assembly loading is lazy - the loaded assemblies list won't reflect referenced assemblies that aren't being used, so it won't be picked up

Paul Betts

SENT FROM MY COMMODORE 64: RESPONSES MAY BE IN ALL CAPS

On Aug 26, 2011, at 11:41, alskireply@reply.github.com wrote:

Ok, so if I add a referenec to nUnit and wrap my existing test code with

using NUnit.Framework;
...
[Test]
public void CanAddWhenNewIntentionIsNotBlank()
{
GivenANewProjectViewModel();
WhenMyProjectViewModelHasANewIntention("Hello world");
ThenMyProjectViewModelShouldBeAbleToAddANewIntention();
WhenMyProjectViewModelHasABlankNewIntention();
ThenMyProjectViewModelShouldNotBeAbleToAddANewIntention();
}

Then I can confirm that the tests pass in an NUnit Gui, via TestDriven.Net's Run Test and NBehave's Run Scenario.
Under TestDriven I get the message
Error: *** Detected Unit Test Runner, setting Scheduler to Immediate ***
Error: If we are not actually in a test runner, please file a bug

When I remove the [Test] everything works (except in nUnit Gui) which can't find a test (still getting the Error under TestDriven)

When I remove the [TestFixture] nBehave RunScenario fails (I'll pass this to them separately) independant of the fact the nUnit assemblies are still referenced. Would that imply because nUnit isn't actually used its not been loaded?

Reply to this email directly or view it on GitHub:
https://github.com/xpaulbettsx/ReactiveUI/issues/32#issuecomment-1915709

@lock lock bot added the outdated label Jun 26, 2019
@lock lock bot locked and limited conversation to collaborators Jun 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants