Browse Source

Basic workflow test added.

avkonst 12 years ago
parent
commit
3c092ebdc2
44 changed files with 1165 additions and 31 deletions
  1. 4 3
      mainline/core/dir.py
  2. 4 4
      mainline/core/log.py
  3. 8 2
      mainline/export.py
  4. 2 1
      mainline/limit.py
  5. 11 4
      mainline/test.py
  6. 0 17
      mainline/tests/general/test_collect.py
  7. 231 0
      mainline/tests/common.py
  8. 138 0
      mainline/tests/general/test_basic.py
  9. 0 0
      mainline/tests/general/test_basic/sources/.unused.cpp
  10. 0 0
      mainline/tests/general/test_basic/sources/dummy.txt
  11. 51 0
      mainline/tests/general/test_basic/sources/simple.cpp
  12. 0 0
      mainline/tests/general/test_basic/sources_changed/.unused.cpp
  13. 64 0
      mainline/tests/general/test_basic/sources_changed/simple.cpp
  14. 25 0
      mainline/tests/general/test_basic/sources_changed/simple2.cpp
  15. 5 0
      mainline/tests/general/test_basic/test_workflow_collect_default_stderr.gold.txt
  16. 0 0
      mainline/tests/general/test_basic/test_workflow_collect_default_stdout.gold.txt
  17. 5 0
      mainline/tests/general/test_basic/test_workflow_collect_second_stderr.gold.txt
  18. 0 0
      mainline/tests/general/test_basic/test_workflow_collect_second_stdout.gold.txt
  19. 3 0
      mainline/tests/general/test_basic/test_workflow_export_default_stderr.gold.txt
  20. 20 0
      mainline/tests/general/test_basic/test_workflow_export_default_stdout.gold.txt
  21. 3 0
      mainline/tests/general/test_basic/test_workflow_export_second_per_file_stderr.gold.txt
  22. 86 0
      mainline/tests/general/test_basic/test_workflow_export_second_per_file_stdout.gold.txt
  23. 3 0
      mainline/tests/general/test_basic/test_workflow_export_second_stderr.gold.txt
  24. 24 0
      mainline/tests/general/test_basic/test_workflow_export_second_stdout.gold.txt
  25. 2 0
      mainline/tests/general/test_basic/test_workflow_info_default_stderr.gold.txt
  26. 6 0
      mainline/tests/general/test_basic/test_workflow_info_default_stdout.gold.txt
  27. 2 0
      mainline/tests/general/test_basic/test_workflow_info_second_stderr.gold.txt
  28. 6 0
      mainline/tests/general/test_basic/test_workflow_info_second_stdout.gold.txt
  29. 4 0
      mainline/tests/general/test_basic/test_workflow_limit_default_stderr.gold.txt
  30. 32 0
      mainline/tests/general/test_basic/test_workflow_limit_default_stdout.gold.txt
  31. 4 0
      mainline/tests/general/test_basic/test_workflow_limit_second_stderr.gold.txt
  32. 48 0
      mainline/tests/general/test_basic/test_workflow_limit_second_stdout.gold.txt
  33. 4 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_all_stderr.gold.txt
  34. 48 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_all_stdout.gold.txt
  35. 5 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_new_stderr.gold.txt
  36. 16 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_new_stdout.gold.txt
  37. 5 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_touched_stderr.gold.txt
  38. 32 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_touched_stdout.gold.txt
  39. 5 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_trend_stderr.gold.txt
  40. 24 0
      mainline/tests/general/test_basic/test_workflow_limit_second_warn_trend_stdout.gold.txt
  41. 85 0
      mainline/tests/general/test_std_code_cpp/sources/operator_test.hpp
  42. 1 0
      mainline/tests/general/test_std_code_cpp/sources/test.c
  43. 40 0
      mainline/tests/general/test_std_code_cpp/sources/test2.cpp
  44. 109 0
      mainline/tests/general/test_std_code_cpp/sources/test3.cpp

+ 4 - 3
mainline/core/dir.py

@@ -73,6 +73,7 @@ class DirectoryReader():
         def run_recursively(plugin, directory):
             for fname in os.listdir(directory):
                 full_path = os.path.join(directory, fname)
+                norm_path = re.sub(r'''[\\]''', "/", full_path)
                 if plugin.is_file_excluded(fname) == False:
                     if os.path.isdir(full_path):
                         if plugin.non_recursively == False:
@@ -80,9 +81,9 @@ class DirectoryReader():
                     else:
                         parser = plugin.get_plugin_loader().get_parser(full_path)
                         if parser == None:
-                            logging.info("Skipping: " + full_path)
+                            logging.info("Skipping: " + norm_path)
                         else:
-                            logging.info("Processing: " + full_path)
+                            logging.info("Processing: " + norm_path)
                             ts = time.time()
                             f = open(full_path, 'r');
                             text = f.read();
@@ -96,7 +97,7 @@ class DirectoryReader():
                             plugin.get_plugin_loader().get_database_loader().save_file_data(data)
                             logging.debug("-" * 60)
                 else:
-                    logging.info("Excluding: " + full_path)
+                    logging.info("Excluding: " + norm_path)
                     logging.debug("-" * 60)
         
         run_recursively(plugin, directory)

+ 4 - 4
mainline/core/log.py

@@ -26,11 +26,11 @@ class Plugin(core.api.Plugin, core.api.IConfigurable):
     def declare_configuration(self, parser, default_value='INFO'):
         allowed_values = ['DEBUG','INFO','WARNING','ERROR']
         default_value_cur = default_value
-        if os.environ.has_key('general.log-level') and os.environ['general.log-level'] in allowed_values:
-            default_value_cur = os.environ['general.log-level']
+        if os.environ.has_key('METRIXPLUSPLUS_LOG_LEVEL') and os.environ['METRIXPLUSPLUS_LOG_LEVEL'] in allowed_values:
+            default_value_cur = os.environ['METRIXPLUSPLUS_LOG_LEVEL']
         parser.add_option("--general.log-level", default=default_value_cur, choices=allowed_values,
                          help="Defines log level. Possible values are 'DEBUG','INFO','WARNING' or 'ERROR'. "
-                         "Default value is inherited from environment variable 'general.log-level' if set. "
+                         "Default value is inherited from environment variable 'METRIXPLUSPLUS_LOG_LEVEL' if set. "
                          "Otherwise, it is '" + default_value_cur +  "' [default: %default]")
     
     def configure(self, options):
@@ -47,7 +47,7 @@ class Plugin(core.api.Plugin, core.api.IConfigurable):
         
         self.level = log_level
         logging.getLogger().setLevel(self.level)
-        os.environ['general.log-level'] = options.__dict__['general.log_level']
+        os.environ['METRIXPLUSPLUS_LOG_LEVEL'] = options.__dict__['general.log_level']
         logging.warn("Logging enabled with " + options.__dict__['general.log_level'] + " level")
 
 

+ 8 - 2
mainline/export.py

@@ -75,7 +75,7 @@ def main():
         print "{'export': ["
 
     for (ind, path) in enumerate(paths):
-        logging.info("Processing: " + path)
+        logging.info("Processing: " + re.sub(r'''[\\]''', "/", path))
         
         aggregated_data = loader.load_aggregated_data(path, namespaces=namespaces)
         aggregated_data_tree = {}
@@ -163,7 +163,13 @@ def append_diff(main_tree, prev_tree):
                 for key in main_tree[name][field].keys():
                     if key not in prev_tree[name][field].keys():
                         continue
-                    diff[key] = main_tree[name][field][key] - prev_tree[name][field][key]
+                    main_val = main_tree[name][field][key]
+                    prev_val = prev_tree[name][field][key]
+                    if main_val == None:
+                        main_val = 0
+                    if prev_val == None:
+                        prev_val = 0
+                    diff[key] = main_val - prev_val
                 main_tree[name][field]['__diff__'] = diff
             elif (not isinstance(main_tree[name][field], dict)) and (not isinstance(prev_tree[name][field], dict)):
                 if '__diff__' not in main_tree[name]:

+ 2 - 1
mainline/limit.py

@@ -20,6 +20,7 @@
 
 import logging
 import time
+import re
 
 import core.log
 import core.db.loader
@@ -80,7 +81,7 @@ def main():
         modified_file_ids = get_list_of_modified_files(loader, loader_prev)
         
     for path in paths:
-        logging.info("Processing: " + path)
+        logging.info("Processing: " + re.sub(r'''[\\]''', "/", path))
         
         for limit in warn_plugin.iterate_limits():
             logging.info("Applying limit: " + str(limit))

+ 11 - 4
mainline/test.py

@@ -33,10 +33,14 @@ def main():
 
     parser = core.cmdparser.MultiOptionParser(usage="Usage: %prog [options] -- [testgroup-dir-path-1[/testsuite-file-path-1]] ... [...path-N]")
     log_plugin.declare_configuration(parser, default_value='ERROR')
+    parser.add_option("-g", "--general.generate-golds", action="store_true", default=False,
+                         help="If the option is set (True), new gold files are generated (replacing existing) [default: %default]")
 
     (options, args) = parser.parse_args()
     log_plugin.configure(options)
     
+    os.environ['METRIXPLUSPLUS_TEST_GENERATE_GOLDS'] = str(options.__dict__['general.generate_golds'])
+    
     install_dir = os.path.dirname(os.path.abspath(__file__))
     tests_dir = os.path.join(install_dir, 'tests')
     os.environ['METRIXPLUSPLUS_INSTALL_DIR'] = install_dir
@@ -44,16 +48,19 @@ def main():
     if len(args) == 0 or tests_dir == os.path.abspath(args[0]):
         for fname in os.listdir(tests_dir):
             full_path = os.path.join(tests_dir, fname)
-            if os.path.isdir(full_path):
-                exit_code += subprocess.call(itertools.chain(process_data, [full_path]))
+            if os.path.isdir(full_path) and fname != "sources":
+                exit_code += subprocess.call(itertools.chain(process_data, [full_path]),
+                                             cwd=os.environ['METRIXPLUSPLUS_INSTALL_DIR'])
     else:
         for arg in args:
             if os.path.isdir(arg):
-                exit_code += subprocess.call(itertools.chain(process_data, [arg]))
+                exit_code += subprocess.call(itertools.chain(process_data, [arg]),
+                                             cwd=os.environ['METRIXPLUSPLUS_INSTALL_DIR'])
             else:
                 dir_name = os.path.dirname(arg)
                 file_name = os.path.basename(arg)
-                exit_code += subprocess.call(itertools.chain(process_data, [dir_name, "-p", file_name]))
+                exit_code += subprocess.call(itertools.chain(process_data, [dir_name, "-p", file_name]),
+                                             cwd=os.environ['METRIXPLUSPLUS_INSTALL_DIR'])
     return exit_code
             
 if __name__ == '__main__':

+ 0 - 17
mainline/tests/general/test_collect.py

@@ -16,20 +16,3 @@
 #    You should have received a copy of the GNU General Public License
 #    along with Metrix++.  If not, see <http://www.gnu.org/licenses/>.
 #
-
-
-import unittest
-import subprocess
-import os.path
-
-class TestGeneralCollect(unittest.TestCase):
-
-    def setUp(self):
-        pass
-
-    def test_default(self):
-        ret_code = subprocess.call(['python', os.path.join(os.environ['METRIXPLUSPLUS_INSTALL_DIR'], 'collect.py'), '--help'])
-        self.assertEqual(ret_code, 0)
-
-if __name__ == '__main__':
-    unittest.main()

+ 231 - 0
mainline/tests/common.py

@@ -0,0 +1,231 @@
+#
+#    Metrix++, Copyright 2009-2013, Metrix++ Project
+#    Link: http://metrixplusplus.sourceforge.net
+#    
+#    This file is a part of Metrix++ Tool.
+#    
+#    Metrix++ 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, version 3 of the License.
+#    
+#    Metrix++ 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 Metrix++.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import inspect
+import os.path
+import subprocess
+import logging
+import difflib
+import unittest
+import shutil
+
+class ToolRunner(object):
+
+    def __init__(self,
+                 tool_name,
+                 opts_list,
+                 dirs_list = None,
+                 cwd='sources',
+                 prefix = "default",
+                 exit_code = 0,
+                 save_prev = False,
+                 use_prev = False,
+                 check_stderr = None,
+                 remove_exiting_dbfile = None,
+                 remove_exiting_dbfile_prev = False):
+        
+        self.message = ""
+        
+        # identify gold_file_location
+        curframe = inspect.currentframe()
+        calframe = inspect.getouterframes(curframe, 2)
+        test_name = calframe[1][3]
+        suite_name = os.path.splitext(os.path.basename(calframe[1][1]))[0]
+        group_name = os.path.basename(os.path.dirname(calframe[1][1]))
+
+        self.suite_location = os.path.join('tests', group_name, suite_name) 
+        self.test_location = os.path.join(self.suite_location, test_name + "_" + tool_name + "_" + str(prefix))
+
+        db_file = os.path.join(os.environ['METRIXPLUSPLUS_INSTALL_DIR'], self.suite_location, test_name + ".db")
+        self.dbfile = db_file
+        if (remove_exiting_dbfile == True or (remove_exiting_dbfile == None and tool_name == 'collect')) and os.path.exists(db_file):
+            os.unlink(db_file)
+        
+        db_file_prev = os.path.join(os.environ['METRIXPLUSPLUS_INSTALL_DIR'], self.suite_location, test_name + ".prev.db")
+        self.dbfile_prev = db_file_prev
+        if (remove_exiting_dbfile_prev == True or (remove_exiting_dbfile_prev == None and tool_name == 'collect')) and os.path.exists(db_file_prev):
+            os.unlink(db_file_prev)
+
+        self.cwd = cwd
+
+        db_opts = ['--general.db-file=' + db_file]
+        if use_prev == True:
+            db_opts.append('--general.db-file-prev=' + db_file_prev)
+        self.dbopts = db_opts
+        
+        self.dirs_list = [] 
+        if dirs_list != None:
+            for each in dirs_list:
+                self.dirs_list = [each]
+               
+        self.call_args = ['python', os.path.join(os.environ['METRIXPLUSPLUS_INSTALL_DIR'], tool_name + ".py")] \
+                    + db_opts + opts_list + ['--'] + self.dirs_list
+        self.cmd = " ".join(self.call_args)
+        self.exit_code_expected = exit_code
+        self.stderr_lines = check_stderr
+        self.save_prev = save_prev
+        
+    def run(self):
+        child = subprocess.Popen(self.call_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                                 cwd=os.path.join(self.suite_location, self.cwd))
+        (child_stdout, child_stderr) =  child.communicate()
+        self.exit_code = child.returncode
+
+        gold_file_stdout = self.test_location + "_stdout.gold.txt"
+        real_file_stdout = self.test_location + "_stdout.real.txt"
+        diff_file_stdout = self.test_location + "_stdout.diff.html"
+        gold_file_stderr = self.test_location + "_stderr.gold.txt"
+        real_file_stderr = self.test_location + "_stderr.real.txt"
+        diff_file_stderr = self.test_location + "_stderr.diff.html"
+
+        # Regenerate gold files if it was requested
+        if os.environ['METRIXPLUSPLUS_TEST_GENERATE_GOLDS'] == "True":
+            f = open(gold_file_stdout, 'wb');
+            f.write(child_stdout);
+            f.close()
+            if self.stderr_lines != None:
+                f = open(gold_file_stderr, 'wb');
+                f.write(child_stderr);
+                f.close()
+
+        # Match with gold        
+        self.is_stdout_matched = self.inetrnal_compare_with_gold(child_stdout, gold_file_stdout, real_file_stdout, diff_file_stdout)
+        if self.stderr_lines != None:
+            self.is_stderr_matched = self.inetrnal_compare_with_gold(child_stderr, gold_file_stderr, real_file_stderr, diff_file_stderr, self.stderr_lines)
+        else:
+            self.is_stderr_matched = None
+            if self.is_stdout_matched == False:
+                f = open(real_file_stderr, 'wb');
+                f.write(child_stderr);
+                f.close()
+
+        if self.save_prev == True:
+            shutil.copy2(self.dbfile, self.dbfile_prev)                
+        return self
+
+    def inetrnal_compare_with_gold(self, text, gold_file, real_file, diff_file, lines = None):
+        if os.path.exists(gold_file) == False:
+            self.message += "\nGold file does not exist: " + gold_file
+            return False
+        
+        f = open(gold_file, 'rb');
+        gold_text = f.read();
+        f.close()
+
+        gold_to_compare = gold_text
+        text_to_compare = text
+        if lines != None:
+            gold_to_compare = ""
+            text_to_compare = ""
+            gold_lines = gold_text.splitlines(True)
+            text_lines = text.splitlines(True)
+            for each in lines:
+                gold_to_compare += "".join(gold_lines[each[0] : each[1]])
+                text_to_compare += "".join(text_lines[each[0] : each[1]])
+            
+        result = (gold_to_compare == text_to_compare)
+        
+        if result == False:
+            f = open(real_file, 'wb');
+            f.write(text);
+            f.close()
+            
+            diff_text = difflib.HtmlDiff().make_file(gold_to_compare.splitlines(), text_to_compare.splitlines(), "Gold file", "Real output")
+            f = open(diff_file, 'w');
+            f.write(diff_text);
+            f.close()
+        else:
+            if os.path.exists(real_file):
+                os.unlink(real_file)
+            if os.path.exists(diff_file):
+                os.unlink(diff_file)
+        return result 
+    
+    def check_exit_code(self):
+        return self.exit_code == self.exit_code_expected
+
+    def check_stdout(self):
+        return self.is_stdout_matched
+
+    def check_stderr(self):
+        if self.is_stderr_matched == None:
+            return True
+        return self.is_stderr_matched
+
+    def check_all(self):
+        result = self.check_exit_code() and self.check_stdout() and self.check_stderr()
+        if result == False:
+            self.message += "\nCheck for exit code: " + str(self.check_exit_code()) \
+             + ", gold: " + str(self.exit_code_expected)  + ", real: " + str(self.exit_code) + \
+             "\nCheck for stdout: " + str(self.check_stdout()) + "\nCheck for stderr: " + str(self.check_stderr())
+        return result
+    
+    def get_message(self):
+        return self.message
+    
+    def get_cmd(self):
+        return self.cmd    
+
+    def get_description(self):
+        return self.get_message() + "\nProcess: " + self.get_cmd()  + "\nCWD: " + self.cwd       
+
+    def get_dbfile(self):
+        return self.dbfile
+
+    def get_dbfile_prev(self):
+        return self.dbfile_prev
+    
+class TestCase(unittest.TestCase):
+
+    def setUp(self):
+        logging.basicConfig(format="[TEST-LOG]: %(levelname)s:\t%(message)s", level=logging.WARN)
+        
+        log_level = os.environ['METRIXPLUSPLUS_LOG_LEVEL']
+        if log_level == 'ERROR':
+            log_level = logging.ERROR
+        elif log_level == 'WARNING':
+            log_level = logging.WARNING
+        elif log_level == 'INFO':
+            log_level = logging.INFO
+        elif log_level == 'DEBUG':
+            log_level = logging.DEBUG
+        else:
+            raise AssertionError("Unhandled choice of log level")
+        logging.getLogger().setLevel(log_level)
+        
+        self.runners = []
+        
+    def assertExec(self, runner):
+        # keep reference, so files are not removed during test case time
+        self.runners.append(runner)
+        self.assertTrue(runner.check_all(), runner.get_description())
+        
+    def run(self, result=None):
+        self.current_result = result # remember result for use in tearDown
+        unittest.TestCase.run(self, result)
+
+    def tearDown(self):
+        unittest.TestCase.tearDown(self)
+        if self.current_result.wasSuccessful() == True:
+            for each in self.runners:
+                if each.check_all() == True:
+                    if os.path.exists(each.get_dbfile()):
+                        os.unlink(each.get_dbfile())
+                    if os.path.exists(each.get_dbfile_prev()):
+                        os.unlink(each.get_dbfile_prev())

+ 138 - 0
mainline/tests/general/test_basic.py

@@ -0,0 +1,138 @@
+#
+#    Metrix++, Copyright 2009-2013, Metrix++ Project
+#    Link: http://metrixplusplus.sourceforge.net
+#    
+#    This file is a part of Metrix++ Tool.
+#    
+#    Metrix++ 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, version 3 of the License.
+#    
+#    Metrix++ 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 Metrix++.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+import unittest
+
+import tests.common
+
+class TestBasic(tests.common.TestCase):
+
+    def test_workflow(self):
+        
+        # first collection
+        runner = tests.common.ToolRunner('collect',
+                                         ['--std.code.complexity.on',
+                                          '--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)],
+                                         save_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('export',
+                                         ['--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)])
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('limit',
+                                         ['--general.log-level=INFO',
+                                          '--general.max-limit=std.code.complexity:cyclomatic:0'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=4)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('info',
+                                         ['--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=0)
+        self.assertExec(runner.run())
+
+        # second collection
+        runner = tests.common.ToolRunner('collect',
+                                         ['--std.code.complexity.on',
+                                          '--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)],
+                                         prefix='second',
+                                         cwd="sources_changed",
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('export',
+                                         ['--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)],
+                                         prefix='second',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('export',
+                                         ['--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)],
+                                         prefix='second_per_file',
+                                         dirs_list=['./simple.cpp'],
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('limit',
+                                         ['--general.log-level=INFO',
+                                          '--general.max-limit=std.code.complexity:cyclomatic:0'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=6,
+                                         prefix='second',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('limit',
+                                         ['--general.log-level=INFO',
+                                          '--general.max-limit=std.code.complexity:cyclomatic:0',
+                                          '--general.warn=all'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=6,
+                                         prefix='second_warn_all',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('limit',
+                                         ['--general.log-level=INFO',
+                                          '--general.max-limit=std.code.complexity:cyclomatic:0',
+                                          '--general.warn=touched'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=4,
+                                         prefix='second_warn_touched',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('limit',
+                                         ['--general.log-level=INFO',
+                                          '--general.max-limit=std.code.complexity:cyclomatic:0',
+                                          '--general.warn=trend'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=3,
+                                         prefix='second_warn_trend',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('limit',
+                                         ['--general.log-level=INFO',
+                                          '--general.max-limit=std.code.complexity:cyclomatic:0',
+                                          '--general.warn=new'],
+                                         check_stderr=[(0, -1)],
+                                         exit_code=2,
+                                         prefix='second_warn_new',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+        runner = tests.common.ToolRunner('info',
+                                         ['--general.log-level=INFO'],
+                                         check_stderr=[(0, -1)],
+                                         prefix='second',
+                                         use_prev=True)
+        self.assertExec(runner.run())
+
+
+if __name__ == '__main__':
+    unittest.main()

+ 0 - 0
mainline/tests/general/test_basic/sources/.unused.cpp


+ 0 - 0
mainline/tests/general/test_basic/sources/dummy.txt


+ 51 - 0
mainline/tests/general/test_basic/sources/simple.cpp

@@ -0,0 +1,51 @@
+
+
+// Just produce any code in order to test basic workflow
+namespace hmm
+{
+
+class A
+{
+
+	A()
+	{
+		/* first funtion */
+		this->m_member = 10;
+		if (a & b)
+		{
+			for (int i = 0; i < 0 && i > 0; i++)
+			{
+				// crazy, right?
+			}
+		}
+	}
+
+	int func(int param = 5)
+	{
+		class embeded
+		{
+			embeded()
+			{
+				int a = 10;
+				if (true)
+				{
+					// again crazy
+				}
+			}
+		};
+		if (a);
+	}
+
+	int never(int how_long = 999)
+	{
+		while(true)
+		{
+
+		}
+		return 1;
+	}
+
+	int m_member = 10;
+};
+
+}

+ 0 - 0
mainline/tests/general/test_basic/sources_changed/.unused.cpp


+ 64 - 0
mainline/tests/general/test_basic/sources_changed/simple.cpp

@@ -0,0 +1,64 @@
+
+
+// Just produce any code in order to test basic workflow
+namespace hmm
+{
+
+class A
+{
+
+	A()
+	{
+		/* first funtion */
+		this->m_member = 10;
+		if (a & b)
+		{
+			for (int i = 0; i < 0 && i > 0; i++)
+			{
+				// crazy, right?
+			}
+		}
+	}
+
+	int func(int param = 5)
+	{
+		class embeded
+		{
+			embeded()
+			{
+				int a = 10;
+				if (true)
+				{
+					// again crazy
+				}
+
+				while (a == b); // regressed
+			}
+		};
+		if (a);
+	}
+
+	int never(int how_long = 999)
+	{
+		while(true)
+		{
+
+		}
+		return 2; // slightly modified
+	}
+
+	char new_func()
+	{
+		// simple
+	}
+
+	char new_func_complex()
+	{
+		if (true) {}
+		return 'A';
+	}
+
+	int m_member = 10;
+};
+
+}

+ 25 - 0
mainline/tests/general/test_basic/sources_changed/simple2.cpp

@@ -0,0 +1,25 @@
+
+
+// Just produce any code in order to test basic workflow
+namespace hmm
+{
+
+class New_A
+{
+
+	New_A()
+	{
+		/* first funtion */
+		this->m_member = 10;
+		if (a & b)
+		{
+			for (int i = 0; i < 0 && i > 0; i++)
+			{
+				// crazy, right?
+			}
+		}
+	}
+
+};
+
+}

+ 5 - 0
mainline/tests/general/test_basic/test_workflow_collect_default_stderr.gold.txt

@@ -0,0 +1,5 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Excluding: ./.unused.cpp
+[LOG]: INFO:	Skipping: ./dummy.txt
+[LOG]: INFO:	Processing: ./simple.cpp
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.11 seconds. Done

+ 0 - 0
mainline/tests/general/test_basic/test_workflow_collect_default_stdout.gold.txt


+ 5 - 0
mainline/tests/general/test_basic/test_workflow_collect_second_stderr.gold.txt

@@ -0,0 +1,5 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Excluding: ./.unused.cpp
+[LOG]: INFO:	Processing: ./simple.cpp
+[LOG]: INFO:	Processing: ./simple2.cpp
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.05 seconds. Done

+ 0 - 0
mainline/tests/general/test_basic/test_workflow_collect_second_stdout.gold.txt


+ 3 - 0
mainline/tests/general/test_basic/test_workflow_export_default_stderr.gold.txt

@@ -0,0 +1,3 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Processing: 
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.0 seconds. Done

+ 20 - 0
mainline/tests/general/test_basic/test_workflow_export_default_stdout.gold.txt

@@ -0,0 +1,20 @@
+<export>
+
+    <data>
+        <info path="" id="1" />
+        <file-data />
+        <subfiles>
+        </subfiles>
+        <subdirs>
+            <subdir>.</subdir>
+        </subdirs>
+        <aggregated-data>
+            <std.code.complexity>
+                <cyclomatic max="3" total="6.0" avg="1.5" min="1" />
+            </std.code.complexity>
+            <std.code.cpp>
+                <mismatched_brackets max="None" total="0.0" avg="None" min="None" />
+            </std.code.cpp>
+        </aggregated-data>
+    </data>
+</export>

+ 3 - 0
mainline/tests/general/test_basic/test_workflow_export_second_per_file_stderr.gold.txt

@@ -0,0 +1,3 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Processing: ./simple.cpp
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.01 seconds. Done

+ 86 - 0
mainline/tests/general/test_basic/test_workflow_export_second_per_file_stdout.gold.txt

@@ -0,0 +1,86 @@
+<export>
+
+    <data>
+        <info path="./simple.cpp" id="1" />
+        <file-data>
+            <regions>
+                <region>
+                    <info cursor="0" name="__global__" offset_end="639" line_begin="3" type="global" line_end="65" offset_begin="2" />
+                    <data />
+                </region>
+                <region>
+                    <info cursor="4" name="hmm" offset_end="638" line_begin="3" type="namespace" line_end="64" offset_begin="2" />
+                    <data />
+                </region>
+                <region>
+                    <info cursor="7" name="A" offset_end="634" line_begin="7" type="class" line_end="62" offset_begin="76" />
+                    <data />
+                </region>
+                <region>
+                    <info cursor="10" name="A" offset_end="234" line_begin="10" type="function" line_end="21" offset_begin="88" />
+                    <data>
+                        <std.code.complexity cyclomatic="3">
+                            <__diff__ cyclomatic="0" />
+                        </std.code.complexity>
+                    </data>
+                </region>
+                <region>
+                    <info cursor="23" name="func" offset_end="420" line_begin="23" type="function" line_end="39" offset_begin="237" />
+                    <data>
+                        <std.code.complexity cyclomatic="1">
+                            <__diff__ cyclomatic="0" />
+                        </std.code.complexity>
+                    </data>
+                </region>
+                <region>
+                    <info cursor="25" name="embeded" offset_end="406" line_begin="25" type="class" line_end="37" offset_begin="266" />
+                    <data />
+                </region>
+                <region>
+                    <info cursor="27" name="embeded" offset_end="402" line_begin="27" type="function" line_end="36" offset_begin="287" />
+                    <data>
+                        <std.code.complexity cyclomatic="2">
+                            <__diff__ cyclomatic="1" />
+                        </std.code.complexity>
+                    </data>
+                </region>
+                <region>
+                    <info cursor="41" name="never" offset_end="514" line_begin="41" type="function" line_end="48" offset_begin="423" />
+                    <data>
+                        <std.code.complexity cyclomatic="1">
+                            <__diff__ cyclomatic="0" />
+                        </std.code.complexity>
+                    </data>
+                </region>
+                <region>
+                    <info cursor="50" name="new_func" offset_end="550" line_begin="50" type="function" line_end="53" offset_begin="517" />
+                    <data>
+                        <std.code.complexity cyclomatic="0" />
+                    </data>
+                </region>
+                <region>
+                    <info cursor="55" name="new_func_complex" offset_end="611" line_begin="55" type="function" line_end="59" offset_begin="553" />
+                    <data>
+                        <std.code.complexity cyclomatic="1" />
+                    </data>
+                </region>
+            </regions>
+        </file-data>
+        <subfiles>
+        </subfiles>
+        <subdirs>
+        </subdirs>
+        <aggregated-data>
+            <std.code.complexity>
+                <cyclomatic max="3" total="8.0" avg="1.33333333333" min="0">
+                    <__diff__ max="0" total="2.0" avg="-0.166666666667" min="-1" />
+                </cyclomatic>
+            </std.code.complexity>
+            <std.code.cpp>
+                <mismatched_brackets max="None" total="0.0" avg="None" min="None">
+                    <__diff__ max="0" total="0.0" avg="0" min="0" />
+                </mismatched_brackets>
+            </std.code.cpp>
+        </aggregated-data>
+    </data>
+</export>

+ 3 - 0
mainline/tests/general/test_basic/test_workflow_export_second_stderr.gold.txt

@@ -0,0 +1,3 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Processing: 
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.02 seconds. Done

+ 24 - 0
mainline/tests/general/test_basic/test_workflow_export_second_stdout.gold.txt

@@ -0,0 +1,24 @@
+<export>
+
+    <data>
+        <info path="" id="1" />
+        <file-data />
+        <subfiles>
+        </subfiles>
+        <subdirs>
+            <subdir>.</subdir>
+        </subdirs>
+        <aggregated-data>
+            <std.code.complexity>
+                <cyclomatic max="3" total="11.0" avg="1.57142857143" min="0">
+                    <__diff__ max="0" total="5.0" avg="0.0714285714286" min="-1" />
+                </cyclomatic>
+            </std.code.complexity>
+            <std.code.cpp>
+                <mismatched_brackets max="None" total="0.0" avg="None" min="None">
+                    <__diff__ max="0" total="0.0" avg="0" min="0" />
+                </mismatched_brackets>
+            </std.code.cpp>
+        </aggregated-data>
+    </data>
+</export>

+ 2 - 0
mainline/tests/general/test_basic/test_workflow_info_default_stderr.gold.txt

@@ -0,0 +1,2 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.0 seconds. Done

+ 6 - 0
mainline/tests/general/test_basic/test_workflow_info_default_stdout.gold.txt

@@ -0,0 +1,6 @@
+Info data:
+	version	=>	1.0
+	core.log:version	=>	1.0
+	std.code.complexity:version	=>	1.0
+	std.code.cpp:version	=>	1.1
+	std.code.cpp:files	=>	*.c,*.cpp,*.h,*.hpp

+ 2 - 0
mainline/tests/general/test_basic/test_workflow_info_second_stderr.gold.txt

@@ -0,0 +1,2 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: WARNING:	Exit code: 0. Time spent: 0.01 seconds. Done

+ 6 - 0
mainline/tests/general/test_basic/test_workflow_info_second_stdout.gold.txt

@@ -0,0 +1,6 @@
+Info data:
+	version	=>	1.0
+	core.log:version	=>	1.0
+	std.code.complexity:version	=>	1.0
+	std.code.cpp:version	=>	1.1
+	std.code.cpp:files	=>	*.c,*.cpp,*.h,*.hpp

+ 4 - 0
mainline/tests/general/test_basic/test_workflow_limit_default_stderr.gold.txt

@@ -0,0 +1,4 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Processing: 
+[LOG]: INFO:	Applying limit: namespace 'std.code.complexity', filter '('cyclomatic', '>', 0.0)'
+[LOG]: WARNING:	Exit code: 4. Time spent: 0.0 seconds. Done

+ 32 - 0
mainline/tests/general/test_basic/test_workflow_limit_default_stdout.gold.txt

@@ -0,0 +1,32 @@
+./simple.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : A
+	Metric value   : 3
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple.cpp:23: warning: Metric 'std.code.complexity/cyclomatic' for region 'func' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : func
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple.cpp:27: warning: Metric 'std.code.complexity/cyclomatic' for region 'embeded' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : embeded
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple.cpp:39: warning: Metric 'std.code.complexity/cyclomatic' for region 'never' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : never
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+

+ 4 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_stderr.gold.txt

@@ -0,0 +1,4 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Processing: 
+[LOG]: INFO:	Applying limit: namespace 'std.code.complexity', filter '('cyclomatic', '>', 0.0)'
+[LOG]: WARNING:	Exit code: 6. Time spent: 0.01 seconds. Done

+ 48 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_stdout.gold.txt

@@ -0,0 +1,48 @@
+./simple.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : A
+	Metric value   : 3
+	Modified       : False
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:23: warning: Metric 'std.code.complexity/cyclomatic' for region 'func' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : func
+	Metric value   : 1
+	Modified       : False
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:27: warning: Metric 'std.code.complexity/cyclomatic' for region 'embeded' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : embeded
+	Metric value   : 2
+	Modified       : True
+	Change trend   : +1
+	Limit          : 0.0
+
+./simple.cpp:41: warning: Metric 'std.code.complexity/cyclomatic' for region 'never' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : never
+	Metric value   : 1
+	Modified       : True
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:55: warning: Metric 'std.code.complexity/cyclomatic' for region 'new_func_complex' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : new_func_complex
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple2.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'New_A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : New_A
+	Metric value   : 3
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+

+ 4 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_all_stderr.gold.txt

@@ -0,0 +1,4 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Processing: 
+[LOG]: INFO:	Applying limit: namespace 'std.code.complexity', filter '('cyclomatic', '>', 0.0)'
+[LOG]: WARNING:	Exit code: 6. Time spent: 0.01 seconds. Done

+ 48 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_all_stdout.gold.txt

@@ -0,0 +1,48 @@
+./simple.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : A
+	Metric value   : 3
+	Modified       : False
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:23: warning: Metric 'std.code.complexity/cyclomatic' for region 'func' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : func
+	Metric value   : 1
+	Modified       : False
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:27: warning: Metric 'std.code.complexity/cyclomatic' for region 'embeded' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : embeded
+	Metric value   : 2
+	Modified       : True
+	Change trend   : +1
+	Limit          : 0.0
+
+./simple.cpp:41: warning: Metric 'std.code.complexity/cyclomatic' for region 'never' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : never
+	Metric value   : 1
+	Modified       : True
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:55: warning: Metric 'std.code.complexity/cyclomatic' for region 'new_func_complex' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : new_func_complex
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple2.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'New_A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : New_A
+	Metric value   : 3
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+

+ 5 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_new_stderr.gold.txt

@@ -0,0 +1,5 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Identifying changed files...
+[LOG]: INFO:	Processing: 
+[LOG]: INFO:	Applying limit: namespace 'std.code.complexity', filter '('cyclomatic', '>', 0.0)'
+[LOG]: WARNING:	Exit code: 2. Time spent: 0.01 seconds. Done

+ 16 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_new_stdout.gold.txt

@@ -0,0 +1,16 @@
+./simple.cpp:55: warning: Metric 'std.code.complexity/cyclomatic' for region 'new_func_complex' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : new_func_complex
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple2.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'New_A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : New_A
+	Metric value   : 3
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+

+ 5 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_touched_stderr.gold.txt

@@ -0,0 +1,5 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Identifying changed files...
+[LOG]: INFO:	Processing: 
+[LOG]: INFO:	Applying limit: namespace 'std.code.complexity', filter '('cyclomatic', '>', 0.0)'
+[LOG]: WARNING:	Exit code: 4. Time spent: 0.01 seconds. Done

+ 32 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_touched_stdout.gold.txt

@@ -0,0 +1,32 @@
+./simple.cpp:27: warning: Metric 'std.code.complexity/cyclomatic' for region 'embeded' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : embeded
+	Metric value   : 2
+	Modified       : True
+	Change trend   : +1
+	Limit          : 0.0
+
+./simple.cpp:41: warning: Metric 'std.code.complexity/cyclomatic' for region 'never' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : never
+	Metric value   : 1
+	Modified       : True
+	Change trend   : 0
+	Limit          : 0.0
+
+./simple.cpp:55: warning: Metric 'std.code.complexity/cyclomatic' for region 'new_func_complex' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : new_func_complex
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple2.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'New_A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : New_A
+	Metric value   : 3
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+

+ 5 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_trend_stderr.gold.txt

@@ -0,0 +1,5 @@
+[LOG]: WARNING:	Logging enabled with INFO level
+[LOG]: INFO:	Identifying changed files...
+[LOG]: INFO:	Processing: 
+[LOG]: INFO:	Applying limit: namespace 'std.code.complexity', filter '('cyclomatic', '>', 0.0)'
+[LOG]: WARNING:	Exit code: 3. Time spent: 0.01 seconds. Done

+ 24 - 0
mainline/tests/general/test_basic/test_workflow_limit_second_warn_trend_stdout.gold.txt

@@ -0,0 +1,24 @@
+./simple.cpp:27: warning: Metric 'std.code.complexity/cyclomatic' for region 'embeded' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : embeded
+	Metric value   : 2
+	Modified       : True
+	Change trend   : +1
+	Limit          : 0.0
+
+./simple.cpp:55: warning: Metric 'std.code.complexity/cyclomatic' for region 'new_func_complex' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : new_func_complex
+	Metric value   : 1
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+
+./simple2.cpp:10: warning: Metric 'std.code.complexity/cyclomatic' for region 'New_A' exceeds the limit.
+	Metric name    : std.code.complexity/cyclomatic
+	Region name    : New_A
+	Metric value   : 3
+	Modified       : None
+	Change trend   : None
+	Limit          : 0.0
+

+ 85 - 0
mainline/tests/general/test_std_code_cpp/sources/operator_test.hpp

@@ -0,0 +1,85 @@
+
+namespace {
+/*!
+       *  Finds the optimal cycle ratio of the policy graph
+       */
+      float_t policy_mcr()
+      {
+        std::fill(m_col_bfs.begin(), m_col_bfs.end(), my_white);
+        color_map_t vcm_ = color_map_t(m_col_bfs.begin(), m_vim);
+        typename graph_traits<Graph>::vertex_iterator uv_itr, vie;
+        boost::tie(uv_itr, vie) = vertices(m_g);
+        float_t mcr = m_bound;
+        while ( (uv_itr = std::find_if(uv_itr, vie,
+                                       boost::bind(std::equal_to<my_color_type>(),
+                                                   my_white,
+                                                   boost::bind(&color_map_t::operator[], vcm_, _1)
+                                                   )
+                                       )
+                 ) != vie )
+          ///While there are undiscovered vertices
+          {
+            vertex_t gv = find_cycle_vertex(*uv_itr);
+            float_t cr = cycle_ratio(gv) ;
+            mcr_bfv(gv, cr, vcm_);
+            if ( m_cmp(mcr, cr) )  mcr = cr;
+            ++uv_itr;
+          }
+        return mcr;
+      }
+
+      function_after(){}
+}
+
+
+class ALL_operators {
+	operator int () {}
+	operator new () {}
+	operator delete () {}
+	operator new[ ] () {}
+	operator delete [] () {}
+	operator+ () {}
+	operator - () {}
+	operator * () {}
+	operator / () {}
+	operator= () {}
+	operator< () {}
+	operator > () {}
+	operator+= () {}
+	operator -= () {}
+	operator*= () {}
+	operator/= () {}
+	operator<<() {}
+	operator >> () {}
+	operator <<=() {}
+	operator>>=() {}
+	operator==() {}
+	operator!=() {}
+	operator<=() {}
+	operator >= () {}
+	operator ++ () {}
+	operator--() {}
+	operator%() {}
+	operator &() {}
+	operator ^() {}
+	operator !() {}
+	operator|() {}
+	operator~() {}
+	operator &=() {}
+	operator ^=() {}
+	operator |=() {}
+	operator &&() {}
+	operator ||  () {}
+	operator %=() {}
+	operator []  () {}
+	operator  ()  () {}
+	operator() () {}
+	operator()(){}
+	operator()   (){}
+	operator ()() {}
+	operator ()(){}
+	operator ,() {}
+	operator ->*() {}
+	operator->() {}
+	operator.() {}
+};

File diff suppressed because it is too large
+ 1 - 0
mainline/tests/general/test_std_code_cpp/sources/test.c


+ 40 - 0
mainline/tests/general/test_std_code_cpp/sources/test2.cpp

@@ -0,0 +1,40 @@
+#ifdef preprocessor___
+
+   	   #endif
+
+class A
+{
+	A() : m_asign(0), asd(4)
+	{
+if(){}
+	}int method()
+	{
+		return 0;
+	}int operator ++ ()
+	{
+		return 0;
+	}
+
+	int m_asign;
+};
+
+//
+namespace aaa {
+int main(int a, string b)
+{
+	return 0;
+}
+}
+
+"text" // C++ comments
+"text________________"
+"text" /* C comment */
+"text________________"
+"multiline____________
+_text________________"
+"multiline____________
+_text________________"
+"text" /* C multiline_
+_____comment */ "text"
+"text" /* C multiline_
+_____comment */ "text"

+ 109 - 0
mainline/tests/general/test_std_code_cpp/sources/test3.cpp

@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2006-2007, Johan Thelin
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *     * Neither the name of APress nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <QApplication>
+
+#include <QFontDialog>
+#include <QColorDialog>
+
+class Tester : public QWidget
+{public:
+  void doColor()
+  /* haha */
+  {
+    QColor color = QColorDialog::getColor(Qt::yellow, this );
+    if( color.isValid() )
+    {
+
+      qDebug( "ok" );
+    }
+  }
+#define asdsads
+#define asdsads
+#define asdsads
+
+  void doFont()
+#define asd
+  {
+    bool ok;
+    QFont font = QFontDialog::getFont(
+                    &ok,
+                    QFont( "Arial", 18 ),
+                    this,
+                    tr("Pick a font") );
+    if( ok )
+    {
+      qDebug( "ok" );
+    }
+  }
+
+}} // non-matching brackets for test!!
+#define asdsads
+#define asdsads
+#define asdsads
+  void doFont222()
+
+#define asd
+  {
+    bool ok;
+    QFont font = QFontDialog::getFont(
+                    &ok,
+                    QFont( "Arial", 18 ),
+                    this,
+                    tr("Pick a font") );
+    if(){}
+    if( ok )
+    {
+      qDebug( "ok" );
+    }
+  }
+};
+
+namespace not_closed { // non matching open bracket for test
+int main( int argc, char **argv )
+{
+  QApplication app( argc, argv );
+
+  Tester t;
+  t.doColor();
+  t.doFont();
+
+  return 0;
+}
+
+namespace {
+	typedef struct{
+
+	} aa;
+}
+
+
+