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"
////////////////////////////////////////////////////////////////////////////////
@ -44,6 +46,18 @@ Att::Att (const std::string& name, const std::string& value)
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)
{
@ -55,7 +69,6 @@ Att::Att (const Att& other)
////////////////////////////////////////////////////////////////////////////////
Att& Att::operator= (const Att& other)
{
throw std::string ("unimplemented Att::operator=");
if (this != &other)
{
mName = other.mName;
@ -73,21 +86,43 @@ Att::~Att ()
////////////////////////////////////////////////////////////////////////////////
// Parse the following forms:
// name [[.mod] ...] : [value]
// name [[.mod] ...] : " [value] "
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 "
std::string Att::composeF4 () const
{
std::string output = "";
if (mName != "" && mValue != "")
{
std::string value = mValue;
encode (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
{
throw std::string ("unimplemented Att::value_int");
return 0;
return ::atoi (mValue.c_str ());
}
////////////////////////////////////////////////////////////////////////////////
void Att::value_int (int)
void Att::value_int (int value)
{
throw std::string ("unimplemented Att::value_int");
}
////////////////////////////////////////////////////////////////////////////////
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;
std::stringstream s;
s << value;
mValue = s.str ();
}
////////////////////////////////////////////////////////////////////////////////
@ -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
{
if (value.length () > 2 &&
value[0] == '"' &&
value[value.length () - 1] == '"')
value = value.substr (1, value.length () - 2);
std::string::size_type quote;
while ((quote = value.find ('"')) != std::string::npos)
value.replace (quote, 1, "");
}
////////////////////////////////////////////////////////////////////////////////

View file

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

View file

@ -25,6 +25,7 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <sys/file.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)
{
char line[T_LINE_MAX];
foreach (location, mLocations)
{
std::cout << "# location: " << location->first << std::endl;
while (fgets (line, T_LINE_MAX, location->second))
{
int length = ::strlen (line);
if (length > 1)
{
line[length - 1] = '\0'; // Kill \n
std::cout << "# line: " << line << std::endl;
T task (line);

View file

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

View file

@ -7,3 +7,6 @@ text.t
autocomplete.t
parse.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 \
parse.t seq.t
parse.t seq.t att.t # mod.t record.t
CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti
LFLAGS = -L/usr/local/lib
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)
@ -46,3 +46,12 @@ parse.t: parse.t.o $(OBJECTS) test.o
seq.t: seq.t.o $(OBJECTS) test.o
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;
}
////////////////////////////////////////////////////////////////////////////////