Whether you find a bug, typo or an API call that could be clarified, please file an issue on our GitHub repository.
When filing an issue, please provide as much of the following information as possible in order to help us fix it:
- Goals
- Expected results
- Actual results
- Steps to reproduce
- Code sample that highlights the issue (link to full Android Studio projects that we can compile ourselves are ideal)
- Version of Realm/Android Studio/OS
If you'd like to send us sensitive sample code to help troubleshoot your issue, you can email [email protected] directly.
We love contributions to Realm! If you'd like to contribute code, documentation, or any other improvements, please file a Pull Request on our GitHub repository. Make sure to accept our CLA!
Realm welcomes all contributions! The only requirement we have is that, like many other projects, we need to have a Contributor License Agreement (CLA) in place before we can accept any external code. Our own CLA is a modified version of the Apache Software Foundation’s CLA.
Please submit your CLA electronically using our Google form so we can accept your submissions. The GitHub username you file there will need to match that of your Pull Requests. If you have any questions or cannot file the CLA electronically, you can email [email protected].
While we havn't described our code style yet, please just follow the existing style you see in the files you change.
All PR's must be accompanied by related unit tests. All bug fixes must have a unit test proving that the bug is fixed.
You can use ./realm/gradlew connectedCheck createDebugCoverageReport
to generate a coverage report to check for
missing unit test coverage. The aim is 100% code coverage.
When writing unit tests, use the following guide lines:
-
Unit tests must be written using JUnit4.
-
All tests for a class should be grouped in a class called
<className>Tests
, unless the functionality is cross- cutting likeRxJavaTests
orRealmAsyncQueryTests
. -
Test methods should use camelCase and underscore
_
between logical sections to increase method name readability. Methods should ideally start with the name of the method being tested. Patterns like:<methodName>_<description>
,<methodName>_<param>_<description>
or<description>
are encouraged. -
All unit tests creating Realms must do so using the
TestRealmConfigurationFactory
orRunInLooperThread
test rules. This ensures that all Realms are properly closed and deleted between each test. -
Use the
@RunInLooperThread
rule for any test that depends on Realms notification system. -
Input-parameters should be boundary tested. Especially
Null/NotNull
, but also the state of Realm objects like standalone objects, deleted objects, objects from other threads. -
Unit tests are not required to only have 1 test. It is acceptable to combine multiple tests into one unit test, but if it fails, it should be clear why it failed. E.g. you can group related tests with the same setup like negative tests. If you do so, make sure to separate each "subtest" with a comment stating what you test.
-
Use only
@Test(expected = xxx.class)
if the test case contains one line. If the test contains multiple lines and it is the last line that is tested, use theExceptedException
rule instead. In all other cases, use the following pattern:try { somethingThatThrowsIllegalArgument();
} catch (IllegalArgumentException ignored) { } -
Use comments to make the intent of the unit test easily understandable at a glance. A simple one line comment is often easier to read
thanALongCamelCasedSentenceThatAttemptsToDescribeWhatHappens
. Describe the test steps inside the method, if it's not glaringly obvious.
This is an example of how a unit test class could look like:
@RunWith(AndroidJUnit4.class)
public class RealmTests {
@Rule
public final TestRealmConfigurationFactory configFactory = new TestRealmConfigurationFactory();
@Rule
public final RunInLooperThread looperThread = new RunInLooperThread();
private Realm realm;
@Before
public void setUp() {
RealmConfiguration config = configFactory.createConfiguration();
realm = Realm.getInstance(config);
}
@After
public void tearDown() {
if (realm != null) {
realm.close();
}
}
@Test(expected = IllegalStateException.class)
public void createObject_outsideTransaction() {
realm.createObject(Foo.class);
}
@Test
public void createObject_illegalInput {
// Class not part of the schema
try {
realm.createObject(Foo.class);
} catch (IllegalArgumentException ignored) {
}
// Null class
try {
realm.createObject(null);
} catch (IllegalArgumentException ignored) {
}
}
@Test
@RunTestInLooperThread
public void addChangeListener_notifiedOnLocalCommit() {
realm.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
assert(1, realm.allObjects(Foo.class).size());
looperThread.testComplete();
}
});
realm.beginTransaction();
realm.createObject(Foo.class);
realm.commitTransaction();
}
}
All public classes and methods must have Javadoc describing their purpose.
/**
* Checks if given field is equal to the provided value.
*
* <pre>
* {@code
* // A multi-line code sample should be formatted like this.
* // Please wrap the code element in a <pre> tag.
* }
* </pre>
*
* @param fieldName the field to compare.
* @param fieldValue the value to compare with.
* @param caseSensitive if {@code true}, substring matching is case sensitive. Setting this to {@code false} works for English locale characters only.
* @param caseSensitive if true, substring matching is case sensitive. Setting this to false only works for English
* locale characters.
* @return the query object.
* @throws java.lang.IllegalArgumentException if one or more arguments do not match class or field type.
* @throws IllegalArgumentException if field name doesn't exists, it doesn't contain a list of links or the type
* of the object represented by the DynamicRealmObject doesn't match.
* @deprecated Please use {@link #average(String)} instead.
* @see #endGroup()
*/
public RealmQuery<E> equalTo(String fieldName, String fieldValue, boolean caseSensitive) {
// ...
}
- Method descriptions begin with a verb phrase, e.g. "Checks" instead of "Check".
- Capitalize the first letter of the method and @deprecated descriptions. Everything else starts with lower case.
- Empty line between method description and the rest.
- End all descriptions with a period
.
(except @see). - Reference other Realm classes using
{@link ...}
. - Wrap Java values in
{@code ...}
. - @throws description must start with "if".
- Never list generic exceptions like
RuntimeException
,Exception
orError
. Always reference the specific error. - Line-length maximum is 120 chars. Parameter descriptions that go above this, should be split into multiple lines and indented. Otherwise do not use indentation (contrary to Oracle guidelines).
Above is based on the official guidelines from Oracle regarding Javadoc: http://www.oracle.com/technetwork/articles/java/index-137868.html