Created
May 10, 2013 22:40
-
-
Save jopek/5557960 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[11:36pm] ChanServ: | |
[##gwt] Welcome to the unofficial Google Web Toolkit channel on freenode. This is a starting (and growing) community, and we need your help. Stick around! | |
[11:37pm] keex: | |
hello | |
[11:37pm] keex: | |
is there a way of injecting a Scheduler ? | |
[11:38pm] keex: | |
I now get Rebind result 'com.google.gwt.core.client.Scheduler' cannot be abstract after injecting the scheduler through the contractor... | |
[11:38pm] keex: | |
constructor | |
[11:39pm] keex: | |
of course, it IS abstract.. but how else do i inject it for internal use? | |
[11:39pm] keex: | |
i want to avoid using a GWTTestCase while unit testing | |
[11:42pm] Obsitos left the chat room. (Ping timeout: 256 seconds) | |
[11:42pm] niloc132: | |
what would your scheduler do, exactly? | |
[11:42pm] niloc132: | |
how would you implement the end of an event loop, or the next one? | |
[11:43pm] niloc132: | |
(also, isn't that "Rebind result xxx cannot be abstract" error something you only get when using GWTTestCases, not real ones?) | |
[11:44pm] keex: | |
the scheduler is only used for deferred execution | |
[11:44pm] keex: | |
Binder TextBox focus="true" broken: https://code.google.com/p/google-web-toolkit/issues/detail?id=6477 | |
[11:44pm] atomatom: | |
I'm not sure if this is useful, but I created a mock for Scheduler once when using gwt-test utils https://groups.google.com/forum/?fromgroups=#!searchin/gwt-test-utils-users/scheduler/gwt-test-utils-users/ueCbvdiUaRE/YJIUFLVa594J | |
[11:44pm] keex: | |
the exact same case | |
[11:45pm] keex: | |
giving a text box focus | |
[11:45pm] niloc132: | |
keex: how could TextBox work at all in a non-GWTTestCase, since it needs JSOs anyway | |
[11:45pm] niloc132: | |
Element, etc | |
[11:46pm] niloc132: | |
it'd make sense if it was already jvm compatible code, but widget is stuck in the non-jvm world thanks to Element and jsni methods | |
[11:46pm] keex: | |
in the test cases i would use the StubScheduler | |
[11:47pm] keex: | |
niloc132: unfortunately i am not that experienced yet to understand what you are talking about | |
[11:47pm] niloc132: | |
the purpose of GWTTestCase is to give the classes a 'browser-like' env to run in | |
[11:47pm] keex: | |
yes | |
[11:47pm] niloc132: | |
either by compiling to js and running in a browser, or using dev mode | |
[11:48pm] niloc132: | |
TextBox can't be used without dev or prod mode - you can't use TextBox in a standard TestCase, since it needs Element, etc to work | |
[11:48pm] niloc132: | |
and those need a browser to talk to | |
[11:48pm] niloc132: | |
i understand (and agree with) trying to avoid using GWTTestCase in some unit tests, but those tests must exclude all widgets and elements | |
[11:48pm] niloc132: | |
there are some mock tools that let you talk *about* a widget, but not actually test the widget itself | |
[11:49pm] niloc132: | |
but in those cases things like focus dont actually do anything | |
[11:49pm] keex: | |
…which is just what i want | |
[11:49pm] niloc132: | |
so you want a mocked TextBox, but insist on having a non-mocked Scheduler inside that TextBox? | |
[11:49pm] keex: | |
nonono | |
[11:49pm] keex: | |
let me explain | |
[11:49pm] niloc132: | |
ok, good :) i was very confused | |
[11:50pm] keex: | |
i use gwtp | |
[11:50pm] keex: | |
so there is a clear separation of each part: MVP ;) | |
[11:50pm] keex: | |
the view holds the textbox | |
[11:51pm] keex: | |
and the implementation itself isn't that important | |
[11:51pm] niloc132: | |
so far, so good | |
[11:51pm] keex: | |
i want the views to be as duuuumb as possible | |
[11:51pm] keex: | |
therefore i implement most controlling login inside the presenter | |
[11:52pm] keex: | |
the view has a method setFocus() | |
[11:53pm] keex: | |
the presenter runs through the lifecycle | |
[11:53pm] keex: | |
and when using the scheduler, i want the focus to be set AFTER rendering the textbox | |
[11:53pm] keex: | |
that's the basic idea | |
[11:54pm] keex: | |
therefore the deferred command is getView().setFocus() | |
[11:54pm] niloc132: | |
and the view can't be in charge of those tasks? or the presenter can't say "hey view, render, okay now focus" and the view do nothing? | |
[11:54pm] keex: | |
inside the presenter | |
[11:54pm] niloc132: | |
or your same mock tool can't mock the scheduler? | |
[11:54pm] keex: | |
preferrably not | |
[11:54pm] keex: | |
the scheduler CAN be mocked | |
[11:55pm] keex: | |
but the Scheduler is abstract | |
[11:55pm] niloc132: | |
just as you call @Inject instead of GWT.create to get the gwt out of your presenter code, you can inject the scheduler too | |
[11:55pm] keex: | |
thats what i tried | |
[11:55pm] keex: | |
crap | |
[11:55pm] keex: | |
BRB | |
[11:55pm] keex: | |
security is throwing me out the office | |
[11:55pm] keex: | |
i'm in very late | |
[11:55pm] keex: | |
brb | |
[11:55pm] niloc132: | |
haha, ok | |
[11:59pm] You left the chat by being disconnected from the server. | |
[12:00am] You reconnected to the server. | |
[12:00am] You rejoined the room. | |
[12:00am] ChanServ: | |
[##gwt] Welcome to the unofficial Google Web Toolkit channel on freenode. This is a starting (and growing) community, and we need your help. Stick around! | |
[12:02am] niloc132: | |
welcome back - as i understand reading back on your error, the issue is not in the test, but in getting the gwt stuff to use the real thing - hooking into Scheduler.get() with a provider should help there i think... | |
[12:04am] keex: | |
:) | |
[12:04am] keex: | |
back | |
[12:04am] niloc132: | |
when i say 'real' module, i mean the gin module that the compiled or dev mode app uses | |
[12:04am] niloc132: | |
bind(Scheduler.class).toProvider(MySchedulerSingletonProvider.class) | |
[12:04am] niloc132: | |
where that provider just returns Scheduler.get() | |
[12:04am] keex: | |
ok | |
[12:05am] niloc132: | |
i use gin a lot, but i dont use gwtp enough, so i might not be clear on where those boundaries lie | |
[12:05am] keex: | |
gwtp is not much different to gwt | |
[12:05am] keex: | |
so when it comes to gin it is the same | |
[12:05am] niloc132: | |
right, mostly convinient scaffolding around your app | |
[12:06am] keex: | |
right | |
[12:06am] niloc132: | |
i usually build my own mvp stuff off of just interfaces | |
[12:06am] keex: | |
i was thinking of using a SchedulerFactory interface | |
[12:06am] niloc132: | |
its lighter when i'm building small apps, but gets too adhoc for big ones, so i should do more with gwtp... | |
[12:06am] keex: | |
and binding it in gin "somehow" | |
[12:06am] niloc132: | |
that is what the Provider<Scheduler> would do | |
[12:06am] keex: | |
oh | |
[12:06am] keex: | |
ok | |
[12:06am] niloc132: | |
it *must* return the existing gwt scheduler instance | |
[12:07am] niloc132: | |
or else the running app will misbehave | |
[12:07am] niloc132: | |
by not running finally statements correctly, etc | |
[12:08am] keex: | |
so… do i simply inject a Provider<Scheduler> and thats it ? | |
[12:08am] niloc132: | |
no, you need the bind.toprovider to wire it up | |
[12:08am] keex: | |
yes, that's what i was afraid of ;) | |
[12:08am] niloc132: | |
then you can say @Inject Scheduler scheduler; and gin will call on your factory (aka provider) to see about getting the real instance | |
[12:08am] niloc132: | |
its the same as your original problem | |
[12:09am] niloc132: | |
we need to teach gin how to do @Inject Scheduler | |
[12:09am] niloc132: | |
i'll make a quick gist | |
[12:09am] keex: | |
yes, i suppose THAT is the essence of my problem | |
[12:11am] niloc132: | |
very roughly: https://gist.github.com/niloc132/5557812 | |
[12:11am] niloc132: | |
not tested in an ide, so it makes sense, but may or may not actually compile | |
[12:12am] niloc132: | |
no need to declare as a singleton (unless you want to) since Schduler.get() already returns a singleton | |
[12:13am] niloc132: | |
aaand updated https://gist.github.com/niloc132/5557812 | |
[12:13am] niloc132: | |
two different options, mutually exclusive, should behave the same | |
[12:13am] niloc132: | |
depends on your preferences for your gin wiring | |
[12:14am] keex: | |
is it necessary to use Provider / Proviedes? | |
[12:14am] niloc132: | |
one or the other, yeah, to tell gin that this isn't a typical binding | |
[12:14am] niloc132: | |
otherwise you can't point it at Scheduler.get() which has the One True Schduler | |
[12:14am] keex: | |
instead of using public class A { public interface A.Factory{ A create(); } } | |
[12:14am] niloc132: | |
its kinda like saying on the server "I can just make a new servlet instance and expect it to be init'd correctly" | |
[12:15am] niloc132: | |
erm, its the same thing - Provider is essentially the same idea as factory | |
[12:15am] keex: | |
i get confused with factories, providers and whatnot... | |
[12:15am] niloc132: | |
i think it is a more broad concept, at least thats how i see it | |
[12:15am] keex: | |
yes, but why are there solo many names for it? | |
[12:15am] keex: | |
ok | |
[12:16am] niloc132: | |
you can create a provider<T> and say @Inject T, or you can bind(T).to(...) and say @Inject Provider<T> | |
[12:16am] niloc132: | |
or you can do both, or you can do neither | |
[12:16am] niloc132: | |
i see assisted inject as closer to 'factory' | |
[12:19am] keex: | |
I'll try it out now | |
[12:19am] niloc132: | |
reading wikipedia's def of factory pattern, i think a @Provides methods is an abstract factory pattern, same as bind.toProvider - its all about how you create the objects on that side | |
[12:20am] niloc132: | |
on the consuming side, *every* 'give me something' call in guice/gin is either @Inject T or @Inject Provider<T> (or assisted inject), and the tool manages the rest of the dependencies | |
[12:25am] keex: | |
i like the brevity of option 2 | |
[12:25am] keex: | |
i'm trying that first ;) | |
[12:26am] tdebat left the chat room. (Quit: tdebat) | |
[12:26am] niloc132: | |
i like brevity, but i also like it when the class is reusable for later projects, and not cluttering up the module | |
[12:26am] niloc132: | |
i think i'd go option 2 though too | |
[12:27am] keex: | |
the provideScheduler is used INSIDE the module ? | |
[12:27am] niloc132: | |
interestingly, yes | |
[12:27am] keex: | |
so, how is it used in the using class ? | |
[12:27am] niloc132: | |
the @Provides methods are the only one of the module that actually get invoked when the app is running | |
[12:27am] Essington: | |
The thing about providers is they help with code splitting .... | |
[12:28am] niloc132: | |
if I say @Inject Scheduler s;, gin looks for a scheduler binding, and it finds this rule, so it calls that method to get the instance | |
[12:28am] niloc132: | |
AsyncProviders can help with splitting, if used well, but Providers do nothing for splitting (unless inside a splitpoint already i guess) | |
[12:28am] Essington: | |
well ... | |
[12:29am] Essington: | |
true | |
[12:29am] Essington: | |
but if you are already in the mindset of using that pattern, ... | |
[12:29am] niloc132: | |
right, that's true | |
[12:29am] niloc132: | |
but a scheduler is never something you'd need/want to split | |
[12:30am] Essington: | |
right | |
[12:30am] niloc132: | |
and the crux of this issue is 'how to i expose core gwt classes as if they were owned by gin/guice' | |
[12:30am] Essington: | |
did I mention that I can't be arsed to use my scrollback? | |
[12:30am] niloc132: | |
hahaha | |
[12:30am] keex: | |
niloc132: I LOVE YOU ! | |
[12:30am] niloc132: | |
you might've, i didn't scroll back to check | |
[12:30am] keex: | |
it works! | |
[12:30am] niloc132: | |
glad it worked out keex, go home and sleep ;) | |
[12:30am] keex: | |
:D | |
[12:30am] keex: | |
i am solo happy right now | |
[12:31am] Essington: | |
wait, why would you want to ginject scheduler anyway? | |
[12:31am] keex: | |
jenkins will run without a build failure again :) | |
[12:31am] niloc132: | |
allow your presenter (which uses it) to be tested in a jvm testcase, not gwttestcase | |
[12:31am] niloc132: | |
his use case, not mine | |
[12:31am] keex: | |
exactly | |
[12:31am] Essington: | |
scheduler does GWT.create() | |
[12:31am] Essington: | |
? | |
[12:31am] niloc132: | |
jvm test case then can mock it i guess or provide a realish imp | |
[12:31am] Essington: | |
huh | |
[12:32am] niloc132: | |
impl | |
[12:32am] niloc132: | |
Schedule.get() uses GWT.create(SchedulerImpl.class) to get the one true instance | |
[12:32am] Essington: | |
already then | |
[12:33am] niloc132: | |
the goal is to avoid Scheduler.get() in the presenter (i.e. jvm-able) code, and just use @Inject instead | |
[12:33am] • Essington | |
nods | |
[12:33am] keex: | |
to recap: the module looks up the methods annotated with @Provides with a certain return value/type and uses THAT first to instantiate the injected classes, right ? | |
[12:33am] keex: | |
…inside the module | |
[12:33am] niloc132: | |
it builds a bind.toprovider rule out of that method implicitly | |
[12:33am] niloc132: | |
right | |
[12:34am] keex: | |
haaa :) | |
[12:34am] niloc132: | |
so its a matter of style in some cases (and state in others...) whether you bind.toprovider or @Provides | |
[12:34am] cbrock_ joined the chat room. | |
[12:35am] cbrock_ left the chat room. (Remote host closed the connection) | |
[12:35am] keex: | |
next i will try the bind.toProvider() - some other tme | |
[12:35am] keex: | |
time | |
[12:35am] keex: | |
are you leavingg the gist up for eternity ? | |
[12:35am] keex: | |
or removing it some day? | |
[12:36am] niloc132: | |
i'll leave it up forever | |
[12:36am] keex: | |
:) | |
[12:36am] keex: | |
thank you once again ! | |
[12:37am] niloc132: | |
np | |
[12:38am] cbrock left the chat room. (Ping timeout: 276 seconds) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment