Merge lp:~salgado/tomdroid/sync-ui into lp:~tomdroid-dev/tomdroid/sync-ui

Proposed by Guilherme Salgado
Status: Merged
Merged at revision: 239
Proposed branch: lp:~salgado/tomdroid/sync-ui
Merge into: lp:~tomdroid-dev/tomdroid/sync-ui
Diff against target: 289 lines (+149/-9)
7 files modified
.classpath (+1/-0)
AndroidManifest.xml (+3/-0)
src/org/tomdroid/Note.java (+17/-1)
src/org/tomdroid/NoteManager.java (+15/-6)
src/org/tomdroid/NoteProvider.java (+4/-2)
tests/org/tomdroid/NoteManagerTest.java (+74/-0)
tests/org/tomdroid/NoteTest.java (+35/-0)
To merge this branch: bzr merge lp:~salgado/tomdroid/sync-ui
Reviewer Review Type Date Requested Status
Rodja (community) Approve
Olivier Bilodeau Pending
Review via email: mp+32509@code.launchpad.net

Description of the change

This branch excludes notebook templates from the list of notes.

To do that it parses the tags of all notes looking for a "system:template" and when found it flags that note as a notebook template. Right now this only happens when syncing notes from the web, but it could easily be done when syncing from SD as well.

That flag is then stored in the DB and used later to filter out the notebook templates from the notes list. One thing I'm not sure about is whether or not we want to have this flag stored in the DB or computed at run-time.

Oh, and I also started writing unit tests for the some things -- right now only for the things I've changed, but I plan to write more of them to help us feel more confident when doing refactorings.

To post a comment you must log in.
lp:~salgado/tomdroid/sync-ui updated
237. By Guilherme Salgado

Get rid of lots of unnecessary boilerplate created by Eclipse when I created a separate test project

238. By Guilherme Salgado

Fix a Null pointer error when loading a note JSON with no tags.

Revision history for this message
Olivier Bilodeau (plaxx) wrote :

Rodja, please review this and integrate it in sync-ui if you don't see any problems with it.

Revision history for this message
Rodja (trappe) wrote :

It is great to get rid of the templates but...

1. The tests are not passing if there are already notes in the database (see two-way-branch for an setUp/tearDown example).

2. Rather then introducing a new member to flag a note as "template" I would suggest to seach for the template tag each time isNotebookTemplate() is called. Performance is not an issue, but later refactorings will be harder with each new member variable.

3. Similar to the second remark, I would sooner see a row for all the tags changing the database when ever we feel about supporting a new tag.

Revision history for this message
Guilherme Salgado (salgado) wrote :

On Wed, 2010-08-25 at 20:26 +0000, Rodja wrote:
> It is great to get rid of the templates but...
>
> 1. The tests are not passing if there are already notes in the
> database (see two-way-branch for an setUp/tearDown example).
>

So, IIUC, you suggest that I just reset the database as part of
setUp/tearDown? That sounds fine to me, but the sync-ui branch doesn't
have LocalStorage (which you use in the two-way-sync branch to reset the
DB), so I'd have to do it manually for now. Something like:

  activity.getContentResolver().delete(Tomdroid.CONTENT_URI, null, null);
  Preferences.putLong(Preferences.Key.LATEST_SYNC_REVISION, 0);

Is that ok with you?

> 2. Rather then introducing a new member to flag a note as "template" I
> would suggest to seach for the template tag each time
> isNotebookTemplate() is called. Performance is not an issue, but later
> refactorings will be harder with each new member variable.

It's not because of performance that I made it a flag -- it's because I
think we should avoid spending processor cycles unnecessarily, to not
drain people's batteries.

My thinking was that if you have a long list of notes and you're
switching back and forth between any note and the notes list, tomdroid
would be doing a good job at draining your battery. To be honest I have
no idea how much power it'd spend while doing that, but it's easily
avoidable so I thought it was worth it. I'd be OK with dropping the new
flag as you suggest, if you feel it's not worth.

>
> 3. Similar to the second remark, I would sooner see a row for all the
> tags changing the database when ever we feel about supporting a new
> tag.

Do you mean you think we shouldn't be changing the DB schema often? I
don't think that's a problem (thanks to the framework's ability of
detecting when schema upgrades are needed and doing the migration
semi-automatically for us), specially when it's as early in the
lifecycle of the project as we are now.

--
Guilherme Salgado <https://launchpad.net/~salgado>

Revision history for this message
Rodja (trappe) wrote :

> On Wed, 2010-08-25 at 20:26 +0000, Rodja wrote:
> > It is great to get rid of the templates but...
> >
> > 1. The tests are not passing if there are already notes in the
> > database (see two-way-branch for an setUp/tearDown example).
> >
>
> So, IIUC, you suggest that I just reset the database as part of
> setUp/tearDown? That sounds fine to me, but the sync-ui branch doesn't
> have LocalStorage (which you use in the two-way-sync branch to reset the
> DB), so I'd have to do it manually for now. Something like:
>
> activity.getContentResolver().delete(Tomdroid.CONTENT_URI, null, null);
> Preferences.putLong(Preferences.Key.LATEST_SYNC_REVISION, 0);
>
> Is that ok with you?

Yes.

> > 2. Rather then introducing a new member to flag a note as "template" I
> > would suggest to seach for the template tag each time
> > isNotebookTemplate() is called. Performance is not an issue, but later
> > refactorings will be harder with each new member variable.
>
> It's not because of performance that I made it a flag -- it's because I
> think we should avoid spending processor cycles unnecessarily, to not
> drain people's batteries.
>
> My thinking was that if you have a long list of notes and you're
> switching back and forth between any note and the notes list, tomdroid
> would be doing a good job at draining your battery.

Is it? Have you tested? I would expect Android to keep the notes list Activity running while showing a Note; and calling onResume when switching back. But guessing is never good when talking about optimizations.

> To be honest I have
> no idea how much power it'd spend while doing that, but it's easily
> avoidable so I thought it was worth it. I'd be OK with dropping the new
> flag as you suggest, if you feel it's not worth.

Power consumtion is not easily measureable. But when looking on the battery usage graph from my Motorola Droid the big consumers are wifi, display, Maps and phone. I prefer having a clean code base which is easier to change in the future than "pollute" it with optimizations.

> > 3. Similar to the second remark, I would sooner see a row for all the
> > tags changing the database when ever we feel about supporting a new
> > tag.
>
> Do you mean you think we shouldn't be changing the DB schema often? I
> don't think that's a problem (thanks to the framework's ability of
> detecting when schema upgrades are needed and doing the migration
> semi-automatically for us), specially when it's as early in the
> lifecycle of the project as we are now.

True. I'm not against changing the data base scheme in general. But sooner or later we will introduce a column to store the tags of a note. Should we remove the system:template tag befor putting the others into that column?

I've no insights about Tomboy server API decisions of having "open-on-startup" and "pinned" as extra flags and "system:template" inside the tag list, but would recommend to stick as close as possible with the already provided scheme to avoid complicated data renderings and difficulties for other Tomboy developers.

Revision history for this message
Guilherme Salgado (salgado) wrote :

On Sat, 2010-08-28 at 08:10 +0000, Rodja wrote:
> > On Wed, 2010-08-25 at 20:26 +0000, Rodja wrote:
> > > It is great to get rid of the templates but...
> > >
> > > 1. The tests are not passing if there are already notes in the
> > > database (see two-way-branch for an setUp/tearDown example).
> > >
> >
> > So, IIUC, you suggest that I just reset the database as part of
> > setUp/tearDown? That sounds fine to me, but the sync-ui branch doesn't
> > have LocalStorage (which you use in the two-way-sync branch to reset the
> > DB), so I'd have to do it manually for now. Something like:
> >
> > activity.getContentResolver().delete(Tomdroid.CONTENT_URI, null, null);
> > Preferences.putLong(Preferences.Key.LATEST_SYNC_REVISION, 0);
> >
> > Is that ok with you?
>
> Yes.
>

Cool, I've done that.

> > > 2. Rather then introducing a new member to flag a note as "template" I
> > > would suggest to seach for the template tag each time
> > > isNotebookTemplate() is called. Performance is not an issue, but later
> > > refactorings will be harder with each new member variable.
> >

One issue with the solution you suggest is that, in the current
implementation, we only have access to the tags (which is in the JSON
representation sent by the server) when creating a new Note row in the
database, so I'd have to store all the tags in the DB somehow. Probably
in a custom format as the web sync gives me JSON and the file sync gives
XML.

Does that sound ok to you? Do you have any suggestions as to which
format to use for the tags in the DB? Ideally I think it should be in a
separate table (linked to the Note table) with one column for the key
and another for the value.

> > It's not because of performance that I made it a flag -- it's because I
> > think we should avoid spending processor cycles unnecessarily, to not
> > drain people's batteries.
> >
> > My thinking was that if you have a long list of notes and you're
> > switching back and forth between any note and the notes list, tomdroid
> > would be doing a good job at draining your battery.
>
> Is it? Have you tested? I would expect Android to keep the notes list
> Activity running while showing a Note; and calling onResume when
> switching back. But guessing is never good when talking about
> optimizations.

You're most likely right here. I didn't know this could happen as I
don't know much about Android and this is the first time I write some
code for it.

>
> > To be honest I have
> > no idea how much power it'd spend while doing that, but it's easily
> > avoidable so I thought it was worth it. I'd be OK with dropping the new
> > flag as you suggest, if you feel it's not worth.
>
> Power consumtion is not easily measureable. But when looking on the
> battery usage graph from my Motorola Droid the big consumers are wifi,
> display, Maps and phone. I prefer having a clean code base which is
> easier to change in the future than "pollute" it with optimizations.

Fair enough.

lp:~salgado/tomdroid/sync-ui updated
239. By Guilherme Salgado

A couple tweaks suggested by reviewer

240. By Guilherme Salgado

merge lp:~tomdroid-developers/sync-ui

Revision history for this message
Olivier Bilodeau (plaxx) wrote :

Hi guys,

I'm a bit concerned when hearing about the XML vs JSON tags.. In the end, aren't they both strings (ex: system:template or system:notebook:bookname)? Wait, as I write this (noticing the <bookname> related to the notebook addin) I see tons of potential problems with a rigid SQL approach..

- A multi to multi SQL approach would be ugly as hell (one entry per <bookname>) but then what about nested xml in the tag or attributes in the xml node.. where would they end up?
- A list of enabled/disabled tags represented in a row of a note as a packed binary would not handle additional data either.. and would be more coupled with Tomdroid's version..

What do we do here? <buzzword>Schema-less database?</buzzword> I'll let you guys think about that. Do not hesitate to bring this to the -dev list if you feel it deserves to.

On the performance / potential power-saving topic:
Until we have benchmark evidence showing it's not efficient I would opt for simpler code and less db maintenance. I don't plan to do auto db upgrade for 0.4 but just drop the db because no notes can be created locally yet. Someone could work on that if required though.

However, related to your concern Guilherme, to improve things we should save and restore the list of notes from the main activity whenever we can in the lifecycle. This would improve a case or two where it is dropped. Actually I should write that down in doc/dev/TODO...

Thanks for the work guys!

Revision history for this message
Rodja (trappe) wrote :

I'm by no means a database guy, so i've no clue how to solve the tag storing problem. But a quick Google search (http://lmgtfy.com/?q=storing+tags+in+relational+database) reveals tons of howtos and insights.

I suggest to use the simplest possible approach for a start (this may be storing all tags comma seperated in a single column) and optimizing it in a seperate branch. This merge is about removing the templates from the main list, not getting a high performance tag storage.

Revision history for this message
Guilherme Salgado (salgado) wrote :

On Fri, 2010-09-03 at 04:29 +0000, Olivier Bilodeau wrote:
> Hi guys,
>
> I'm a bit concerned when hearing about the XML vs JSON tags.. In the
> end, aren't they both strings (ex: system:template or
> system:notebook:bookname)? Wait, as I write this (noticing the

Yes, they're the same thing; I don't know what I had in mind when I
wrote that.

> <bookname> related to the notebook addin) I see tons of potential
> problems with a rigid SQL approach..

Well, that could be extrapolated to the rest of tomdroid, no? I mean,
is a relational database the right thing to store tomboy notes?

>
> - A multi to multi SQL approach would be ugly as hell (one entry per
> <bookname>) but then what about nested xml in the tag or attributes in
> the xml node.. where would they end up?
> - A list of enabled/disabled tags represented in a row of a note as a
> packed binary would not handle additional data either.. and would be
> more coupled with Tomdroid's version..
>
> What do we do here? <buzzword>Schema-less database?</buzzword> I'll
> let you guys think about that. Do not hesitate to bring this to the
> -dev list if you feel it deserves to.

We could use CouchDB (http://www.couch.io/android) for 2.1 and 2.2, but
not for previous versions. Do you know of any alternatives?

> On the performance / potential power-saving topic:
> Until we have benchmark evidence showing it's not efficient I would
> opt for simpler code and less db maintenance. I don't plan to do auto
> db upgrade for 0.4 but just drop the db because no notes can be
> created locally yet. Someone could work on that if required though.

IMHO, that's not necessary as long as notes are read-only in tomdroid.

I'd really like to keep working on this and do some experiments, but I
won't be able to do that before November as I'm recovering from a
surgery and have my left arm in a sling, so unless anybody else wants to
move this forward, I think it won't be included in 0.4

--
Guilherme Salgado <https://launchpad.net/~salgado>

lp:~salgado/tomdroid/sync-ui updated
241. By Guilherme Salgado

Store all tags in the DB rather than storing just a flag telling whether or not a note is a notebook template

242. By Guilherme Salgado

Add a comment explaining why the test will fail in some cases

Revision history for this message
Guilherme Salgado (salgado) wrote :

Actually, it was fairly easy to do what Rodja suggested, so maybe this can still be included in 0.4

Revision history for this message
Rodja (trappe) wrote :

Works fine and is defenitly a good thing to have in the 0.4 release featuring 'web sync'.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.classpath'
2--- .classpath 2010-08-31 21:00:35 +0000
3+++ .classpath 2010-09-17 21:12:56 +0000
4@@ -6,4 +6,5 @@
5 <classpathentry kind="lib" path="lib/signpost-core-1.2.1.1.jar"/>
6 <classpathentry kind="lib" path="lib/signpost-commonshttp4-1.2.1.1.jar"/>
7 <classpathentry kind="output" path="bin"/>
8+ <classpathentry kind="src" path="tests"/>
9 </classpath>
10
11=== modified file 'AndroidManifest.xml'
12--- AndroidManifest.xml 2010-05-24 07:27:14 +0000
13+++ AndroidManifest.xml 2010-09-17 21:12:56 +0000
14@@ -48,7 +48,10 @@
15
16 </activity>
17
18+ <uses-library android:name="android.test.runner" />
19 </application>
20
21 <uses-permission android:name="android.permission.INTERNET" />
22+<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="org.tomdroid"></instrumentation>
23+
24 </manifest>
25
26=== modified file 'src/org/tomdroid/Note.java'
27--- src/org/tomdroid/Note.java 2010-08-30 16:33:02 +0000
28+++ src/org/tomdroid/Note.java 2010-09-17 21:12:56 +0000
29@@ -28,6 +28,7 @@
30 import java.util.regex.Pattern;
31
32 import org.json.JSONObject;
33+import org.json.JSONArray;
34 import org.tomdroid.util.NoteContentBuilder;
35 import org.tomdroid.util.XmlUtils;
36
37@@ -46,6 +47,7 @@
38 public static final String MODIFIED_DATE = "modified_date";
39 public static final String URL = "url";
40 public static final String FILE = "file";
41+ public static final String TAGS = "tags";
42 public static final String NOTE_CONTENT = "content";
43
44 // Logging info
45@@ -65,6 +67,7 @@
46 private String url;
47 private String fileName;
48 private String title;
49+ private String tags;
50 private Time lastChangeDate;
51 private int dbId;
52 private UUID guid;
53@@ -85,8 +88,21 @@
54 setGuid(json.optString("guid"));
55 setLastChangeDate(json.optString("last-change-date"));
56 setXmlContent(json.optString("note-content"));
57+ JSONArray jtags = json.optJSONArray("tags");
58+ String tag;
59+ tags = new String();
60+ if (jtags != null) {
61+ for (int i = 0; i < jtags.length(); i++ ) {
62+ tag = jtags.optString(i);
63+ tags += tag + ",";
64+ }
65+ }
66 }
67
68+ public String getTags() {
69+ return tags;
70+ }
71+
72 public String getUrl() {
73 return url;
74 }
75@@ -150,7 +166,7 @@
76 public void setGuid(String guid) {
77 this.guid = UUID.fromString(guid);
78 }
79-
80+
81 // TODO: should this handler passed around evolve into an observer pattern?
82 public SpannableStringBuilder getNoteContent(Handler handler) {
83
84
85=== modified file 'src/org/tomdroid/NoteManager.java'
86--- src/org/tomdroid/NoteManager.java 2010-03-21 18:38:49 +0000
87+++ src/org/tomdroid/NoteManager.java 2010-09-17 21:12:56 +0000
88@@ -96,6 +96,7 @@
89 // Notice that we store the date in UTC because sqlite doesn't handle RFC3339 timezone information
90 values.put(Note.MODIFIED_DATE, note.getLastChangeDate().format3339(false));
91 values.put(Note.NOTE_CONTENT, note.getXmlContent());
92+ values.put(Note.TAGS, note.getTags());
93
94 if (managedCursor.getCount() == 0) {
95
96@@ -127,18 +128,26 @@
97 return false;
98 }
99
100+ public static Cursor getAllNotes(Activity activity, Boolean includeNotebookTemplates) {
101+ // get a cursor representing all notes from the NoteProvider
102+ Uri notes = Tomdroid.CONTENT_URI;
103+ String where = null;
104+ if (!includeNotebookTemplates) {
105+ where = Note.TAGS + " NOT LIKE '%" + "system:template" + "%'";
106+ }
107+ return activity.managedQuery(notes, LIST_PROJECTION, where, null, null);
108+ }
109+
110+
111 public static ListAdapter getListAdapter(Activity activity) {
112-
113- // get a cursor representing all notes from the NoteProvider
114- Uri notes = Tomdroid.CONTENT_URI;
115- Cursor notesCursor = activity.managedQuery(notes, LIST_PROJECTION, null, null, null);
116+ Cursor notesCursor = getAllNotes(activity, false);
117
118 // set up an adapter binding the TITLE field of the cursor to the list item
119 String[] from = new String[] { Note.TITLE };
120 int[] to = new int[] { R.id.note_title };
121 return new SimpleCursorAdapter(activity, R.layout.main_list_item, notesCursor, from, to);
122 }
123-
124+
125 // gets the titles of the notes present in the db, used in ViewNote.buildLinkifyPattern()
126 public static Cursor getTitles(Activity activity) {
127
128@@ -149,7 +158,7 @@
129 // gets the ids of the notes present in the db, used in SyncService.deleteNotes()
130 public static Cursor getGuids(Activity activity) {
131
132- // get a cursor containing the notes titles
133+ // get a cursor containing the notes guids
134 return activity.managedQuery(Tomdroid.CONTENT_URI, GUID_PROJECTION, null, null, null);
135 }
136
137
138=== modified file 'src/org/tomdroid/NoteProvider.java'
139--- src/org/tomdroid/NoteProvider.java 2010-08-30 16:33:02 +0000
140+++ src/org/tomdroid/NoteProvider.java 2010-09-17 21:12:56 +0000
141@@ -69,7 +69,7 @@
142 // --
143 private static final String DATABASE_NAME = "tomdroid-notes.db";
144 private static final String DB_TABLE_NOTES = "notes";
145- private static final int DB_VERSION = 2;
146+ private static final int DB_VERSION = 3;
147 private static final String DEFAULT_SORT_ORDER = Note.MODIFIED_DATE + " DESC";
148
149 private static HashMap<String, String> notesProjectionMap;
150@@ -100,7 +100,8 @@
151 + Note.TITLE + " TEXT,"
152 + Note.FILE + " TEXT,"
153 + Note.NOTE_CONTENT + " TEXT,"
154- + Note.MODIFIED_DATE + " STRING"
155+ + Note.MODIFIED_DATE + " STRING,"
156+ + Note.TAGS + " STRING"
157 + ");");
158 }
159
160@@ -297,6 +298,7 @@
161 notesProjectionMap.put(Note.TITLE, Note.TITLE);
162 notesProjectionMap.put(Note.FILE, Note.FILE);
163 notesProjectionMap.put(Note.NOTE_CONTENT, Note.NOTE_CONTENT);
164+ notesProjectionMap.put(Note.TAGS, Note.TAGS);
165 notesProjectionMap.put(Note.MODIFIED_DATE, Note.MODIFIED_DATE);
166 }
167 }
168
169=== added directory 'tests'
170=== added directory 'tests/org'
171=== added directory 'tests/org/tomdroid'
172=== added file 'tests/org/tomdroid/NoteManagerTest.java'
173--- tests/org/tomdroid/NoteManagerTest.java 1970-01-01 00:00:00 +0000
174+++ tests/org/tomdroid/NoteManagerTest.java 2010-09-17 21:12:56 +0000
175@@ -0,0 +1,74 @@
176+package org.tomdroid;
177+
178+import org.json.JSONObject;
179+import org.tomdroid.Note;
180+import org.tomdroid.NoteManager;
181+import org.tomdroid.ui.Tomdroid;
182+import org.tomdroid.util.Preferences;
183+
184+import android.app.Activity;
185+import android.content.Intent;
186+import android.database.Cursor;
187+import android.test.ActivityUnitTestCase;
188+
189+public class NoteManagerTest extends ActivityUnitTestCase<Tomdroid> {
190+
191+ public NoteManagerTest() {
192+ super(Tomdroid.class);
193+ }
194+
195+ public void testGetAllNotes() throws Exception {
196+ Activity activity = getActivity();
197+ putNotes(activity);
198+ Cursor cursor;
199+ // Get all notes excluding the notebook template ones.
200+ cursor = NoteManager.getAllNotes(activity, false);
201+ assertEquals(1, cursor.getCount());
202+
203+ // Get all notes, including notebook templates this time.
204+ cursor = NoteManager.getAllNotes(activity, true);
205+ assertEquals(2, cursor.getCount());
206+ }
207+
208+ private void putNotes(Activity a) throws Exception {
209+ // Add a regular note to the content manager.
210+ JSONObject note = new JSONObject(
211+ "{'title': 'foo', 'note-content': 'bar', " +
212+ "'guid': '002e91a2-2e34-4e2d-bf88-21def49a7704', " +
213+ "'last-change-date': '2009-04-19T21:29:23.2197340-07:00', " +
214+ "'tags': ['tag1', 'tag2']}");
215+ Note n = new Note(note);
216+ NoteManager.putNote(a, n);
217+
218+ // Add a notebook template to the content manager.
219+ JSONObject template = new JSONObject(
220+ "{'title': 'foo', 'note-content': 'bar', " +
221+ "'guid': '992e91a2-2e34-4e2d-bf88-21def49a7712', " +
222+ "'last-change-date': '2009-04-19T21:29:23.2197340-07:00', " +
223+ "'tags': ['system:template', 'tag2']}");
224+ Note t = new Note(template);
225+ NoteManager.putNote(a, t);
226+ }
227+
228+ @Override
229+ public void setUp() throws Exception {
230+ super.setUp();
231+ // XXX: For some reason this will raise an
232+ // "Unable to add window -- token null is not for an application"
233+ // error when you run the test after wiping user data from the emulator.
234+ // The error is actually raised when we try to display the AlertDialog that
235+ // is shown the first time the user runs tomdroid.
236+ startActivity(new Intent(), null, null);
237+ // XXX: Soon we'll be able to replace the two lines below with LocalStorage.resetDatabase().
238+ getActivity().getContentResolver().delete(Tomdroid.CONTENT_URI, null, null);
239+ Preferences.putLong(Preferences.Key.LATEST_SYNC_REVISION, 0);
240+ }
241+
242+ @Override
243+ public void tearDown() throws Exception {
244+ // XXX: Soon we'll be able to replace the two lines below with LocalStorage.resetDatabase().
245+ getActivity().getContentResolver().delete(Tomdroid.CONTENT_URI, null, null);
246+ Preferences.putLong(Preferences.Key.LATEST_SYNC_REVISION, 0);
247+ super.tearDown();
248+ }
249+}
250
251=== added file 'tests/org/tomdroid/NoteTest.java'
252--- tests/org/tomdroid/NoteTest.java 1970-01-01 00:00:00 +0000
253+++ tests/org/tomdroid/NoteTest.java 2010-09-17 21:12:56 +0000
254@@ -0,0 +1,35 @@
255+package org.tomdroid;
256+
257+import junit.framework.Assert;
258+import junit.framework.TestCase;
259+
260+import org.tomdroid.Note;
261+import org.json.JSONException;
262+import org.json.JSONObject;
263+
264+
265+public class NoteTest extends TestCase {
266+
267+ public void testConstructorForNoteWithTags() throws JSONException {
268+ JSONObject json = new JSONObject(
269+ "{'title': 'foo', 'note-content': 'bar', " +
270+ "'guid': '002e91a2-2e34-4e2d-bf88-21def49a7705', " +
271+ "'last-change-date': '2009-04-19T21:29:23.2197340-07:00', " +
272+ "'tags': ['tag1', 'tag2']}");
273+ Note n = new Note(json);
274+ Assert.assertEquals("foo", n.getTitle());
275+ Assert.assertEquals("002e91a2-2e34-4e2d-bf88-21def49a7705", n.getGuid().toString());
276+ Assert.assertEquals("bar", n.getXmlContent());
277+ Assert.assertEquals("tag1,tag2,", n.getTags());
278+ }
279+
280+ public void testConstructorForNoteWithNoTags() throws JSONException {
281+ JSONObject json = new JSONObject(
282+ "{'title': 'foo', 'note-content': 'bar', " +
283+ "'guid': '002e91a2-2e34-4e2d-bf88-21def49a7705', " +
284+ "'last-change-date': '2009-04-19T21:29:23.2197340-07:00'}");
285+ Note n = new Note(json);
286+ Assert.assertEquals("foo", n.getTitle());
287+ Assert.assertEquals("", n.getTags());
288+ }
289+}

Subscribers

People subscribed via source and target branches

to all changes: