-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from benjchristensen/language-adaptors
Language adaptors
- Loading branch information
Showing
51 changed files
with
1,344 additions
and
241 deletions.
There are no files selected for viewing
Binary file not shown.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# originally from http://sensemaya.org/files/stylesheet.css and then modified | ||
# http://sensemaya.org/maya/2009/07/10/making-javadoc-more-legible | ||
|
||
/* Javadoc style sheet */ | ||
|
||
/* Define colors, fonts and other style attributes here to override the defaults */ | ||
|
||
/* Page background color */ | ||
body { background-color: #FFFFFF; color:#333; font-size: 100%; } | ||
|
||
body { font-size: 0.875em; line-height: 1.286em; font-family: "Helvetica", "Arial", sans-serif; } | ||
|
||
code { color: #777; line-height: 1.286em; font-family: "Consolas", "Lucida Console", "Droid Sans Mono", "Andale Mono", "Monaco", "Lucida Sans Typewriter"; } | ||
|
||
a { text-decoration: none; color: #16569A; /* also try #2E85ED, #0033FF, #6C93C6, #1D7BBE, #1D8DD2 */ } | ||
a:hover { text-decoration: underline; } | ||
|
||
|
||
table[border="1"] { border: 1px solid #ddd; } | ||
table[border="1"] td, table[border="1"] th { border: 1px solid #ddd; } | ||
table[cellpadding="3"] td { padding: 0.5em; } | ||
|
||
font[size="-1"] { font-size: 0.85em; line-height: 1.5em; } | ||
font[size="-2"] { font-size: 0.8em; } | ||
font[size="+2"] { font-size: 1.4em; line-height: 1.3em; padding: 0.4em 0; } | ||
|
||
/* Headings */ | ||
h1 { font-size: 1.5em; line-height: 1.286em;} | ||
h2.title { color: #c81f08; } | ||
|
||
/* Table colors */ | ||
.TableHeadingColor { background: #ccc; color:#444; } /* Dark mauve */ | ||
.TableSubHeadingColor { background: #ddd; color:#444; } /* Light mauve */ | ||
.TableRowColor { background: #FFFFFF; color:#666; font-size: 0.95em; } /* White */ | ||
.TableRowColor code { color:#000; } /* White */ | ||
|
||
/* Font used in left-hand frame lists */ | ||
.FrameTitleFont { font-size: 100%; } | ||
.FrameHeadingFont { font-size: 90%; } | ||
.FrameItemFont { font-size: 0.9em; line-height: 1.3em; | ||
} | ||
/* Java Interfaces */ | ||
.FrameItemFont a i { | ||
font-style: normal; color: #16569A; | ||
} | ||
.FrameItemFont a:hover i { | ||
text-decoration: underline; | ||
} | ||
|
||
|
||
/* Navigation bar fonts and colors */ | ||
.NavBarCell1 { background-color:#E0E6DF; } /* Light mauve */ | ||
.NavBarCell1Rev { background-color:#16569A; color:#FFFFFF} /* Dark Blue */ | ||
.NavBarFont1 { } | ||
.NavBarFont1Rev { color:#FFFFFF; } | ||
|
||
.NavBarCell2 { background-color:#FFFFFF; color:#000000} | ||
.NavBarCell3 { background-color:#FFFFFF; color:#000000} | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apply plugin: 'java' | ||
dependencies { | ||
compile project(':rxjava-core') | ||
compile 'org.codehaus.groovy:groovy:1.8.8' | ||
provided 'junit:junit:4.10' | ||
provided 'org.mockito:mockito-core:1.9.5' | ||
} |
260 changes: 260 additions & 0 deletions
260
language-adaptors/rxjava-groovy/src/main/java/org/rx/lang/groovy/GroovyAdaptor.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
/** | ||
* Copyright 2013 Netflix, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.rx.lang.groovy; | ||
|
||
import static org.mockito.Matchers.*; | ||
import static org.mockito.Mockito.*; | ||
import groovy.lang.Binding; | ||
import groovy.lang.Closure; | ||
import groovy.lang.GroovyClassLoader; | ||
|
||
import java.util.Arrays; | ||
|
||
import org.codehaus.groovy.runtime.InvokerHelper; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.mockito.Mock; | ||
import org.mockito.MockitoAnnotations; | ||
import org.rx.functions.FunctionLanguageAdaptor; | ||
import org.rx.reactive.Notification; | ||
import org.rx.reactive.Observable; | ||
import org.rx.reactive.Observer; | ||
import org.rx.reactive.Subscription; | ||
|
||
public class GroovyAdaptor implements FunctionLanguageAdaptor { | ||
|
||
@Override | ||
public Object call(Object function, Object[] args) { | ||
return ((Closure<?>) function).call(args); | ||
} | ||
|
||
public Class<?> getFunctionClass() { | ||
return Closure.class; | ||
} | ||
|
||
public static class UnitTest { | ||
|
||
@Mock | ||
ScriptAssertion assertion; | ||
|
||
@Mock | ||
Observer<Integer> w; | ||
|
||
@Before | ||
public void before() { | ||
MockitoAnnotations.initMocks(this); | ||
} | ||
|
||
@Test | ||
public void testCreateViaGroovy() { | ||
runGroovyScript("o.create({it.onNext('hello');it.onCompleted();}).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received("hello"); | ||
} | ||
|
||
@Test | ||
public void testFilterViaGroovy() { | ||
runGroovyScript("o.filter(o.toObservable(1, 2, 3), {it >= 2}).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(0)).received(1); | ||
verify(assertion, times(1)).received(2); | ||
verify(assertion, times(1)).received(3); | ||
} | ||
|
||
@Test | ||
public void testLast() { | ||
String script = "mockApiCall.getObservable().last().subscribe({ result -> a.received(result)});"; | ||
runGroovyScript(script); | ||
verify(assertion, times(1)).received("hello_1"); | ||
} | ||
|
||
@Test | ||
public void testMap() { | ||
String script = "mockApiCall.getObservable().map({v -> 'say' + v}).subscribe({ result -> a.received(result)});"; | ||
runGroovyScript(script); | ||
verify(assertion, times(1)).received("sayhello_1"); | ||
} | ||
|
||
@Test | ||
public void testMapViaGroovy() { | ||
runGroovyScript("o.map(o.toObservable(1, 2, 3), {'hello_' + it}).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received("hello_" + 1); | ||
verify(assertion, times(1)).received("hello_" + 2); | ||
verify(assertion, times(1)).received("hello_" + 3); | ||
} | ||
|
||
@Test | ||
public void testMaterializeViaGroovy() { | ||
runGroovyScript("o.materialize(o.toObservable(1, 2, 3)).subscribe({ result -> a.received(result)});"); | ||
// we expect 4 onNext calls: 3 for 1, 2, 3 ObservableNotification.OnNext and 1 for ObservableNotification.OnCompleted | ||
verify(assertion, times(4)).received(any(Notification.class)); | ||
verify(assertion, times(0)).error(any(Exception.class)); | ||
} | ||
|
||
@Test | ||
public void testMergeDelayErrorViaGroovy() { | ||
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)});"); | ||
verify(assertion, times(1)).received(1); | ||
verify(assertion, times(1)).received(2); | ||
verify(assertion, times(1)).received(3); | ||
verify(assertion, times(1)).received(4); | ||
verify(assertion, times(1)).received(5); | ||
verify(assertion, times(1)).received(6); | ||
verify(assertion, times(0)).received(7); | ||
verify(assertion, times(1)).error(any(NullPointerException.class)); | ||
} | ||
|
||
@Test | ||
public void testMergeViaGroovy() { | ||
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)});"); | ||
// executing synchronously so we can deterministically know what order things will come | ||
verify(assertion, times(1)).received(1); | ||
verify(assertion, times(1)).received(2); | ||
verify(assertion, times(1)).received(3); | ||
verify(assertion, times(0)).received(4); // the NPE will cause this sequence to be skipped | ||
verify(assertion, times(0)).received(5); // the NPE will cause this sequence to be skipped | ||
verify(assertion, times(1)).received(6); // this comes before the NPE so should exist | ||
verify(assertion, times(0)).received(7);// this comes in the sequence after the NPE | ||
verify(assertion, times(1)).error(any(NullPointerException.class)); | ||
} | ||
|
||
@Test | ||
public void testScriptWithMaterialize() { | ||
String script = "mockApiCall.getObservable().materialize().subscribe({ result -> a.received(result)});"; | ||
runGroovyScript(script); | ||
// 2 times: once for hello_1 and once for onCompleted | ||
verify(assertion, times(2)).received(any(Notification.class)); | ||
} | ||
|
||
@Test | ||
public void testScriptWithMerge() { | ||
String script = "o.merge(mockApiCall.getObservable(), mockApiCall.getObservable()).subscribe({ result -> a.received(result)});"; | ||
runGroovyScript(script); | ||
verify(assertion, times(1)).received("hello_1"); | ||
verify(assertion, times(1)).received("hello_2"); | ||
} | ||
|
||
@Test | ||
public void testScriptWithOnNext() { | ||
String script = "mockApiCall.getObservable().subscribe({ result -> a.received(result)})"; | ||
runGroovyScript(script); | ||
verify(assertion).received("hello_1"); | ||
} | ||
|
||
@Test | ||
public void testSkipTakeViaGroovy() { | ||
runGroovyScript("o.skip(o.toObservable(1, 2, 3), 1).take(1).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(0)).received(1); | ||
verify(assertion, times(1)).received(2); | ||
verify(assertion, times(0)).received(3); | ||
} | ||
|
||
@Test | ||
public void testSkipViaGroovy() { | ||
runGroovyScript("o.skip(o.toObservable(1, 2, 3), 2).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(0)).received(1); | ||
verify(assertion, times(0)).received(2); | ||
verify(assertion, times(1)).received(3); | ||
} | ||
|
||
@Test | ||
public void testTakeViaGroovy() { | ||
runGroovyScript("o.take(o.toObservable(1, 2, 3), 2).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received(1); | ||
verify(assertion, times(1)).received(2); | ||
verify(assertion, times(0)).received(3); | ||
} | ||
|
||
@Test | ||
public void testToSortedList() { | ||
runGroovyScript("mockApiCall.getNumbers().toSortedList().subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5)); | ||
} | ||
|
||
@Test | ||
public void testToSortedListStatic() { | ||
runGroovyScript("o.toSortedList(o.toObservable(1, 3, 2, 5, 4)).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5)); | ||
} | ||
|
||
@Test | ||
public void testToSortedListWithFunction() { | ||
runGroovyScript("mockApiCall.getNumbers().toSortedList({a, b -> a - b}).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5)); | ||
} | ||
|
||
@Test | ||
public void testToSortedListWithFunctionStatic() { | ||
runGroovyScript("o.toSortedList(o.toObservable(1, 3, 2, 5, 4), {a, b -> a - b}).subscribe({ result -> a.received(result)});"); | ||
verify(assertion, times(1)).received(Arrays.asList(1, 2, 3, 4, 5)); | ||
} | ||
|
||
private void runGroovyScript(String script) { | ||
ClassLoader parent = getClass().getClassLoader(); | ||
@SuppressWarnings("resource") | ||
GroovyClassLoader loader = new GroovyClassLoader(parent); | ||
|
||
Binding binding = new Binding(); | ||
binding.setVariable("mockApiCall", new TestFactory()); | ||
binding.setVariable("a", assertion); | ||
binding.setVariable("o", org.rx.reactive.Observable.class); | ||
|
||
/* parse the script and execute it */ | ||
InvokerHelper.createScript(loader.parseClass(script), binding).run(); | ||
} | ||
|
||
private static interface ScriptAssertion { | ||
public void error(Exception o); | ||
|
||
public void received(Object o); | ||
} | ||
|
||
private static class TestFactory { | ||
int counter = 1; | ||
|
||
@SuppressWarnings("unused") | ||
public Observable<Integer> getNumbers() { | ||
return Observable.toObservable(1, 3, 2, 5, 4); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public TestObservable getObservable() { | ||
return new TestObservable(counter++); | ||
} | ||
} | ||
|
||
private static class TestObservable extends Observable<String> { | ||
private final int count; | ||
|
||
public TestObservable(int count) { | ||
this.count = count; | ||
} | ||
|
||
public Subscription subscribe(Observer<String> observer) { | ||
|
||
observer.onNext("hello_" + count); | ||
observer.onCompleted(); | ||
|
||
return new Subscription() { | ||
|
||
public void unsubscribe() { | ||
// unregister ... will never be called here since we are executing synchronously | ||
} | ||
|
||
}; | ||
} | ||
} | ||
} | ||
|
||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apply plugin: 'java' | ||
dependencies { | ||
compile project(':rxjava-core') | ||
compile 'org.jruby:jruby:1.7.2' | ||
provided 'junit:junit:4.10' | ||
provided 'org.mockito:mockito-core:1.9.5' | ||
} |
Oops, something went wrong.