[tomboy] REST API now removes title from content completely. Implement in NoteConvert, with corresponding uni



commit ab32ef3826e1e95b3468b162ffdb08d1ab6e8c3f
Author: Sandy Armstrong <sanfordarmstrong gmail com>
Date:   Sat May 23 19:57:30 2009 -0700

    REST API now removes title from content completely. Implement in NoteConvert, with corresponding unit test.
    
    Set URI correctly when creating NoteData from NoteInfo.
---
 Tomboy/Addins/WebSyncService/NoteConvert.cs        |   56 ++++-
 .../WebSyncService/Tests/NoteConvertTests.cs       |  247 +++++++++++++++++++-
 2 files changed, 289 insertions(+), 14 deletions(-)

diff --git a/Tomboy/Addins/WebSyncService/NoteConvert.cs b/Tomboy/Addins/WebSyncService/NoteConvert.cs
index 96c5797..a64983d 100644
--- a/Tomboy/Addins/WebSyncService/NoteConvert.cs
+++ b/Tomboy/Addins/WebSyncService/NoteConvert.cs
@@ -25,6 +25,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Text;
 using System.Text.RegularExpressions;
 
 using Tomboy.Sync;
@@ -51,7 +52,7 @@ namespace Tomboy.WebSync
 				noteInfo.Tags.Add (tag.Name);
 
 			const string noteContentRegex =
-				@"^<note-content(\s+version=""(?<contentVersion>[^""]+)"")?>(?<innerContent>.*)</note-content>$";
+				@"^<note-content(\s+version=""(?<contentVersion>[^""]+)"")?\s*((/>)|(>(?<innerContent>.*)</note-content>))$";
 			Match m = Regex.Match (note.XmlContent, noteContentRegex, RegexOptions.Singleline);
 			Group versionGroup = m.Groups ["contentVersion"];
 			Group contentGroup = m.Groups ["innerContent"];
@@ -61,11 +62,38 @@ namespace Tomboy.WebSync
 			    double.TryParse (versionGroup.Value, out contentVersion)) {
 				noteInfo.NoteContentVersion = contentVersion;
 			} else
-				noteInfo.NoteContentVersion = 0.1;
+				noteInfo.NoteContentVersion = 0.1;	// TODO: Constants, transformations, etc, if this changes
 
-			if (contentGroup.Success)
-				noteInfo.NoteContent = contentGroup.Value;
-			else
+			if (contentGroup.Success) {
+				string [] splits =
+					contentGroup.Value.Split (new char [] {'\n'}, 2);
+				if (splits.Length > 1 && splits [1].Length > 0) {
+					StringBuilder builder = new StringBuilder (contentGroup.Value.Length);
+					bool inTag = false;
+					// Strip everything out of first line, except for XML tags
+					// TODO: Handle 'note-title' element differently?
+					//       Ideally we would want to get rid of it completely.
+					foreach (char c in splits [0]) {
+						if (!inTag && c == '<')
+							inTag = true;
+						if (inTag) {
+							builder.Append (c);
+							if (c == '>')
+								inTag = false;
+						}
+					}
+					
+					// Trim leading newline, if there is one
+					if (splits [1][0] == '\n')
+						builder.Append (splits [1], 1, splits [1].Length - 1);
+					else
+						builder.Append (splits [1]);
+					
+					noteInfo.NoteContent = builder.ToString ();
+				}
+			}
+			
+			if (noteInfo.NoteContent == null)
 				noteInfo.NoteContent = string.Empty;
 
 			return noteInfo;
@@ -75,11 +103,13 @@ namespace Tomboy.WebSync
 		{
 			// NOTE: For now, we absolutely require values for
 			//       Guid, Title, NoteContent, and NoteContentVersion
-			NoteData noteData = new NoteData (noteInfo.Guid);
+			// TODO: Is this true? What happens if dates are excluded?
+			NoteData noteData = new NoteData (NoteUriFromGuid (noteInfo.Guid));
 			noteData.Title = noteInfo.Title;
-			noteData.Text =
-				"<note-content version=\"" + noteInfo.NoteContentVersion.ToString () + "\">" +
-				noteInfo.NoteContent + "</note-content>";
+			noteData.Text = string.Format ("<note-content version=\"{0}\">{1}\n\n{2}</note-content>",
+				noteInfo.NoteContentVersion,
+				noteData.Title,
+				noteInfo.NoteContent);
 			if (noteInfo.LastChangeDate.HasValue)
 				noteData.ChangeDate = noteInfo.LastChangeDate.Value;
 			if (noteInfo.LastMetadataChangeDate.HasValue)
@@ -88,7 +118,7 @@ namespace Tomboy.WebSync
 				noteData.CreateDate = noteInfo.CreateDate.Value;
 			if (noteInfo.OpenOnStartup.HasValue)
 				noteData.IsOpenOnStartup = noteInfo.OpenOnStartup.Value;
-			// TODO: support Pinned
+			// TODO: support Pinned -- http://bugzilla.gnome.org/show_bug.cgi?id=433412
 
 			if (noteInfo.Tags != null) {
 				foreach (string tagName in noteInfo.Tags) {
@@ -105,5 +135,11 @@ namespace Tomboy.WebSync
 			NoteData noteData = ToNoteData (noteInfo);
 			return NoteArchiver.WriteString (noteData);
 		}
+
+		// TODO: Copied from Note.cs, duplication sucks
+		static string NoteUriFromGuid (string guid)
+		{
+			return "note://tomboy/" + guid;
+		}
 	}
 }
diff --git a/Tomboy/Addins/WebSyncService/Tests/NoteConvertTests.cs b/Tomboy/Addins/WebSyncService/Tests/NoteConvertTests.cs
index 9222d2a..b82062a 100644
--- a/Tomboy/Addins/WebSyncService/Tests/NoteConvertTests.cs
+++ b/Tomboy/Addins/WebSyncService/Tests/NoteConvertTests.cs
@@ -26,17 +26,256 @@
 #if ENABLE_TESTS
 
 using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
 
-namespace Tomboy
+using Tomboy.WebSync;
+using Tomboy.WebSync.Api;
+
+using NUnit.Framework;
+
+namespace Tomboy.WebSync.Tests
 {
-	
-	
+	[TestFixture]
 	public class NoteConvertTests
 	{
+		[TestFixtureSetUp]
+		public void FixtureSetUp ()
+		{
+			InMemoryPreferencesClient memPrefsClient = new InMemoryPreferencesClient ();
+
+			Type prefsType = typeof (Preferences);
+			FieldInfo prefsClientField =
+				prefsType.GetField ("client", BindingFlags.NonPublic
+				                              | BindingFlags.Static);
+			prefsClientField.SetValue (null, memPrefsClient);
+
+			Type servicesType = typeof (Services);
+			FieldInfo servicesClientField =
+				servicesType.GetField ("prefs", BindingFlags.NonPublic
+				                                | BindingFlags.Static);
+			servicesClientField.SetValue (null, memPrefsClient);
+		}
+
+		[TestFixtureTearDown]
+		public void FixtureTearDown ()
+		{
+			Type prefsType = typeof (Preferences);
+			FieldInfo prefsClientField =
+				prefsType.GetField ("client", BindingFlags.NonPublic
+				                                        | BindingFlags.Static);
+			prefsClientField.SetValue (null, null);
+
+			Type servicesType = typeof (Services);
+			FieldInfo servicesClientField =
+				servicesType.GetField ("client", BindingFlags.NonPublic
+				                                        | BindingFlags.Static);
+			servicesClientField.SetValue (null, null);
+		}
+		
+		[Test]
+		public void ToNoteInfoTest ()
+		{
+			// Note content stress tests
+			string [] titles = new string [14];
+			string [] contents = new string [14];
+			string [] expectedInfoContents = new string [14];
+			
+			titles [0] = "(Untitled 238)";
+			contents [0] = @"<note-content version=""0.1"">
+
+Title Actually on Third Line
+
+(edited before moving to third line)
+
+<link:internal>new note 322</link:internal>
+
+title on second lin</note-content>";
+			expectedInfoContents [0] = @"Title Actually on Third Line
+
+(edited before moving to third line)
+
+<link:internal>new note 322</link:internal>
+
+title on second lin";
+
+			titles [1] = "Title on Fourth Line";
+			contents [1] = @"<note-content version=""0.1"">
+
+
+Title on Fourth Line
+
+Describe your new note here.</note-content>";
+			expectedInfoContents [1] = @"
+Title on Fourth Line
+
+Describe your new note here.";
+
+			titles [2] = "New Note 322";
+			contents [2] = @"<note-content version=""0.1"">
+Title on second lin
+
+(edited after moving to second line)</note-content>";
+			expectedInfoContents [2] = @"Title on second lin
+
+(edited after moving to second line)";
+
+			titles [3] = "New Note 326";
+			contents [3] = @"<note-content version=""0.1"">
+
+
+
+
+
+
+
+New Note 326
+
+Describe your new note here.</note-content>";
+			expectedInfoContents [3] = @"
+
+
+
+
+
+New Note 326
+
+Describe your new note here.";
+
+			titles [4] = "(Untitled 331)";
+			contents [4] = @"<note-content version=""0.1"" />";
+			expectedInfoContents [4] = string.Empty;
+
+			titles [5] = "(Untitled 329)";
+			contents [5] = @"<note-content version=""0.1"">
+Text on second line added after first line totally deleted
+Describe your new note here.</note-content>";
+			expectedInfoContents [5] = @"Text on second line added after first line totally deleted
+Describe your new note here.";
+
+			titles [6] = "Seventy Six trombones in the big parade blah blah blah blah blah blah blah blah hlkjsfdijsdflksjf lsajfsdlj lskjf sljk lsjf sljflsjf lsjkf sljfsl slfj sljfslkjf lsjf lsjf lsj fsdlj fsdlj fsljkf sljkf slfjk slkfj slfj sldfj sljkf lsakjfslajf sljf lsfjk sl dfjlsf j";
+			contents [6] = @"<note-content version=""0.1"">Seventy Six trombones in the big parade blah blah blah blah blah blah blah blah hlkjsfdijsdflksjf lsajfsdlj lskjf sljk lsjf sljflsjf lsjkf sljfsl slfj sljfslkjf lsjf lsjf lsj fsdlj fsdlj fsljkf sljkf slfjk slkfj slfj sldfj sljkf lsakjfslajf sljf lsfjk sl dfjlsf j
+Title on Third Lne yeah?
+
+(edited before moving to second line...didn't mean third)</note-content>";
+			expectedInfoContents [6] = @"Title on Third Lne yeah?
+
+(edited before moving to second line...didn't mean third)";
+
+			titles [7] = "New Note 329";
+			contents [7] = @"<note-content version=""0.1"">New Note 329
+
+Describe your new note here.</note-content>";
+			expectedInfoContents [7] = @"Describe your new note here.";
+
+			titles [8] = "New Note 329";
+			contents [8] = @"<note-content version=""0.1""><note-title>New Note 329</note-title>
+
+Describe your new note here.</note-content>";
+			expectedInfoContents [8] = @"<note-title></note-title>Describe your new note here.";
+
+			titles [9] = "New Note 329";
+			contents [9] = @"<note-content version=""0.1""><note-title><b>New Note 329</b></note-title>
+
+Describe your new note here.</note-content>";
+			expectedInfoContents [9] = @"<note-title><b></b></note-title>Describe your new note here.";
+
+			titles [10] = "New Note 329";
+			contents [10] = @"<note-content version=""0.1""><size:huge><note-title>New Note 329</note-title>
+
+Describe your new note here.</size:huge></note-content>";
+			expectedInfoContents [10] = @"<size:huge><note-title></note-title>Describe your new note here.</size:huge>";
+
+			titles [11] = "New Note 329";
+			contents [11] = @"<note-content version=""0.1""><size:huge>New Note 329
+
+Describe your new note here.</size:huge></note-content>";
+			expectedInfoContents [11] = @"<size:huge>Describe your new note here.</size:huge>";
+
+			titles [12] = "New Note 330";
+			contents [12] = @"<note-content version=""0.1"">New Note 330
+Describe your new note here.</note-content>";
+			expectedInfoContents [12] = @"Describe your new note here.";
+
+			titles [13] = "New Note 331";
+			contents [13] = @"<note-content version=""0.1"">New Note 331
+
+
+Describe your new note here.</note-content>";
+			expectedInfoContents [13] = @"
+Describe your new note here.";
+			
+
+			for (int i =0; i < titles.Length; i++) {
+				NoteData data = new NoteData ("note://tomboy/12345");
+				data.Title = titles [i];
+				data.Text = contents [i];
+				string tmpFileName = "ToNoteInfoTest.tmp";
+				File.Create (tmpFileName).Close ();
+				File.SetCreationTime (tmpFileName, new DateTime (2009, 1, 5));
+				File.SetLastWriteTime (tmpFileName, new DateTime (2009, 1, 6));
+	
+				Note note = Note.CreateExistingNote (data, tmpFileName, null);
+				
+				NoteInfo info = NoteConvert.ToNoteInfo (note);
+				Assert.AreEqual (titles [i], info.Title, "Title");
+				Assert.AreEqual (expectedInfoContents [i], info.NoteContent, "NoteContent");
+				Assert.AreEqual (0.1, info.NoteContentVersion.Value, "NoteContentVersion");
+			}
+		}
+	}
+
+	public class InMemoryPreferencesClient : IPreferencesClient
+	{
+		private Dictionary<string, object> prefs =
+			new Dictionary<string, object> ();
+		private Dictionary<string, NotifyEventHandler> events =
+			new Dictionary<string, NotifyEventHandler> ();
+
+		#region IPreferencesClient implementation
+		public void Set (string key, object val)
+		{
+			prefs [key] = val;
+			foreach (string nkey in events.Keys) {
+				NotifyEventHandler handler = events [nkey] as NotifyEventHandler;
+				if (handler != null && key.StartsWith (nkey)) {
+					NotifyEventArgs args = new NotifyEventArgs (key, val);
+					handler (this, args);
+				}
+			}
+		}
+		
+		public object Get (string key)
+		{
+			object val;
+			if (prefs.TryGetValue (key, out val))
+				return val;
+			throw new NoSuchKeyException (key);
+		}
+		
+		public void AddNotify (string dir, NotifyEventHandler notify)
+		{
+			lock (events) {
+				if (!events.ContainsKey (dir))
+					events [dir] = notify;
+				else
+					events [dir] += notify;
+			}
+		}
+		
+		public void RemoveNotify (string dir, NotifyEventHandler notify)
+		{
+			lock (events) {
+				if (events.ContainsKey (dir))
+					events [dir] -= notify;
+			}
+		}
 		
-		public NoteConvertTests()
+		public void SuggestSync ()
 		{
 		}
+		#endregion
 	}
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]