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

292 bug unexpected vm is created #294

Merged
merged 2 commits into from
Aug 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,27 @@ public <ViewType extends View<? extends ViewModelType>, ViewModelType extends Vi
throw new IOException("Could not load the controller for the View " + resource
+ " maybe your missed the fx:controller in your fxml?");
}


// the actually used ViewModel instance. We need this so we can return it in the ViewTuple
ViewModelType actualViewModel;


ViewModelType loadedViewModel = ViewLoaderReflectionUtils.getExistingViewModel(loadedController);

if (loadedViewModel == null) {
loadedViewModel = ViewLoaderReflectionUtils.createViewModel(loadedController);
// if no existing viewModel was provided...
if(viewModel == null) {
// ... we try to find the created ViewModel from the codeBehind.
// this is only possible when the codeBehind has a field for the VM and the VM was injected
actualViewModel = ViewLoaderReflectionUtils.getExistingViewModel(loadedController);

// otherwise we create a new ViewModel. This is needed because the ViewTuple has to contain a VM even if the codeBehind doesn't need one
if (actualViewModel == null) {
actualViewModel = ViewLoaderReflectionUtils.createViewModel(loadedController);
}
} else {
actualViewModel = viewModel;
}

return new ViewTuple<>(loadedController, loadedRoot, loadedViewModel);

return new ViewTuple<>(loadedController, loadedRoot, actualViewModel);

} catch (final IOException ex) {
throw new RuntimeException(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
package de.saxsys.mvvmfx.internal.viewloader;

import de.saxsys.mvvmfx.FluentViewLoader;
import de.saxsys.mvvmfx.MvvmFX;
import de.saxsys.mvvmfx.ViewTuple;
import de.saxsys.mvvmfx.internal.viewloader.example.*;
import de.saxsys.mvvmfx.testingutils.ExceptionUtils;
import de.saxsys.mvvmfx.testingutils.jfxrunner.JfxRunner;
import javafx.fxml.LoadException;
import javafx.scene.layout.VBox;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

Expand Down Expand Up @@ -341,4 +343,41 @@ public void testViewModelIsAvailableInViewTupleEvenIfItIsntInjectedInTheView() {
assertThat(viewTuple.getViewModel()).isNotNull();

}

/**
* This test reproduces the <a href="https://github.com/sialcasa/mvvmFX/issues/292">bug #292</a>
* Given the following conditions:
* 1. The View has no ViewModel field and not injection of the ViewModel.
* 2. While loading an existing ViewModel instance is passed to the {@link FluentViewLoader}
*
* Under this conditions the ViewLoader was still creating a new ViewModel instance or retrieved an instance
* from DI. This isn't expected because the user has passed an existing ViewModel instance into the ViewLoader.
*
*/
@Test
public void testExistingViewModelWithoutInjectionInView() {
DependencyInjector.getInstance().setCustomInjector(type -> {
if(type.equals(TestViewModel.class)) {
fail("An instance of TestViewModel was requested!");
throw new IllegalStateException("An instance of TestViewModel was requested!");
} else {
try {
return type.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
});


TestViewModel viewModel = new TestViewModel();

final ViewTuple<TestFxmlViewWithoutViewModelField, TestViewModel> viewTuple = FluentViewLoader
.fxmlView(TestFxmlViewWithoutViewModelField.class).viewModel(viewModel).load();

assertThat(viewTuple.getViewModel()).isEqualTo(viewModel);

// we need to reset the DI
DependencyInjector.getInstance().setCustomInjector(null);
}
}