Skip to content

Commit 74caddb

Browse files
Merge pull request #2 from benjchristensen/language-adaptors
Language adaptors
2 parents d297bef + ef6dd02 commit 74caddb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1344
-241
lines changed

gradle/doclet-exclude.jar

3.23 KB
Binary file not shown.

gradle/javadocStyleSheet.css

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# originally from http://sensemaya.org/files/stylesheet.css and then modified
2+
# http://sensemaya.org/maya/2009/07/10/making-javadoc-more-legible
3+
4+
/* Javadoc style sheet */
5+
6+
/* Define colors, fonts and other style attributes here to override the defaults */
7+
8+
/* Page background color */
9+
body { background-color: #FFFFFF; color:#333; font-size: 100%; }
10+
11+
body { font-size: 0.875em; line-height: 1.286em; font-family: "Helvetica", "Arial", sans-serif; }
12+
13+
code { color: #777; line-height: 1.286em; font-family: "Consolas", "Lucida Console", "Droid Sans Mono", "Andale Mono", "Monaco", "Lucida Sans Typewriter"; }
14+
15+
a { text-decoration: none; color: #16569A; /* also try #2E85ED, #0033FF, #6C93C6, #1D7BBE, #1D8DD2 */ }
16+
a:hover { text-decoration: underline; }
17+
18+
19+
table[border="1"] { border: 1px solid #ddd; }
20+
table[border="1"] td, table[border="1"] th { border: 1px solid #ddd; }
21+
table[cellpadding="3"] td { padding: 0.5em; }
22+
23+
font[size="-1"] { font-size: 0.85em; line-height: 1.5em; }
24+
font[size="-2"] { font-size: 0.8em; }
25+
font[size="+2"] { font-size: 1.4em; line-height: 1.3em; padding: 0.4em 0; }
26+
27+
/* Headings */
28+
h1 { font-size: 1.5em; line-height: 1.286em;}
29+
h2.title { color: #c81f08; }
30+
31+
/* Table colors */
32+
.TableHeadingColor { background: #ccc; color:#444; } /* Dark mauve */
33+
.TableSubHeadingColor { background: #ddd; color:#444; } /* Light mauve */
34+
.TableRowColor { background: #FFFFFF; color:#666; font-size: 0.95em; } /* White */
35+
.TableRowColor code { color:#000; } /* White */
36+
37+
/* Font used in left-hand frame lists */
38+
.FrameTitleFont { font-size: 100%; }
39+
.FrameHeadingFont { font-size: 90%; }
40+
.FrameItemFont { font-size: 0.9em; line-height: 1.3em;
41+
}
42+
/* Java Interfaces */
43+
.FrameItemFont a i {
44+
font-style: normal; color: #16569A;
45+
}
46+
.FrameItemFont a:hover i {
47+
text-decoration: underline;
48+
}
49+
50+
51+
/* Navigation bar fonts and colors */
52+
.NavBarCell1 { background-color:#E0E6DF; } /* Light mauve */
53+
.NavBarCell1Rev { background-color:#16569A; color:#FFFFFF} /* Dark Blue */
54+
.NavBarFont1 { }
55+
.NavBarFont1Rev { color:#FFFFFF; }
56+
57+
.NavBarCell2 { background-color:#FFFFFF; color:#000000}
58+
.NavBarCell3 { background-color:#FFFFFF; color:#000000}
59+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apply plugin: 'java'
2+
dependencies {
3+
compile project(':rxjava-core')
4+
compile 'org.codehaus.groovy:groovy:1.8.8'
5+
provided 'junit:junit:4.10'
6+
provided 'org.mockito:mockito-core:1.9.5'
7+
}
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/**
2+
* Copyright 2013 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.rx.lang.groovy;
17+
18+
import static org.mockito.Matchers.*;
19+
import static org.mockito.Mockito.*;
20+
import groovy.lang.Binding;
21+
import groovy.lang.Closure;
22+
import groovy.lang.GroovyClassLoader;
23+
24+
import java.util.Arrays;
25+
26+
import org.codehaus.groovy.runtime.InvokerHelper;
27+
import org.junit.Before;
28+
import org.junit.Test;
29+
import org.mockito.Mock;
30+
import org.mockito.MockitoAnnotations;
31+
import org.rx.functions.FunctionLanguageAdaptor;
32+
import org.rx.reactive.Notification;
33+
import org.rx.reactive.Observable;
34+
import org.rx.reactive.Observer;
35+
import org.rx.reactive.Subscription;
36+
37+
public class GroovyAdaptor implements FunctionLanguageAdaptor {
38+
39+
@Override
40+
public Object call(Object function, Object[] args) {
41+
return ((Closure<?>) function).call(args);
42+
}
43+
44+
public Class<?> getFunctionClass() {
45+
return Closure.class;
46+
}
47+
48+
public static class UnitTest {
49+
50+
@Mock
51+
ScriptAssertion assertion;
52+
53+
@Mock
54+
Observer<Integer> w;
55+
56+
@Before
57+
public void before() {
58+
MockitoAnnotations.initMocks(this);
59+
}
60+
61+
@Test
62+
public void testCreateViaGroovy() {
63+
runGroovyScript("o.create({it.onNext('hello');it.onCompleted();}).subscribe({ result -> a.received(result)});");
64+
verify(assertion, times(1)).received("hello");
65+
}
66+
67+
@Test
68+
public void testFilterViaGroovy() {
69+
runGroovyScript("o.filter(o.toObservable(1, 2, 3), {it >= 2}).subscribe({ result -> a.received(result)});");
70+
verify(assertion, times(0)).received(1);
71+
verify(assertion, times(1)).received(2);
72+
verify(assertion, times(1)).received(3);
73+
}
74+
75+
@Test
76+
public void testLast() {
77+
String script = "mockApiCall.getObservable().last().subscribe({ result -> a.received(result)});";
78+
runGroovyScript(script);
79+
verify(assertion, times(1)).received("hello_1");
80+
}
81+
82+
@Test
83+
public void testMap() {
84+
String script = "mockApiCall.getObservable().map({v -> 'say' + v}).subscribe({ result -> a.received(result)});";
85+
runGroovyScript(script);
86+
verify(assertion, times(1)).received("sayhello_1");
87+
}
88+
89+
@Test
90+
public void testMapViaGroovy() {
91+
runGroovyScript("o.map(o.toObservable(1, 2, 3), {'hello_' + it}).subscribe({ result -> a.received(result)});");
92+
verify(assertion, times(1)).received("hello_" + 1);
93+
verify(assertion, times(1)).received("hello_" + 2);
94+
verify(assertion, times(1)).received("hello_" + 3);
95+
}
96+
97+
@Test
98+
public void testMaterializeViaGroovy() {
99+
runGroovyScript("o.materialize(o.toObservable(1, 2, 3)).subscribe({ result -> a.received(result)});");
100+
// we expect 4 onNext calls: 3 for 1, 2, 3 ObservableNotification.OnNext and 1 for ObservableNotification.OnCompleted
101+
verify(assertion, times(4)).received(any(Notification.class));
102+
verify(assertion, times(0)).error(any(Exception.class));
103+
}
104+
105+
@Test
106+
public void testMergeDelayErrorViaGroovy() {
107+
runGroovyScript("o.mergeDelayError(o.toObservable(1, 2, 3), o.merge(o.toObservable(6), o.error(new NullPointerException()), o.toObservable(7)), o.toObservable(4, 5)).subscribe({ result -> a.received(result)}, { exception -> a.error(exception)});");
108+
verify(assertion, times(1)).received(1);
109+
verify(assertion, times(1)).received(2);
110+
verify(assertion, times(1)).received(3);
111+
verify(assertion, times(1)).received(4);
112+
verify(assertion, times(1)).received(5);
113+
verify(assertion, times(1)).received(6);
114+
verify(assertion, times(0)).received(7);
115+
verify(assertion, times(1)).error(any(NullPointerException.class));
116+
}
117+
118+
@Test
119+
public void testMergeViaGroovy() {
120+
runGroovyScript("o.merge(o.toObservable(1, 2, 3), o.merge(o.toObservable(6), o.error(new NullPointerException()), o.toObservable(7)), o.toObservable(4, 5)).subscribe({ result -> a.received(result)}, { exception -> a.error(exception)});");
121+
// executing synchronously so we can deterministically know what order things will come
122+
verify(assertion, times(1)).received(1);
123+
verify(assertion, times(1)).received(2);
124+
verify(assertion, times(1)).received(3);
125+
verify(assertion, times(0)).received(4); // the NPE will cause this sequence to be skipped
126+
verify(assertion, times(0)).received(5); // the NPE will cause this sequence to be skipped
127+
verify(assertion, times(1)).received(6); // this comes before the NPE so should exist
128+
verify(assertion, times(0)).received(7);// this comes in the sequence after the NPE
129+
verify(assertion, times(1)).error(any(NullPointerException.class));
130+
}
131+
132+
@Test
133+
public void testScriptWithMaterialize() {
134+
String script = "mockApiCall.getObservable().materialize().subscribe({ result -> a.received(result)});";
135+
runGroovyScript(script);
136+
// 2 times: once for hello_1 and once for onCompleted
137+
verify(assertion, times(2)).received(any(Notification.class));
138+
}
139+
140+
@Test
141+
public void testScriptWithMerge() {
142+
String script = "o.merge(mockApiCall.getObservable(), mockApiCall.getObservable()).subscribe({ result -> a.received(result)});";
143+
runGroovyScript(script);
144+
verify(assertion, times(1)).received("hello_1");
145+
verify(assertion, times(1)).received("hello_2");
146+
}
147+
148+
@Test
149+
public void testScriptWithOnNext() {
150+
String script = "mockApiCall.getObservable().subscribe({ result -> a.received(result)})";
151+
runGroovyScript(script);
152+
verify(assertion).received("hello_1");
153+
}
154+
155+
@Test
156+
public void testSkipTakeViaGroovy() {
157+
runGroovyScript("o.skip(o.toObservable(1, 2, 3), 1).take(1).subscribe({ result -> a.received(result)});");
158+
verify(assertion, times(0)).received(1);
159+
verify(assertion, times(1)).received(2);
160+
verify(assertion, times(0)).received(3);
161+
}
162+
163+
@Test
164+
public void testSkipViaGroovy() {
165+
runGroovyScript("o.skip(o.toObservable(1, 2, 3), 2).subscribe({ result -> a.received(result)});");
166+
verify(assertion, times(0)).received(1);
167+
verify(assertion, times(0)).received(2);
168+
verify(assertion, times(1)).received(3);
169+
}
170+
171+
@Test
172+
public void testTakeViaGroovy() {
173+
runGroovyScript("o.take(o.toObservable(1, 2, 3), 2).subscribe({ result -> a.received(result)});");
174+
verify(assertion, times(1)).received(1);
175+
verify(assertion, times(1)).received(2);
176+
verify(assertion, times(0)).received(3);
177+
}
178+
179+
@Test
180+
public void testToSortedList() {
181+
runGroovyScript("mockApiCall.getNumbers().toSortedList().subscribe({ result -> a.received(result)});");
182+
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5));
183+
}
184+
185+
@Test
186+
public void testToSortedListStatic() {
187+
runGroovyScript("o.toSortedList(o.toObservable(1, 3, 2, 5, 4)).subscribe({ result -> a.received(result)});");
188+
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5));
189+
}
190+
191+
@Test
192+
public void testToSortedListWithFunction() {
193+
runGroovyScript("mockApiCall.getNumbers().toSortedList({a, b -> a - b}).subscribe({ result -> a.received(result)});");
194+
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5));
195+
}
196+
197+
@Test
198+
public void testToSortedListWithFunctionStatic() {
199+
runGroovyScript("o.toSortedList(o.toObservable(1, 3, 2, 5, 4), {a, b -> a - b}).subscribe({ result -> a.received(result)});");
200+
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5));
201+
}
202+
203+
private void runGroovyScript(String script) {
204+
ClassLoader parent = getClass().getClassLoader();
205+
@SuppressWarnings("resource")
206+
GroovyClassLoader loader = new GroovyClassLoader(parent);
207+
208+
Binding binding = new Binding();
209+
binding.setVariable("mockApiCall", new TestFactory());
210+
binding.setVariable("a", assertion);
211+
binding.setVariable("o", org.rx.reactive.Observable.class);
212+
213+
/* parse the script and execute it */
214+
InvokerHelper.createScript(loader.parseClass(script), binding).run();
215+
}
216+
217+
private static interface ScriptAssertion {
218+
public void error(Exception o);
219+
220+
public void received(Object o);
221+
}
222+
223+
private static class TestFactory {
224+
int counter = 1;
225+
226+
@SuppressWarnings("unused")
227+
public Observable<Integer> getNumbers() {
228+
return Observable.toObservable(1, 3, 2, 5, 4);
229+
}
230+
231+
@SuppressWarnings("unused")
232+
public TestObservable getObservable() {
233+
return new TestObservable(counter++);
234+
}
235+
}
236+
237+
private static class TestObservable extends Observable<String> {
238+
private final int count;
239+
240+
public TestObservable(int count) {
241+
this.count = count;
242+
}
243+
244+
public Subscription subscribe(Observer<String> observer) {
245+
246+
observer.onNext("hello_" + count);
247+
observer.onCompleted();
248+
249+
return new Subscription() {
250+
251+
public void unsubscribe() {
252+
// unregister ... will never be called here since we are executing synchronously
253+
}
254+
255+
};
256+
}
257+
}
258+
}
259+
260+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apply plugin: 'java'
2+
dependencies {
3+
compile project(':rxjava-core')
4+
compile 'org.jruby:jruby:1.7.2'
5+
provided 'junit:junit:4.10'
6+
provided 'org.mockito:mockito-core:1.9.5'
7+
}

0 commit comments

Comments
 (0)