Skip to content

Commit

Permalink
Support searching by plain timestamps and agenda
Browse files Browse the repository at this point in the history
Part of orgzly#76.
  • Loading branch information
nevenz committed Mar 7, 2019
1 parent 8c4bb47 commit 7cfd22e
Show file tree
Hide file tree
Showing 19 changed files with 1,842 additions and 32 deletions.
1,361 changes: 1,361 additions & 0 deletions app/schemas/com.orgzly.android.db.OrgzlyDatabase/151.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.test.espresso.Espresso.*
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.rule.ActivityTestRule
import com.orgzly.R
import com.orgzly.android.OrgzlyTest
import com.orgzly.android.espresso.EspressoUtils.*
Expand All @@ -19,7 +18,7 @@ import org.junit.Test
//@Ignore
class BookPrefaceTest : OrgzlyTest() {
@get:Rule
var activityRule: ActivityTestRule<*> = EspressoActivityTestRule(MainActivity::class.java, true, false)
var activityRule = EspressoActivityTestRule(MainActivity::class.java, true, false)

@Before
@Throws(Exception::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.rule.ActivityTestRule
import com.orgzly.R
import com.orgzly.android.OrgzlyTest
import com.orgzly.android.espresso.EspressoUtils.*
Expand All @@ -23,7 +22,7 @@ import org.junit.Test
//@Ignore
class BooksSortOrderTest : OrgzlyTest() {
@get:Rule
var activityRule: ActivityTestRule<*> = EspressoActivityTestRule(MainActivity::class.java, true, false)
var activityRule = EspressoActivityTestRule(MainActivity::class.java, true, false)

@Before
@Throws(Exception::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.os.Environment
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.rule.ActivityTestRule
import com.orgzly.R
import com.orgzly.android.App
import com.orgzly.android.OrgzlyTest
Expand All @@ -27,7 +26,7 @@ class ExternalLinksTest(private val param: Parameter) : OrgzlyTest() {
data class Parameter(val link: String, val check: () -> Any)

@get:Rule
var activityRule: ActivityTestRule<*> = EspressoActivityTestRule(MainActivity::class.java, true, false)
var activityRule = EspressoActivityTestRule(MainActivity::class.java, true, false)

companion object {
@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import org.junit.Ignore
//@Ignore
class InternalLinksTest : OrgzlyTest() {
@get:Rule
var activityRule: ActivityTestRule<*> = EspressoActivityTestRule(MainActivity::class.java, true, false)
var activityRule = EspressoActivityTestRule(MainActivity::class.java, true, false)

@Before
@Throws(Exception::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.orgzly.android.espresso

import androidx.test.espresso.assertion.ViewAssertions.matches
import com.orgzly.android.OrgzlyTest
import com.orgzly.android.espresso.EspressoUtils.*
import com.orgzly.android.ui.main.MainActivity
import com.orgzly.org.datetime.OrgDateTime
import org.junit.Rule
import org.junit.Test

class NoteTimestampTest : OrgzlyTest() {
@get:Rule
var activityRule = EspressoActivityTestRule(MainActivity::class.java, true, false)

private val now: String
get() = OrgDateTime(true).toString()

private val today: String
get() = OrgDateTime.Builder()
.setDay(System.currentTimeMillis())
.setIsActive(true)
.build()
.toString()

private val tomorrow: String
get() = OrgDateTime.Builder()
.setDay(System.currentTimeMillis() + 86400000L)
.setIsActive(true)
.build()
.toString()

private val inFewDays: String
get() = OrgDateTime.Builder()
.setDay(System.currentTimeMillis() + 86400000L * 3)
.setIsActive(true)
.build()
.toString()

private val fewDaysAgo: String
get() = OrgDateTime.Builder()
.setDay(System.currentTimeMillis() - 86400000L * 3)
.setIsActive(true)
.build()
.toString()


@Test
fun search_OneInTitle() {
testUtils.setupBook("book-a", "* Note $now")
activityRule.launchActivity(null)
searchForText("e.ge.today")
onNotesInSearch().check(matches(recyclerViewItemCount(1)))
}

@Test
fun search_OneInContent() {
testUtils.setupBook("book-a", "* Note\n$now")
activityRule.launchActivity(null)
searchForText("e.ge.today")
onNotesInSearch().check(matches(recyclerViewItemCount(1)))
}

@Test
fun search_TwoSameInContent() {
testUtils.setupBook("book-a", "* Note\n$now $now")
activityRule.launchActivity(null)
searchForText("e.ge.today")
onNotesInSearch().check(matches(recyclerViewItemCount(1)))
}

@Test
fun agenda_OneInTitle() {
testUtils.setupBook("book-a", "* Note $now")
activityRule.launchActivity(null)
searchForText("ad.1")
onNotesInAgenda().check(matches(recyclerViewItemCount(2)))
}

@Test
fun agenda_TwoInTitle() {
testUtils.setupBook("book-a", "* Note $now $tomorrow")
activityRule.launchActivity(null)
searchForText("ad.2")
onNotesInAgenda().check(matches(recyclerViewItemCount(4)))
}

@Test
fun agenda_OneInContent() {
testUtils.setupBook("book-a", "* Note\n$now")
activityRule.launchActivity(null)
searchForText("ad.1")
onNotesInAgenda().check(matches(recyclerViewItemCount(2)))
}

@Test
fun agenda_TwoInContent() {
testUtils.setupBook("book-a", "* Note\n$now $tomorrow")
activityRule.launchActivity(null)
searchForText("ad.2")
onNotesInAgenda().check(matches(recyclerViewItemCount(4)))
}

@Test
fun search_TodayAndInFewDays() {
testUtils.setupBook(
"book-a",
"* Today $today\n* In few days $inFewDays\n* Today & In few days $today $inFewDays")
activityRule.launchActivity(null)
searchForText("e.gt.1d")
onNotesInSearch().check(matches(recyclerViewItemCount(2)))
}

@Test
fun agenda_PastEvent() {
testUtils.setupBook("book-a", "* Few days ago\n$fewDaysAgo")
activityRule.launchActivity(null)
searchForText("ad.2")
onNotesInAgenda().check(matches(recyclerViewItemCount(2)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -766,4 +766,12 @@ public void testOpensBookFromSearchBySwiping() {
onNoteInSearch(1).perform(swipeLeft());
onView(withId(R.id.fragment_book_view_flipper)).check(matches(isDisplayed()));
}

@Test
public void testSearchAndClickOnNoteWithTwoDifferentEvents() {
testUtils.setupBook("notebook", "* Note\n<2000-01-01>\n<2000-01-02>");
activityRule.launchActivity(null);
searchForText("e.lt.now");
onNoteInSearch(0).perform(click());
}
}
43 changes: 40 additions & 3 deletions app/src/main/java/com/orgzly/android/data/DataRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import com.orgzly.android.util.MiscUtils
import com.orgzly.android.util.OrgFormatter
import com.orgzly.org.OrgFile
import com.orgzly.org.OrgFileSettings
import com.orgzly.org.OrgActiveTimestamps
import com.orgzly.org.datetime.OrgDateTime
import com.orgzly.org.datetime.OrgRange
import com.orgzly.org.parser.OrgNestedSetParserListener
Expand Down Expand Up @@ -936,7 +937,7 @@ class DataRepository @Inject constructor(
return db.noteView().runQuery(sqlQuery)
}

private fun buildSqlQuery(query: Query): SupportSQLiteQuery {
private fun buildSqlQuery(query: Query, groupByEvent: Boolean = false): SupportSQLiteQuery {
val queryBuilder = SqliteQueryBuilder(context)

val (selection, selectionArgs, orderBy) = queryBuilder.build(query)
Expand All @@ -948,7 +949,7 @@ class DataRepository @Inject constructor(
}

if (query.options.agendaDays > 0) {
s.add("(scheduled_range_id IS NOT NULL OR deadline_range_id IS NOT NULL)")
s.add("(scheduled_range_id IS NOT NULL OR deadline_range_id IS NOT NULL OR event_timestamp IS NOT NULL)")
}

if (!s.isEmpty() || !query.sortOrders.isEmpty()) {
Expand All @@ -957,9 +958,15 @@ class DataRepository @Inject constructor(

val selection2 = if (s.isEmpty()) "0" else TextUtils.join(" AND ", s)

// For agenda, group by event timestamp too
val groupBy = if (query.isAgenda()) {
"notes.id, event_timestamp"
} else {
"notes.id"
}

val supportQuery = SupportSQLiteQueryBuilder
.builder("(${NoteViewDao.QUERY} GROUP BY notes.id)")
.builder("(${NoteViewDao.QUERY_WITH_NOTE_EVENTS} GROUP BY $groupBy)")
.selection(selection2, selectionArgs.toTypedArray())
.orderBy(orderBy)
.create()
Expand Down Expand Up @@ -1178,6 +1185,8 @@ class DataRepository @Inject constructor(

replaceNoteProperties(noteId, notePayload.properties)

replaceNoteEvents(noteId, notePayload.title, notePayload.content)

db.noteAncestor().insertAncestorsForNote(noteId)

updateBookIsModified(target.bookId, true, time)
Expand Down Expand Up @@ -1222,6 +1231,8 @@ class DataRepository @Inject constructor(

replaceNoteProperties(noteId, notePayload.properties)

replaceNoteEvents(noteId, notePayload.title, notePayload.content)

val newNote = note.copy(
title = notePayload.title,
content = notePayload.content,
Expand All @@ -1240,6 +1251,30 @@ class DataRepository @Inject constructor(
}
}

private fun replaceNoteEvents(noteId: Long, title: String, content: String?) {
db.noteEvent().deleteForNote(noteId)

insertNoteEvents(noteId, title, content)
}

private fun insertNoteEvents(noteId: Long, title: String, content: String?) {
if (title.isNotEmpty()) {
parseAndInsertEvents(noteId, title)
}

if (! content.isNullOrEmpty()) {
parseAndInsertEvents(noteId, content)
}
}

private fun parseAndInsertEvents(noteId: Long, str: String) {
OrgActiveTimestamps.parse(str).forEach { range ->
getOrgRangeId(range)?.let { orgRangeId ->
db.noteEvent().replace(NoteEvent(noteId, orgRangeId))
}
}
}

/**
* Loads book from resource.
*/
Expand Down Expand Up @@ -1430,6 +1465,8 @@ class DataRepository @Inject constructor(

insertNoteProperties(noteId, node.head.properties)

insertNoteEvents(noteId, note.title, note.content)

/*
* Update notes' parent IDs and insert ancestors.
* Going through all descendants - nodes between lft and rgt.
Expand Down
Loading

0 comments on commit 7cfd22e

Please sign in to comment.