Tuesday, November 6, 2018

Found a new usage of getLoadFile()

Initially I was thinking to sunset the getLoadFile() as it's just another dump function for debugging purpose, but now I am going to need it in the search process. The original function will accept a FileNode object and then recursively loop through each path until the last object has reached, then convert each object into the URL string.
std::list<string> FileBot::getLoadedFiles(FileNode *fileNode)
{
    std::list<string> mlist;

    if( fileNode == nullptr || fileNode->sibling.size() == 0 )
        return mlist;

    for( FileNodeListType::iterator it = fileNode->sibling.begin(); it != fileNode->sibling.end(); ++it )
    {
        FileNode *n = (&*it);

        if( n->getType() == 'd' ) {
            std::list<string> subList;
            subList = getLoadedFiles(n);

            mlist.insert(mlist.begin(), subList.begin(), subList.end());
        }
        else {
            string filePath = constructPathAddress(n);
            mlist.push_back(filePath);
        }
    }

    return mlist;
}
This was originally used in path construction process to verify the path has correctly loaded into memory by verifying the URL returned. For now, I need this to retrieve all the FileNode objects that park under a particular FileNode object rather than the URL string. Thus, I am converting the list storage to store the FileNode object instead of string:
std::list<FileNode*> FileBot::getLoadedFiles(FileNode *fileNode)
{
    std::list<FileNode*> mlist;

    ...

    for( FileNodeListType::iterator it = fileNode->sibling.begin(); it != fileNode->sibling.end(); ++it )
    {
        ...

        if( n->getType() == 'd' ) {
           ...
           ...
        }
        else {
            mlist.push_back(n);
        }
    }

    return mlist;
}
On the unit testing site, originally I have the following code to verify my desired URL was loaded into the memory. The std::find is a very useful function to lookup a value in the list.
BOOST_AUTO_TEST_CASE(TL_5, *boost::unit_test::precondition(skipTest(false)))
{
    ...

    // verify the file name was captured
    std::list<string> files = fb.getLoadedFiles(root);

    if( std::find(files.begin(), files.end(), "/home/kokhoe/workspaceqt/debug/FolderA/file_1.txt") == files.end() )
        BOOST_TEST(false);
}
Due to the change to object type, the std::find is unusable anymore. But I found a workaround on this, to lookup a value in the object list, that is to create a new functor for this purpose. The URL is now constructed and perform matching inside functor.
struct FileNodeFinder
{
    FileNodeFinder(const std::string &s) : s_(s) {}

    bool operator() (const FileNode* obj)
    {
        FileBotUnderTest fb;

        return fb.constructPathAddress(obj).compare(s_) == 0 ? true : false ;
    }

private:
    const std::string s_;
};
Thus, the new way of doing work is like this:
BOOST_AUTO_TEST_CASE(TL_5, *boost::unit_test::precondition(skipTest(false)))
{
    ...

    // verify the file name was captured
    std::list<FileNode*>::iterator it = find_if(files.begin(),
                                                files.end(),
                                                FileNodeFinder("/home/kokhoe/workspaceqt/debug/FolderA/file_1.txt"));
    FileNode *n = *it;

    if( it == files.end() )
        BOOST_FAIL("nothing were found");
}

No comments: