Enhancement - Att object

- Improved new Att object.
- Added new constructor to accommodate integer attribute values.
- Implemented unit tests.
This commit is contained in:
Paul Beckingham 2009-05-24 12:25:20 -04:00
parent 6600f9bac4
commit c860d58641
7 changed files with 205 additions and 47 deletions

View file

@ -25,6 +25,8 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <sstream>
#include <stdlib.h>
#include "Att.h" #include "Att.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -44,6 +46,18 @@ Att::Att (const std::string& name, const std::string& value)
mMods.clear (); mMods.clear ();
} }
////////////////////////////////////////////////////////////////////////////////
Att::Att (const std::string& name, int value)
{
mName = name;
std::stringstream s;
s << value;
mValue = s.str ();
mMods.clear ();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Att::Att (const Att& other) Att::Att (const Att& other)
{ {
@ -55,7 +69,6 @@ Att::Att (const Att& other)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Att& Att::operator= (const Att& other) Att& Att::operator= (const Att& other)
{ {
throw std::string ("unimplemented Att::operator=");
if (this != &other) if (this != &other)
{ {
mName = other.mName; mName = other.mName;
@ -73,21 +86,43 @@ Att::~Att ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Parse the following forms: // Parse the following forms:
// name [[.mod] ...] : [value] // name [[.mod] ...] : " [value] "
void Att::parse (const std::string& input) void Att::parse (const std::string& input)
{ {
throw std::string ("unimplemented Att::parse"); mName = "";
mValue = "";
mMods.clear ();
std::string::size_type colon = input.find (":");
if (colon != std::string::npos)
{
std::string name = input.substr (0, colon);
// TODO Are there mods?
mName = name;
std::string value = input.substr (colon + 1, std::string::npos);
dequote (value);
decode (value);
mValue = value;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// name : " value " // name : " value "
std::string Att::composeF4 () const std::string Att::composeF4 () const
{ {
std::string output = "";
if (mName != "" && mValue != "")
{
std::string value = mValue; std::string value = mValue;
encode (value); encode (value);
enquote (value); enquote (value);
return mName + ":" + value; output += mName + ":" + value;
}
return output;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -123,35 +158,15 @@ void Att::value (const std::string& value)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int Att::value_int () const int Att::value_int () const
{ {
throw std::string ("unimplemented Att::value_int"); return ::atoi (mValue.c_str ());
return 0;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Att::value_int (int) void Att::value_int (int value)
{ {
throw std::string ("unimplemented Att::value_int"); std::stringstream s;
} s << value;
mValue = s.str ();
////////////////////////////////////////////////////////////////////////////////
bool Att::filter () const
{
throw std::string ("unimplemented filter");
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Att::required () const
{
throw std::string ("unimplemented Att::required");
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Att::reserved () const
{
throw std::string ("unimplemented Att::reserved");
return false;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -162,13 +177,14 @@ void Att::enquote (std::string& value) const
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Remove quotes. // Remove quotes. Instead of being picky, just remove them all. There should
// be none within the value, and this will correct for one possible corruption
// that hand-editing the pending.data file could cause.
void Att::dequote (std::string& value) const void Att::dequote (std::string& value) const
{ {
if (value.length () > 2 && std::string::size_type quote;
value[0] == '"' && while ((quote = value.find ('"')) != std::string::npos)
value[value.length () - 1] == '"') value.replace (quote, 1, "");
value = value.substr (1, value.length () - 2);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -36,6 +36,7 @@ class Att
public: public:
Att (); // Default constructor Att (); // Default constructor
Att (const std::string&, const std::string&); // Simple constructor Att (const std::string&, const std::string&); // Simple constructor
Att (const std::string&, int); // Simple constructor
Att (const Att&); // Copy constructor Att (const Att&); // Copy constructor
Att& operator= (const Att&); // Assignment operator Att& operator= (const Att&); // Assignment operator
~Att (); // Destructor ~Att (); // Destructor
@ -44,6 +45,7 @@ public:
std::string composeF4 () const; std::string composeF4 () const;
void addMod (const std::string&); void addMod (const std::string&);
// TODO Need method to access mods.
std::string name () const; std::string name () const;
void name (const std::string&); void name (const std::string&);
@ -54,10 +56,6 @@ public:
int value_int () const; int value_int () const;
void value_int (int); void value_int (int);
bool filter () const;
bool required () const;
bool reserved () const;
private: private:
void enquote (std::string&) const; void enquote (std::string&) const;
void dequote (std::string&) const; void dequote (std::string&) const;

View file

@ -25,6 +25,7 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string> #include <string>
#include <sys/file.h> #include <sys/file.h>
#include "text.h" #include "text.h"
@ -144,18 +145,23 @@ void TDB::unlock ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// TODO Returns number of filtered tasks. // Returns number of filtered tasks.
int TDB::load (std::vector <T>& tasks, Filter& filter) int TDB::load (std::vector <T>& tasks, Filter& filter)
{ {
char line[T_LINE_MAX]; char line[T_LINE_MAX];
foreach (location, mLocations) foreach (location, mLocations)
{ {
std::cout << "# location: " << location->first << std::endl;
while (fgets (line, T_LINE_MAX, location->second)) while (fgets (line, T_LINE_MAX, location->second))
{ {
int length = ::strlen (line); int length = ::strlen (line);
if (length > 1) if (length > 1)
{ {
line[length - 1] = '\0'; // Kill \n line[length - 1] = '\0'; // Kill \n
std::cout << "# line: " << line << std::endl;
T task (line); T task (line);

View file

@ -67,7 +67,7 @@ private:
bool mLock; bool mLock;
bool mAllOpenAndLocked; bool mAllOpenAndLocked;
// TODO Need cache of raw file contents. // TODO Need cache of raw file contents to preserve comments.
}; };
#endif #endif

View file

@ -7,3 +7,6 @@ text.t
autocomplete.t autocomplete.t
parse.t parse.t
seq.t seq.t
att.t
mod.t
record.t

View file

@ -1,9 +1,9 @@
PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \ PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \
parse.t seq.t parse.t seq.t att.t # mod.t record.t
CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti
LFLAGS = -L/usr/local/lib LFLAGS = -L/usr/local/lib
OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../Duration.o \ OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../Duration.o \
../util.o ../Config.o ../Sequence.o ../util.o ../Config.o ../Sequence.o ../Att.o ../Record.o ../Mod.o
all: $(PROJECT) all: $(PROJECT)
@ -46,3 +46,12 @@ parse.t: parse.t.o $(OBJECTS) test.o
seq.t: seq.t.o $(OBJECTS) test.o seq.t: seq.t.o $(OBJECTS) test.o
g++ seq.t.o $(OBJECTS) test.o $(LFLAGS) -o seq.t g++ seq.t.o $(OBJECTS) test.o $(LFLAGS) -o seq.t
record.t: record.t.o $(OBJECTS) test.o
g++ record.t.o $(OBJECTS) test.o $(LFLAGS) -o record.t
mod.t: mod.t.o $(OBJECTS) test.o
g++ mod.t.o $(OBJECTS) test.o $(LFLAGS) -o mod.t
att.t: att.t.o $(OBJECTS) test.o
g++ att.t.o $(OBJECTS) test.o $(LFLAGS) -o att.t

126
src/tests/att.t.cpp Normal file
View file

@ -0,0 +1,126 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2009, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <Att.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
UnitTest t (31);
Att a1 ("name", "value");
t.is (a1.name (), "name", "Att::Att (name, value), Att.name");
t.is (a1.value (), "value", "Att::Att (name, value), Att.value");
Att a2;
a2.name ("name");
a2.value ("value");
t.is (a2.name (), "name", "Att::Att (), Att.name");
t.is (a2.value (), "value", "Att::Att (), Att.value");
Att a3 (a2);
t.is (a3.name (), "name", "Att::Att (Att), Att.name");
t.is (a3.value (), "value", "Att::Att (Att), Att.value");
Att a4;
a4 = a2;
t.is (a4.name (), "name", "Att::Att (), Att.operator=, Att.name");
t.is (a4.value (), "value", "Att::Att (), Att.operator=, Att.value");
Att a5 ("name", "value");
t.is (a5.composeF4 (), "name:\"value\"", "Att::composeF4 simple");
a5.value ("\"");
t.is (a5.composeF4 (), "name:\"&quot;\"", "Att::composeF4 encoded \"");
a5.value ("\t\",[]:");
t.is (a5.composeF4 (), "name:\"&tab;&quot;&comma;&open;&close;&colon;\"", "Att::composeF4 fully encoded \\t\",[]:");
Att a6 ("name", 6);
t.is (a6.value_int (), 6, "Att::value_int get");
a6.value_int (7);
t.is (a6.value_int (), 7, "Att::value_int set/get");
t.is (a6.value (), "7", "Att::value 7");
// TODO Att::addMod
// Att::parse
Att a7;
a7.parse ("");
t.is (a7.composeF4 (), "", "Att::composeF4 ()");
a7.parse ("name:value");
t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:value)");
a7.parse ("name:\"value\"");
t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"value\")");
a7.parse ("name:\"one two\"");
t.is (a7.composeF4 (), "name:\"one two\"", "Att::composeF4 (name:\"one two\")");
a7.parse ("name:\"&quot;\"");
t.is (a7.composeF4 (), "name:\"&quot;\"", "Att::composeF4 (name:\"&quot;\")");
a7.parse ("name:\"&tab;&quot;&comma;&open;&close;&colon;\"");
t.is (a7.composeF4 (), "name:\"&tab;&quot;&comma;&open;&close;&colon;\"",
"Att::composeF4 (name:\"&tab;&quot;&comma;&open;&close;&colon;\")");
a7.parse ("total gibberish");
t.is (a7.composeF4 (), "", "Att::composeF4 (total gibberish)");
a7.parse ("malformed");
t.is (a7.composeF4 (), "", "Att::composeF4 (malformed)");
a7.parse (":malformed");
t.is (a7.composeF4 (), "", "Att::composeF4 (:malformed)");
a7.parse (":\"\"");
t.is (a7.composeF4 (), "", "Att::composeF4 (:\"\")");
a7.parse (":\"");
t.is (a7.composeF4 (), "", "Att::composeF4 (:\")");
a7.parse ("name:");
t.is (a7.composeF4 (), "", "Att::composeF4 (name:)");
a7.parse ("name:\"value");
t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"value)");
a7.parse ("name:value\"");
t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:value\")");
a7.parse ("name:val\"ue");
t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:val\"ue)");
a7.parse ("name:\"\"va\"\"\"\"\"lu\"\"\"e\"\"");
t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"\"va\"\"\"\"\"lu\"\"\"e\"\")");
a7.parse ("name\"");
t.is (a7.composeF4 (), "", "Att::composeF4 (name\")");
return 0;
}
////////////////////////////////////////////////////////////////////////////////