os/ossrv/stdcpp/tsrc/Boost_test/graph/src/graphviz_test.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright 2004-5 Trustees of Indiana University
sl@0
     2
sl@0
     3
// Use, modification and distribution is subject to the Boost Software
sl@0
     4
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
sl@0
     5
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     6
sl@0
     7
//
sl@0
     8
// graphviz_test.cpp - Test cases for the Boost.Spirit implementation of a
sl@0
     9
// Graphviz DOT Language reader.
sl@0
    10
//
sl@0
    11
sl@0
    12
// Author: Ronald Garcia
sl@0
    13
/*
sl@0
    14
 * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
sl@0
    15
*/
sl@0
    16
sl@0
    17
//#define BOOST_GRAPH_READ_GRAPHVIZ_ITERATORS
sl@0
    18
#define BOOST_GRAPHVIZ_USE_ISTREAM
sl@0
    19
#include <boost/graph/graphviz.hpp>
sl@0
    20
#include <boost/assign/std/map.hpp>
sl@0
    21
#include <boost/graph/adjacency_list.hpp>
sl@0
    22
#include <boost/graph/graph_traits.hpp>
sl@0
    23
#include <boost/tuple/tuple.hpp>
sl@0
    24
#include <boost/dynamic_property_map.hpp>
sl@0
    25
#include <boost/test/test_tools.hpp>
sl@0
    26
#include <boost/test/floating_point_comparison.hpp>
sl@0
    27
#include <algorithm>
sl@0
    28
#include <string>
sl@0
    29
#include <iostream>
sl@0
    30
#include <iterator>
sl@0
    31
#include <map>
sl@0
    32
#include <utility>
sl@0
    33
sl@0
    34
#ifdef __SYMBIAN32__
sl@0
    35
#include "std_log_result.h"
sl@0
    36
#define LOG_FILENAME_LINE __FILE__, __LINE__
sl@0
    37
#endif
sl@0
    38
using namespace std;
sl@0
    39
using namespace boost;
sl@0
    40
sl@0
    41
#ifndef BOOST_GRAPHVIZ_USE_ISTREAM
sl@0
    42
using namespace boost::spirit;
sl@0
    43
#endif
sl@0
    44
using namespace boost::assign;
sl@0
    45
sl@0
    46
typedef std::string node_t;
sl@0
    47
typedef std::pair<node_t,node_t> edge_t;
sl@0
    48
sl@0
    49
typedef std::map<node_t,float> mass_map_t;
sl@0
    50
typedef std::map<edge_t,double> weight_map_t;
sl@0
    51
sl@0
    52
template <typename Directedness, typename OutEdgeList>
sl@0
    53
bool test_graph(std::istream& dotfile, mass_map_t const& masses,
sl@0
    54
                weight_map_t const& weights,
sl@0
    55
                std::string const& node_id = "node_id") {
sl@0
    56
sl@0
    57
  typedef adjacency_list < OutEdgeList, vecS, Directedness,
sl@0
    58
    property < vertex_name_t, std::string,
sl@0
    59
    property < vertex_color_t, float > >,
sl@0
    60
    property < edge_weight_t, double > > graph_t;
sl@0
    61
  typedef typename graph_traits < graph_t >::edge_descriptor edge_t;
sl@0
    62
  typedef typename graph_traits < graph_t >::vertex_descriptor vertex_t;
sl@0
    63
sl@0
    64
  // Construct a graph and set up the dynamic_property_maps.
sl@0
    65
  graph_t graph(0);
sl@0
    66
  dynamic_properties dp;
sl@0
    67
  typename property_map<graph_t, vertex_name_t>::type name =
sl@0
    68
    get(vertex_name, graph);
sl@0
    69
  dp.property(node_id,name);
sl@0
    70
  typename property_map<graph_t, vertex_color_t>::type mass =
sl@0
    71
    get(vertex_color, graph);
sl@0
    72
  dp.property("mass",mass);
sl@0
    73
  typename property_map<graph_t, edge_weight_t>::type weight =
sl@0
    74
    get(edge_weight, graph);
sl@0
    75
  dp.property("weight",weight);
sl@0
    76
sl@0
    77
  // Read in space characters too!
sl@0
    78
  dotfile >> noskipws;
sl@0
    79
sl@0
    80
  bool result = true;
sl@0
    81
#ifdef BOOST_GRAPHVIZ_USE_ISTREAM
sl@0
    82
  if(read_graphviz(dotfile,graph,dp,node_id)) {
sl@0
    83
#else
sl@0
    84
  std::string data;
sl@0
    85
  std::copy(std::istream_iterator<char>(dotfile),
sl@0
    86
            std::istream_iterator<char>(),
sl@0
    87
            std::back_inserter(data));
sl@0
    88
  if(read_graphviz(data.begin(),data.end(),graph,dp,node_id)) {
sl@0
    89
#endif
sl@0
    90
    // check masses
sl@0
    91
    if(!masses.empty()) {
sl@0
    92
      // assume that all the masses have been set
sl@0
    93
      // for each vertex:
sl@0
    94
      typename graph_traits<graph_t>::vertex_iterator i,j;
sl@0
    95
      for(boost::tie(i,j) = vertices(graph); i != j; ++i) {
sl@0
    96
        //  - get its name
sl@0
    97
        std::string node_name = get(name,*i);
sl@0
    98
        //  - get its mass
sl@0
    99
        float node_mass = get(mass,*i);
sl@0
   100
        float ref_mass = masses.find(node_name)->second;
sl@0
   101
        //  - compare the mass to the result in the table
sl@0
   102
sl@0
   103
        BOOST_CHECK_CLOSE(node_mass, ref_mass, 0.01f);
sl@0
   104
      }
sl@0
   105
    }
sl@0
   106
    // check weights
sl@0
   107
    if(!weights.empty()) {
sl@0
   108
      // assume that all weights have been set
sl@0
   109
      /// for each edge:
sl@0
   110
      typename graph_traits<graph_t>::edge_iterator i,j;
sl@0
   111
      for(boost::tie(i,j) = edges(graph); i != j; ++i) {
sl@0
   112
        //  - get its name
sl@0
   113
        std::pair<std::string,std::string>
sl@0
   114
          edge_name = make_pair(get(name, source(*i,graph)),
sl@0
   115
                                get(name, target(*i,graph)));
sl@0
   116
        // - get its weight
sl@0
   117
        double edge_weight = get(weight,*i);
sl@0
   118
        double ref_weight = weights.find(edge_name)->second;
sl@0
   119
        // - compare the weight to teh result in the table
sl@0
   120
        BOOST_CHECK_CLOSE(edge_weight, ref_weight, 0.01);
sl@0
   121
      }
sl@0
   122
    }
sl@0
   123
sl@0
   124
sl@0
   125
  } else {
sl@0
   126
    std::cerr << "Parsing Failed!\n";
sl@0
   127
    result = false;
sl@0
   128
  }
sl@0
   129
sl@0
   130
  return result;
sl@0
   131
  }
sl@0
   132
sl@0
   133
int test_main(int, char*[]) {
sl@0
   134
sl@0
   135
  typedef istringstream gs_t;
sl@0
   136
sl@0
   137
  // Basic directed graph tests
sl@0
   138
  {
sl@0
   139
    mass_map_t masses;
sl@0
   140
    insert ( masses )  ("a",0.0f) ("c",7.7f) ("e", 6.66f);
sl@0
   141
    gs_t gs("digraph { a  node [mass = 7.7] c e [mass = 6.66] }");
sl@0
   142
    BOOST_CHECK((test_graph<directedS,vecS>(gs,masses,weight_map_t())));
sl@0
   143
  }
sl@0
   144
sl@0
   145
  {
sl@0
   146
    weight_map_t weights;
sl@0
   147
    insert( weights )(make_pair("a","b"),0.0)
sl@0
   148
      (make_pair("c","d"),7.7)(make_pair("e","f"),6.66);
sl@0
   149
    gs_t gs("digraph { a -> b edge [weight = 7.7] "
sl@0
   150
            "c -> d e-> f [weight = 6.66] }");
sl@0
   151
    BOOST_CHECK((test_graph<directedS,vecS>(gs,mass_map_t(),weights)));
sl@0
   152
  }
sl@0
   153
sl@0
   154
  // undirected graph with alternate node_id property name
sl@0
   155
  {
sl@0
   156
    mass_map_t masses;
sl@0
   157
    insert ( masses )  ("a",0.0f) ("c",7.7f) ("e", 6.66f);
sl@0
   158
    gs_t gs("graph { a  node [mass = 7.7] c e [mass = 6.66] }");
sl@0
   159
    BOOST_CHECK((test_graph<undirectedS,vecS>(gs,masses,weight_map_t(),
sl@0
   160
                                             "nodenames")));
sl@0
   161
  }
sl@0
   162
sl@0
   163
  // Basic undirected graph tests
sl@0
   164
  {
sl@0
   165
    mass_map_t masses;
sl@0
   166
    insert ( masses )  ("a",0.0f) ("c",7.7f) ("e", 6.66f);
sl@0
   167
    gs_t gs("graph { a  node [mass = 7.7] c e [mass = 6.66] }");
sl@0
   168
    BOOST_CHECK((test_graph<undirectedS,vecS>(gs,masses,weight_map_t())));
sl@0
   169
  }
sl@0
   170
sl@0
   171
  {
sl@0
   172
    weight_map_t weights;
sl@0
   173
    insert( weights )(make_pair("a","b"),0.0)
sl@0
   174
      (make_pair("c","d"),7.7)(make_pair("e","f"),6.66);
sl@0
   175
    gs_t gs("graph { a -- b eDge [weight = 7.7] "
sl@0
   176
            "c -- d e -- f [weight = 6.66] }");
sl@0
   177
    BOOST_CHECK((test_graph<undirectedS,vecS>(gs,mass_map_t(),weights)));
sl@0
   178
  }
sl@0
   179
sl@0
   180
  // Mismatch directed graph test
sl@0
   181
  {
sl@0
   182
    mass_map_t masses;
sl@0
   183
    insert ( masses )  ("a",0.0f) ("c",7.7f) ("e", 6.66f);
sl@0
   184
    gs_t gs("graph { a  nodE [mass = 7.7] c e [mass = 6.66] }");
sl@0
   185
    try {
sl@0
   186
      test_graph<directedS,vecS>(gs,masses,weight_map_t());
sl@0
   187
    } catch (boost::undirected_graph_error&) {}
sl@0
   188
  }
sl@0
   189
sl@0
   190
  // Mismatch undirected graph test
sl@0
   191
  {
sl@0
   192
    mass_map_t masses;
sl@0
   193
    insert ( masses )  ("a",0.0f) ("c",7.7f) ("e", 6.66f);
sl@0
   194
    gs_t gs("digraph { a  node [mass = 7.7] c e [mass = 6.66] }");
sl@0
   195
    try {
sl@0
   196
      test_graph<undirectedS,vecS>(gs,masses,weight_map_t());
sl@0
   197
      BOOST_ERROR("Failed to throw boost::directed_graph_error.");
sl@0
   198
    } catch (boost::directed_graph_error&) {}
sl@0
   199
  }
sl@0
   200
sl@0
   201
  // Complain about parallel edges
sl@0
   202
  {
sl@0
   203
    weight_map_t weights;
sl@0
   204
    insert( weights )(make_pair("a","b"),7.7);
sl@0
   205
    gs_t gs("diGraph { a -> b [weight = 7.7]  a -> b [weight = 7.7] }");
sl@0
   206
    try {
sl@0
   207
      test_graph<directedS,setS>(gs,mass_map_t(),weights);
sl@0
   208
      BOOST_ERROR("Failed to throw boost::bad_parallel_edge.");
sl@0
   209
    } catch (boost::bad_parallel_edge&) {}
sl@0
   210
  }
sl@0
   211
sl@0
   212
  // Handle parallel edges gracefully
sl@0
   213
  {
sl@0
   214
    weight_map_t weights;
sl@0
   215
    insert( weights )(make_pair("a","b"),7.7);
sl@0
   216
    gs_t gs("digraph { a -> b [weight = 7.7]  a -> b [weight = 7.7] }");
sl@0
   217
    BOOST_CHECK((test_graph<directedS,vecS>(gs,mass_map_t(),weights)));
sl@0
   218
  }
sl@0
   219
                
sl@0
   220
        #ifdef __SYMBIAN32__
sl@0
   221
	 
sl@0
   222
	std_log(LOG_FILENAME_LINE,"[End Test Case ]");
sl@0
   223
sl@0
   224
	testResultXml("graphiz_test");
sl@0
   225
	close_log_file();
sl@0
   226
#endif
sl@0
   227
  return 0;
sl@0
   228
}