Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 370740 - [xtext][test] single generated injector provider
Summary: [xtext][test] single generated injector provider
Status: CLOSED WONTFIX
Alias: None
Product: TMF
Classification: Modeling
Component: Xtext (show other bugs)
Version: 2.3.0   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-06 11:24 EST by Knut Wannheden CLA
Modified: 2017-09-19 18:14 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Knut Wannheden CLA 2012-02-06 11:24:14 EST
Currently there are two IInjectorProvider classes generated into the test project when executing the workflow. One to be used for simple JUnit tests and the other for plug-in JUnit tests. It seems to me that it should be possible to generate a single injector provider class which at runtime checks if the test is running as a normal or a plug-in unit test and acts accordingly.

Please close the issue again if I missed something.
Comment 1 Karsten Thoms CLA 2012-02-06 12:57:06 EST
Even further, they should normally be in two different plugins. A runtime test should be executable without UI dependencies, but if I want UI tests, they should be reside in a plugin test project.
Comment 2 Moritz Eysholdt CLA 2012-02-07 03:18:21 EST
(In reply to comment #0)
> Currently there are two IInjectorProvider classes generated into the test
> project when executing the workflow. One to be used for simple JUnit tests and
> the other for plug-in JUnit tests. It seems to me that it should be possible to
> generate a single injector provider class which at runtime checks if the test
> is running as a normal or a plug-in unit test and acts accordingly.
> 
> Please close the issue again if I missed something.

The runtime-InjectorProvider currently implements IRegistryConfigurator, the UI-InjectorProvider does not.

Besides that, I like the idea of this simplification.

(In reply to comment #1)
> Even further, they should normally be in two different plugins. A runtime test
> should be executable without UI dependencies, but if I want UI tests, they
> should be reside in a plugin test project.

That feels overengineered. Since the test projects are not being shipped/deployed anywhere, I don't see the need to be extra careful about their dependency footprint.
Comment 3 Knut Wannheden CLA 2012-02-07 04:13:27 EST
(In reply to comment #2)
> The runtime-InjectorProvider currently implements IRegistryConfigurator, the
> UI-InjectorProvider does not.

It should be possible to implement the IRegistryConfigurator operations as no-ops if the test is run as a Plug-In test. This decision would of course be based on the same logic as used in getInjector().
Comment 4 Moritz Eysholdt CLA 2012-02-14 13:48:35 EST
(In reply to comment #3)
> (In reply to comment #2)
> > The runtime-InjectorProvider currently implements IRegistryConfigurator, the
> > UI-InjectorProvider does not.
> 
> It should be possible to implement the IRegistryConfigurator operations as
> no-ops if the test is run as a Plug-In test. This decision would of course be
> based on the same logic as used in getInjector().

yes, indeed. I just tried this for a customers project:

-----
public class FooInjectorProvider implements IInjectorProvider, IRegistryConfigurator {
  protected GlobalStateMemento globalStateMemento;
  protected Injector injector;

  static {
    GlobalRegistries.initializeDefaults();
  }

  public Injector getInjector() {
    FooActivator instance = FooActivator.getInstance();
    if (instance != null)
      return instance.getInjector("com.jci.instancer.Foo.Foo");
    if (injector == null) {
      this.injector = new FooStandaloneSetup().createInjectorAndDoEMFRegistration();
    }
    return injector;
  }

  public void restoreRegistry() {
    FooActivator instance = FooActivator.getInstance();
    if (instance == null)
      globalStateMemento.restoreGlobalState();
  }

  public void setupRegistry() {
    FooActivator instance = FooActivator.getInstance();
    if (instance == null) {
      globalStateMemento = GlobalRegistries.makeCopyOfGlobalState();
      if (injector != null)
        new FooStandaloneSetup().register(injector);
    }
  }
}
-----


The InjectorProvider works flawlessly...but the tests don't.

As it turns out, the RuntimeInjector can't be replaced so easily by the UIInjector. Example: The RuntimeInjector configures a TypeProvider that can load types via a classloader... the UIInjector on the other hand configures a TypeProvider which delegates to the JDT and therefore expects a workspace and a JavaProject. Consequently, the tests need different kinds of setups depending on which injector is being used.
Comment 5 Knut Wannheden CLA 2012-02-15 13:20:06 EST
(In reply to comment #4)
> As it turns out, the RuntimeInjector can't be replaced so easily by the
> UIInjector. Example: The RuntimeInjector configures a TypeProvider that can
> load types via a classloader... the UIInjector on the other hand configures a
> TypeProvider which delegates to the JDT and therefore expects a workspace and a
> JavaProject. Consequently, the tests need different kinds of setups depending
> on which injector is being used.

A test that relies on services which are only available in Eclipse environment must always be executed as a plug-in test. That fact is of course not changed by having a single injector provider.

But if I understand you correctly you claim that a test which works with the runtime injector may fail when executed with the UI injector? That would of course be a problem with the proposed change.
Comment 6 Karsten Thoms CLA 2012-02-16 04:47:18 EST
> That feels overengineered. Since the test projects are not being
> shipped/deployed anywhere, I don't see the need to be extra careful about their
> dependency footprint.

I usually go with runtime tests as far as possible, and don't want to have UI dependencies in my build until really needed. Maybe the generation of the UI specific injection provider should be configurable for the Junit4Fragment.
Comment 7 Sebastian Zarnekow CLA 2012-02-16 06:17:44 EST
(In reply to comment #6)
> I usually go with runtime tests as far as possible, and don't want to have UI
> dependencies in my build until really needed. Maybe the generation of the UI
> specific injection provider should be configurable for the Junit4Fragment.

It's unlikely that we'll add such a configuration flag. Clients can always remove the JUnit4Fragment from their workflow and use whatever Injector Project implementation or project dependency settings they want. However, we should not bother every user with such things.
Comment 8 Sebastian Zarnekow CLA 2012-02-28 10:05:24 EST
I'm inclined to close this as won't fix since tests that are written for a runtime testcase cannot run as ui test[*] and vice versa thus the selection of the correct injector provider is not transparent to the user.

* the ui injector binds certain services to implementations that assume a resource to be located in an IJavaProject where the runtime injector simply uses the classpath of the current vm. Tests that are written with the runtime injector in mind will not set up such a project and will fail when executed as plugin test.

Please reopen if there are solutions that did not came to my mind.
Comment 9 Karsten Thoms CLA 2017-09-19 18:04:10 EDT
Closing all bugs that were set to RESOLVED before Neon.0
Comment 10 Karsten Thoms CLA 2017-09-19 18:14:13 EDT
Closing all bugs that were set to RESOLVED before Neon.0