From 585d0941bb44359e49a59d6d32c78652146fd85d Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 23 Jul 2017 23:03:21 +0200 Subject: [PATCH] RBA Unit test enhancements - Include a copy of the unit test framework so we're no longer depending on incompatible versions for Ruby 1 and 2. - Avoid duplication of path entries in unit tests --- testdata/python/basic.py | 17 + testdata/python/dbLayoutTest.py | 17 + testdata/python/dbPCells.py | 17 + testdata/python/dbRegionTest.py | 17 + testdata/python/qtbinding.py | 17 + testdata/python/tlTest.py | 17 + testdata/ruby/antTest.rb | 22 +- testdata/ruby/basic.rb | 21 +- testdata/ruby/dbBooleanTest.rb | 21 +- testdata/ruby/dbBoxTest.rb | 22 +- testdata/ruby/dbCellInstArrayTest.rb | 22 +- testdata/ruby/dbCellMapping.rb | 22 +- testdata/ruby/dbEdgePairTest.rb | 22 +- testdata/ruby/dbEdgePairsTest.rb | 22 +- testdata/ruby/dbEdgeTest.rb | 22 +- testdata/ruby/dbEdgesTest.rb | 22 +- testdata/ruby/dbGlyphs.rb | 22 +- testdata/ruby/dbInstElementTest.rb | 22 +- testdata/ruby/dbInstanceTest.rb | 22 +- testdata/ruby/dbLayerMapping.rb | 22 +- testdata/ruby/dbLayout.rb | 22 +- testdata/ruby/dbLayoutDiff.rb | 22 +- testdata/ruby/dbLayoutQuery.rb | 23 +- testdata/ruby/dbLayoutTest.rb | 22 +- testdata/ruby/dbMatrix.rb | 22 +- testdata/ruby/dbPCells.rb | 22 +- testdata/ruby/dbPathTest.rb | 22 +- testdata/ruby/dbPointTest.rb | 22 +- testdata/ruby/dbPolygonTest.rb | 22 +- testdata/ruby/dbRegionTest.rb | 22 +- testdata/ruby/dbShapesTest.rb | 22 +- testdata/ruby/dbSimplePolygonTest.rb | 22 +- testdata/ruby/dbTextTest.rb | 22 +- testdata/ruby/dbTilingProcessorTest.rb | 22 +- testdata/ruby/dbTransTest.rb | 22 +- testdata/ruby/dbVectorTest.rb | 22 +- testdata/ruby/edtTest.rb | 22 +- testdata/ruby/extNetTracer.rb | 22 +- testdata/ruby/imgObject.rb | 22 +- testdata/ruby/layLayers.rb | 22 +- testdata/ruby/layLayoutView.rb | 22 +- testdata/ruby/layMarkers.rb | 22 +- testdata/ruby/layMenuTest.rb | 22 +- testdata/ruby/laySession.rb | 22 +- testdata/ruby/layTechnologies.rb | 22 +- testdata/ruby/qtbinding.rb | 22 +- testdata/ruby/rdbTest.rb | 22 +- testdata/ruby/test_prologue.rb | 7 +- testdata/ruby/tlTest.rb | 22 +- testdata/vendor/ruby/test/unit.rb | 505 ++++ .../ruby/test/unit/assertion-failed-error.rb | 25 + testdata/vendor/ruby/test/unit/assertions.rb | 2219 +++++++++++++++++ .../ruby/test/unit/attribute-matcher.rb | 26 + testdata/vendor/ruby/test/unit/attribute.rb | 158 ++ .../ruby/test/unit/auto-runner-loader.rb | 17 + testdata/vendor/ruby/test/unit/autorunner.rb | 513 ++++ .../ruby/test/unit/code-snippet-fetcher.rb | 58 + testdata/vendor/ruby/test/unit/collector.rb | 73 + .../ruby/test/unit/collector/descendant.rb | 19 + .../vendor/ruby/test/unit/collector/dir.rb | 108 + .../vendor/ruby/test/unit/collector/load.rb | 200 ++ .../ruby/test/unit/collector/objectspace.rb | 34 + .../vendor/ruby/test/unit/collector/xml.rb | 249 ++ .../vendor/ruby/test/unit/color-scheme.rb | 198 ++ testdata/vendor/ruby/test/unit/color.rb | 134 + testdata/vendor/ruby/test/unit/data.rb | 262 ++ testdata/vendor/ruby/test/unit/diff.rb | 746 ++++++ testdata/vendor/ruby/test/unit/error.rb | 158 ++ .../ruby/test/unit/exception-handler.rb | 82 + testdata/vendor/ruby/test/unit/failure.rb | 169 ++ .../ruby/test/unit/fault-location-detector.rb | 100 + testdata/vendor/ruby/test/unit/fixture.rb | 295 +++ .../vendor/ruby/test/unit/notification.rb | 136 + testdata/vendor/ruby/test/unit/omission.rb | 195 ++ testdata/vendor/ruby/test/unit/pending.rb | 154 ++ testdata/vendor/ruby/test/unit/priority.rb | 192 ++ .../vendor/ruby/test/unit/runner/console.rb | 59 + .../vendor/ruby/test/unit/runner/emacs.rb | 8 + testdata/vendor/ruby/test/unit/runner/xml.rb | 15 + .../ruby/test/unit/test-suite-creator.rb | 89 + testdata/vendor/ruby/test/unit/testcase.rb | 812 ++++++ testdata/vendor/ruby/test/unit/testresult.rb | 125 + testdata/vendor/ruby/test/unit/testsuite.rb | 175 ++ .../ruby/test/unit/ui/console/outputlevel.rb | 15 + .../ruby/test/unit/ui/console/testrunner.rb | 693 +++++ .../ruby/test/unit/ui/emacs/testrunner.rb | 49 + .../vendor/ruby/test/unit/ui/testrunner.rb | 53 + .../ruby/test/unit/ui/testrunnermediator.rb | 112 + .../ruby/test/unit/ui/testrunnerutilities.rb | 41 + .../ruby/test/unit/ui/xml/testrunner.rb | 224 ++ .../ruby/test/unit/util/backtracefilter.rb | 59 + .../test/unit/util/method-owner-finder.rb | 28 + .../vendor/ruby/test/unit/util/observable.rb | 90 + testdata/vendor/ruby/test/unit/util/output.rb | 31 + .../vendor/ruby/test/unit/util/procwrapper.rb | 48 + testdata/vendor/ruby/test/unit/version.rb | 5 + 96 files changed, 10744 insertions(+), 44 deletions(-) create mode 100644 testdata/vendor/ruby/test/unit.rb create mode 100644 testdata/vendor/ruby/test/unit/assertion-failed-error.rb create mode 100644 testdata/vendor/ruby/test/unit/assertions.rb create mode 100644 testdata/vendor/ruby/test/unit/attribute-matcher.rb create mode 100644 testdata/vendor/ruby/test/unit/attribute.rb create mode 100644 testdata/vendor/ruby/test/unit/auto-runner-loader.rb create mode 100644 testdata/vendor/ruby/test/unit/autorunner.rb create mode 100644 testdata/vendor/ruby/test/unit/code-snippet-fetcher.rb create mode 100644 testdata/vendor/ruby/test/unit/collector.rb create mode 100644 testdata/vendor/ruby/test/unit/collector/descendant.rb create mode 100644 testdata/vendor/ruby/test/unit/collector/dir.rb create mode 100644 testdata/vendor/ruby/test/unit/collector/load.rb create mode 100644 testdata/vendor/ruby/test/unit/collector/objectspace.rb create mode 100644 testdata/vendor/ruby/test/unit/collector/xml.rb create mode 100644 testdata/vendor/ruby/test/unit/color-scheme.rb create mode 100644 testdata/vendor/ruby/test/unit/color.rb create mode 100644 testdata/vendor/ruby/test/unit/data.rb create mode 100644 testdata/vendor/ruby/test/unit/diff.rb create mode 100644 testdata/vendor/ruby/test/unit/error.rb create mode 100644 testdata/vendor/ruby/test/unit/exception-handler.rb create mode 100644 testdata/vendor/ruby/test/unit/failure.rb create mode 100644 testdata/vendor/ruby/test/unit/fault-location-detector.rb create mode 100644 testdata/vendor/ruby/test/unit/fixture.rb create mode 100644 testdata/vendor/ruby/test/unit/notification.rb create mode 100644 testdata/vendor/ruby/test/unit/omission.rb create mode 100644 testdata/vendor/ruby/test/unit/pending.rb create mode 100644 testdata/vendor/ruby/test/unit/priority.rb create mode 100644 testdata/vendor/ruby/test/unit/runner/console.rb create mode 100644 testdata/vendor/ruby/test/unit/runner/emacs.rb create mode 100644 testdata/vendor/ruby/test/unit/runner/xml.rb create mode 100644 testdata/vendor/ruby/test/unit/test-suite-creator.rb create mode 100644 testdata/vendor/ruby/test/unit/testcase.rb create mode 100644 testdata/vendor/ruby/test/unit/testresult.rb create mode 100644 testdata/vendor/ruby/test/unit/testsuite.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/console/outputlevel.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/console/testrunner.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/emacs/testrunner.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/testrunner.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/testrunnermediator.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/testrunnerutilities.rb create mode 100644 testdata/vendor/ruby/test/unit/ui/xml/testrunner.rb create mode 100644 testdata/vendor/ruby/test/unit/util/backtracefilter.rb create mode 100644 testdata/vendor/ruby/test/unit/util/method-owner-finder.rb create mode 100644 testdata/vendor/ruby/test/unit/util/observable.rb create mode 100644 testdata/vendor/ruby/test/unit/util/output.rb create mode 100644 testdata/vendor/ruby/test/unit/util/procwrapper.rb create mode 100644 testdata/vendor/ruby/test/unit/version.rb diff --git a/testdata/python/basic.py b/testdata/python/basic.py index a11d98a2e..38595d8e8 100644 --- a/testdata/python/basic.py +++ b/testdata/python/basic.py @@ -1,3 +1,20 @@ +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + import pya import unittest diff --git a/testdata/python/dbLayoutTest.py b/testdata/python/dbLayoutTest.py index de343d304..54683a58c 100644 --- a/testdata/python/dbLayoutTest.py +++ b/testdata/python/dbLayoutTest.py @@ -1,3 +1,20 @@ +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + import pya import unittest diff --git a/testdata/python/dbPCells.py b/testdata/python/dbPCells.py index 78dd50111..b5320462a 100644 --- a/testdata/python/dbPCells.py +++ b/testdata/python/dbPCells.py @@ -1,3 +1,20 @@ +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + import pya import unittest diff --git a/testdata/python/dbRegionTest.py b/testdata/python/dbRegionTest.py index 4001d50ac..b12097521 100644 --- a/testdata/python/dbRegionTest.py +++ b/testdata/python/dbRegionTest.py @@ -1,3 +1,20 @@ +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + import pya import unittest diff --git a/testdata/python/qtbinding.py b/testdata/python/qtbinding.py index ea7e3593f..494c363d4 100644 --- a/testdata/python/qtbinding.py +++ b/testdata/python/qtbinding.py @@ -1,3 +1,20 @@ +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + import pya import unittest diff --git a/testdata/python/tlTest.py b/testdata/python/tlTest.py index 7b6a89be0..3a79388b1 100644 --- a/testdata/python/tlTest.py +++ b/testdata/python/tlTest.py @@ -1,3 +1,20 @@ +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + import pya import unittest diff --git a/testdata/ruby/antTest.rb b/testdata/ruby/antTest.rb index 5ddd0dd63..3f063a023 100644 --- a/testdata/ruby/antTest.rb +++ b/testdata/ruby/antTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/basic.rb b/testdata/ruby/basic.rb index c9e57934c..ed9f3d339 100644 --- a/testdata/ruby/basic.rb +++ b/testdata/ruby/basic.rb @@ -1,6 +1,25 @@ # encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbBooleanTest.rb b/testdata/ruby/dbBooleanTest.rb index 7164f3d5e..1d1046ab0 100644 --- a/testdata/ruby/dbBooleanTest.rb +++ b/testdata/ruby/dbBooleanTest.rb @@ -1,6 +1,25 @@ +# encoding: UTF-8 +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA -$:.push(File::dirname($0)) +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbBoxTest.rb b/testdata/ruby/dbBoxTest.rb index 90035af56..d998ca9e5 100644 --- a/testdata/ruby/dbBoxTest.rb +++ b/testdata/ruby/dbBoxTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbCellInstArrayTest.rb b/testdata/ruby/dbCellInstArrayTest.rb index 956a12367..af029b25c 100644 --- a/testdata/ruby/dbCellInstArrayTest.rb +++ b/testdata/ruby/dbCellInstArrayTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbCellMapping.rb b/testdata/ruby/dbCellMapping.rb index 1d08f99a2..3dfb7167a 100644 --- a/testdata/ruby/dbCellMapping.rb +++ b/testdata/ruby/dbCellMapping.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbEdgePairTest.rb b/testdata/ruby/dbEdgePairTest.rb index 9eb929aeb..d1c4e6ba1 100644 --- a/testdata/ruby/dbEdgePairTest.rb +++ b/testdata/ruby/dbEdgePairTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb index f4b05ed17..3ea896d6a 100644 --- a/testdata/ruby/dbEdgePairsTest.rb +++ b/testdata/ruby/dbEdgePairsTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbEdgeTest.rb b/testdata/ruby/dbEdgeTest.rb index a80fa7929..4cc0382cf 100644 --- a/testdata/ruby/dbEdgeTest.rb +++ b/testdata/ruby/dbEdgeTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbEdgesTest.rb b/testdata/ruby/dbEdgesTest.rb index c6eb7b776..b4f90363e 100644 --- a/testdata/ruby/dbEdgesTest.rb +++ b/testdata/ruby/dbEdgesTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbGlyphs.rb b/testdata/ruby/dbGlyphs.rb index f4c041955..d72218785 100644 --- a/testdata/ruby/dbGlyphs.rb +++ b/testdata/ruby/dbGlyphs.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbInstElementTest.rb b/testdata/ruby/dbInstElementTest.rb index 3c438abaf..d3e66cfd8 100644 --- a/testdata/ruby/dbInstElementTest.rb +++ b/testdata/ruby/dbInstElementTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbInstanceTest.rb b/testdata/ruby/dbInstanceTest.rb index 5a6fbbf48..0c99b8280 100644 --- a/testdata/ruby/dbInstanceTest.rb +++ b/testdata/ruby/dbInstanceTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbLayerMapping.rb b/testdata/ruby/dbLayerMapping.rb index 72769ecd7..c1e353a01 100644 --- a/testdata/ruby/dbLayerMapping.rb +++ b/testdata/ruby/dbLayerMapping.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbLayout.rb b/testdata/ruby/dbLayout.rb index d474cadb7..acd3a7b20 100644 --- a/testdata/ruby/dbLayout.rb +++ b/testdata/ruby/dbLayout.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbLayoutDiff.rb b/testdata/ruby/dbLayoutDiff.rb index 41d96ab81..26fe9e45c 100644 --- a/testdata/ruby/dbLayoutDiff.rb +++ b/testdata/ruby/dbLayoutDiff.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbLayoutQuery.rb b/testdata/ruby/dbLayoutQuery.rb index cfc976a0b..cbac516d6 100644 --- a/testdata/ruby/dbLayoutQuery.rb +++ b/testdata/ruby/dbLayoutQuery.rb @@ -1,4 +1,25 @@ -$:.push(File::dirname($0)) +# encoding: UTF-8 + +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbLayoutTest.rb b/testdata/ruby/dbLayoutTest.rb index 8a640b9ec..75f0270ed 100644 --- a/testdata/ruby/dbLayoutTest.rb +++ b/testdata/ruby/dbLayoutTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbMatrix.rb b/testdata/ruby/dbMatrix.rb index a998f8891..f67e89736 100644 --- a/testdata/ruby/dbMatrix.rb +++ b/testdata/ruby/dbMatrix.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbPCells.rb b/testdata/ruby/dbPCells.rb index dee4a5cbe..a44418f63 100644 --- a/testdata/ruby/dbPCells.rb +++ b/testdata/ruby/dbPCells.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbPathTest.rb b/testdata/ruby/dbPathTest.rb index 3c452d9b1..8a09da07d 100644 --- a/testdata/ruby/dbPathTest.rb +++ b/testdata/ruby/dbPathTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbPointTest.rb b/testdata/ruby/dbPointTest.rb index a65f96ff1..63cab774c 100644 --- a/testdata/ruby/dbPointTest.rb +++ b/testdata/ruby/dbPointTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbPolygonTest.rb b/testdata/ruby/dbPolygonTest.rb index a6123d574..04d1c9e14 100644 --- a/testdata/ruby/dbPolygonTest.rb +++ b/testdata/ruby/dbPolygonTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbRegionTest.rb b/testdata/ruby/dbRegionTest.rb index d59529d29..a39d8d809 100644 --- a/testdata/ruby/dbRegionTest.rb +++ b/testdata/ruby/dbRegionTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbShapesTest.rb b/testdata/ruby/dbShapesTest.rb index b1a447fb9..08ea539c1 100644 --- a/testdata/ruby/dbShapesTest.rb +++ b/testdata/ruby/dbShapesTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbSimplePolygonTest.rb b/testdata/ruby/dbSimplePolygonTest.rb index 3bb75e48a..891d3a237 100644 --- a/testdata/ruby/dbSimplePolygonTest.rb +++ b/testdata/ruby/dbSimplePolygonTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbTextTest.rb b/testdata/ruby/dbTextTest.rb index 3cf3e1eef..f370debc2 100644 --- a/testdata/ruby/dbTextTest.rb +++ b/testdata/ruby/dbTextTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbTilingProcessorTest.rb b/testdata/ruby/dbTilingProcessorTest.rb index 9d97c70b4..d192f3073 100644 --- a/testdata/ruby/dbTilingProcessorTest.rb +++ b/testdata/ruby/dbTilingProcessorTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbTransTest.rb b/testdata/ruby/dbTransTest.rb index 44a918831..c94204de8 100644 --- a/testdata/ruby/dbTransTest.rb +++ b/testdata/ruby/dbTransTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/dbVectorTest.rb b/testdata/ruby/dbVectorTest.rb index de99a68c8..7b27afc8f 100644 --- a/testdata/ruby/dbVectorTest.rb +++ b/testdata/ruby/dbVectorTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/edtTest.rb b/testdata/ruby/edtTest.rb index 260b3be39..83c1da445 100644 --- a/testdata/ruby/edtTest.rb +++ b/testdata/ruby/edtTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/extNetTracer.rb b/testdata/ruby/extNetTracer.rb index 0ac958508..c283c4037 100644 --- a/testdata/ruby/extNetTracer.rb +++ b/testdata/ruby/extNetTracer.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/imgObject.rb b/testdata/ruby/imgObject.rb index c1af6f2a7..783a03599 100644 --- a/testdata/ruby/imgObject.rb +++ b/testdata/ruby/imgObject.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/layLayers.rb b/testdata/ruby/layLayers.rb index 52b5734a7..f48769dcb 100644 --- a/testdata/ruby/layLayers.rb +++ b/testdata/ruby/layLayers.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/layLayoutView.rb b/testdata/ruby/layLayoutView.rb index ee3ec1bbc..762ee07d7 100644 --- a/testdata/ruby/layLayoutView.rb +++ b/testdata/ruby/layLayoutView.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/layMarkers.rb b/testdata/ruby/layMarkers.rb index c1bb274f4..493458984 100644 --- a/testdata/ruby/layMarkers.rb +++ b/testdata/ruby/layMarkers.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/layMenuTest.rb b/testdata/ruby/layMenuTest.rb index 5bf0fe746..e5b876418 100644 --- a/testdata/ruby/layMenuTest.rb +++ b/testdata/ruby/layMenuTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/laySession.rb b/testdata/ruby/laySession.rb index 378e25ea6..7b79475f4 100644 --- a/testdata/ruby/laySession.rb +++ b/testdata/ruby/laySession.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/layTechnologies.rb b/testdata/ruby/layTechnologies.rb index 2c7c52e07..6bcba3f35 100644 --- a/testdata/ruby/layTechnologies.rb +++ b/testdata/ruby/layTechnologies.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/qtbinding.rb b/testdata/ruby/qtbinding.rb index 0555a5050..cada243dd 100644 --- a/testdata/ruby/qtbinding.rb +++ b/testdata/ruby/qtbinding.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/rdbTest.rb b/testdata/ruby/rdbTest.rb index affda9af0..86f34dd09 100644 --- a/testdata/ruby/rdbTest.rb +++ b/testdata/ruby/rdbTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/ruby/test_prologue.rb b/testdata/ruby/test_prologue.rb index c5b38cd1c..4dcd70124 100644 --- a/testdata/ruby/test_prologue.rb +++ b/testdata/ruby/test_prologue.rb @@ -1,7 +1,10 @@ # in MSVC environment: -if ENV["RUBY"] && !$:.member?(ENV["RUBY"]) - $:.push("#{ENV["RUBY"]}/lib/ruby/#{RUBY_VERSION}") +if ENV["RUBY"] + ruby_libs = "#{ENV["RUBY"]}/lib/ruby/#{RUBY_VERSION}" + if !$:.member?(ruby_libs) + $:.push(ruby_libs) + end end # Set this to true to disable some tests involving exceptions diff --git a/testdata/ruby/tlTest.rb b/testdata/ruby/tlTest.rb index 08a40e634..3e9d3b281 100644 --- a/testdata/ruby/tlTest.rb +++ b/testdata/ruby/tlTest.rb @@ -1,5 +1,25 @@ +# encoding: UTF-8 -$:.push(File::dirname($0)) +# KLayout Layout Viewer +# Copyright (C) 2006-2017 Matthias Koefferlein +# +# 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 St, Fifth Floor, Boston, MA 02110-1301 USA + +if !$:.member?(File::dirname($0)) + $:.push(File::dirname($0)) +end load("test_prologue.rb") diff --git a/testdata/vendor/ruby/test/unit.rb b/testdata/vendor/ruby/test/unit.rb new file mode 100644 index 000000000..d13831a92 --- /dev/null +++ b/testdata/vendor/ruby/test/unit.rb @@ -0,0 +1,505 @@ +require 'test/unit/testcase' +require 'test/unit/autorunner' + +module Test # :nodoc: + # + # = Test::Unit - Ruby Unit Testing Framework + # + # == Introduction + # + # Unit testing is making waves all over the place, largely due to the + # fact that it is a core practice of XP. While XP is great, unit testing + # has been around for a long time and has always been a good idea. One + # of the keys to good unit testing, though, is not just writing tests, + # but having tests. What's the difference? Well, if you just _write_ a + # test and throw it away, you have no guarantee that something won't + # change later which breaks your code. If, on the other hand, you _have_ + # tests (obviously you have to write them first), and run them as often + # as possible, you slowly build up a wall of things that cannot break + # without you immediately knowing about it. This is when unit testing + # hits its peak usefulness. + # + # Enter Test::Unit, a framework for unit testing in Ruby, helping you to + # design, debug and evaluate your code by making it easy to write and + # have tests for it. + # + # + # == Notes + # + # Test::Unit has grown out of and superceded Lapidary. + # + # + # == Feedback + # + # I like (and do my best to practice) XP, so I value early releases, + # user feedback, and clean, simple, expressive code. There is always + # room for improvement in everything I do, and Test::Unit is no + # exception. Please, let me know what you think of Test::Unit as it + # stands, and what you'd like to see expanded/changed/improved/etc. If + # you find a bug, let me know ASAP; one good way to let me know what the + # bug is is to submit a new test that catches it :-) Also, I'd love to + # hear about any successes you have with Test::Unit, and any + # documentation you might add will be greatly appreciated. My contact + # info is below. + # + # + # == Contact Information + # + # A lot of discussion happens about Ruby in general on the ruby-talk + # mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask + # any questions you might have there. I monitor the list, as do many + # other helpful Rubyists, and you're sure to get a quick answer. Of + # course, you're also welcome to email me (Nathaniel Talbott) directly + # at mailto:testunit@talbott.ws, and I'll do my best to help you out. + # + # + # == Credits + # + # I'd like to thank... + # + # Matz, for a great language! + # + # Masaki Suketa, for his work on RubyUnit, which filled a vital need in + # the Ruby world for a very long time. I'm also grateful for his help in + # polishing Test::Unit and getting the RubyUnit compatibility layer + # right. His graciousness in allowing Test::Unit to supercede RubyUnit + # continues to be a challenge to me to be more willing to defer my own + # rights. + # + # Ken McKinlay, for his interest and work on unit testing, and for his + # willingness to dialog about it. He was also a great help in pointing + # out some of the holes in the RubyUnit compatibility layer. + # + # Dave Thomas, for the original idea that led to the extremely simple + # "require 'test/unit'", plus his code to improve it even more by + # allowing the selection of tests from the command-line. Also, without + # RDoc, the documentation for Test::Unit would stink a lot more than it + # does now. + # + # Everyone who's helped out with bug reports, feature ideas, + # encouragement to continue, etc. It's a real privilege to be a part of + # the Ruby community. + # + # The guys at RoleModel Software, for putting up with me repeating, "But + # this would be so much easier in Ruby!" whenever we're coding in Java. + # + # My Creator, for giving me life, and giving it more abundantly. + # + # + # == License + # + # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free + # software, and is distributed under the Ruby license. See the COPYING + # file. + # + # Exception: lib/test/unit/diff.rb is copyright (c) + # 2008-2010 Kouhei Sutou and 2001-2008 Python Software + # Foundation. It is free software, and is distributed + # under the Ruby license and/or the PSF license. See the + # COPYING file and PSFL file. + # + # == Warranty + # + # This software is provided "as is" and without any express or + # implied warranties, including, without limitation, the implied + # warranties of merchantibility and fitness for a particular + # purpose. + # + # + # == Author + # + # Nathaniel Talbott. + # Copyright (c) 2000-2003, Nathaniel Talbott + # + # ---- + # + # = Usage + # + # The general idea behind unit testing is that you write a _test_ + # _method_ that makes certain _assertions_ about your code, working + # against a _test_ _fixture_. A bunch of these _test_ _methods_ are + # bundled up into a _test_ _suite_ and can be run any time the + # developer wants. The results of a run are gathered in a _test_ + # _result_ and displayed to the user through some UI. So, lets break + # this down and see how Test::Unit provides each of these necessary + # pieces. + # + # + # == Assertions + # + # These are the heart of the framework. Think of an assertion as a + # statement of expected outcome, i.e. "I assert that x should be equal + # to y". If, when the assertion is executed, it turns out to be + # correct, nothing happens, and life is good. If, on the other hand, + # your assertion turns out to be false, an error is propagated with + # pertinent information so that you can go back and make your + # assertion succeed, and, once again, life is good. For an explanation + # of the current assertions, see Test::Unit::Assertions. + # + # + # == Test Method & Test Fixture + # + # Obviously, these assertions have to be called within a context that + # knows about them and can do something meaningful with their + # pass/fail value. Also, it's handy to collect a bunch of related + # tests, each test represented by a method, into a common test class + # that knows how to run them. The tests will be in a separate class + # from the code they're testing for a couple of reasons. First of all, + # it allows your code to stay uncluttered with test code, making it + # easier to maintain. Second, it allows the tests to be stripped out + # for deployment, since they're really there for you, the developer, + # and your users don't need them. Third, and most importantly, it + # allows you to set up a common test fixture for your tests to run + # against. + # + # What's a test fixture? Well, tests do not live in a vacuum; rather, + # they're run against the code they are testing. Often, a collection + # of tests will run against a common set of data, also called a + # fixture. If they're all bundled into the same test class, they can + # all share the setting up and tearing down of that data, eliminating + # unnecessary duplication and making it much easier to add related + # tests. + # + # Test::Unit::TestCase wraps up a collection of test methods together + # and allows you to easily set up and tear down the same test fixture + # for each test. This is done by overriding #setup and/or #teardown, + # which will be called before and after each test method that is + # run. The TestCase also knows how to collect the results of your + # assertions into a Test::Unit::TestResult, which can then be reported + # back to you... but I'm getting ahead of myself. To write a test, + # follow these steps: + # + # * Make sure Test::Unit is in your library path. + # * require 'test/unit' in your test script. + # * Create a class that subclasses Test::Unit::TestCase. + # * Add a method that begins with "test" to your class. + # * Make assertions in your test method. + # * Optionally define #setup and/or #teardown to set up and/or tear + # down your common test fixture. + # * You can now run your test as you would any other Ruby + # script... try it and see! + # + # A really simple test might look like this (#setup and #teardown are + # commented out to indicate that they are completely optional): + # + # require 'test/unit' + # + # class MyTest < Test::Unit::TestCase + # # def setup + # # end + # + # # def teardown + # # end + # + # def test_fail + # assert(false, 'Assertion was false.') + # end + # end + # + # + # == Test Runners + # + # So, now you have this great test class, but you still + # need a way to run it and view any failures that occur + # during the run. There are some test runner; console test + # runner, GTK+ test runner and so on. The console test + # runner is automatically invoked for you if you require + # 'test/unit' and simply run the file. To use another + # runner simply set default test runner ID to + # Test::Unit::AutoRunner: + # + # require 'test/unit' + # Test::Unit::AutoRunner.default_runner = "gtk2" + # + # == Test Suite + # + # As more and more unit tests accumulate for a given project, it + # becomes a real drag running them one at a time, and it also + # introduces the potential to overlook a failing test because you + # forget to run it. Suddenly it becomes very handy that the + # TestRunners can take any object that returns a Test::Unit::TestSuite + # in response to a suite method. The TestSuite can, in turn, contain + # other TestSuites or individual tests (typically created by a + # TestCase). In other words, you can easily wrap up a group of + # TestCases and TestSuites. + # + # Test::Unit does a little bit more for you, by wrapping + # these up automatically when you require + # 'test/unit'. What does this mean? It means you could + # write the above test case like this instead: + # + # require 'test/unit' + # require 'test_myfirsttests' + # require 'test_moretestsbyme' + # require 'test_anothersetoftests' + # + # Test::Unit is smart enough to find all the test cases existing in + # the ObjectSpace and wrap them up into a suite for you. It then runs + # the dynamic suite using the console TestRunner. + # + # + # == Configuration file + # + # Test::Unit reads 'test-unit.yml' in the current working + # directory as Test::Unit's configuration file. It can + # contain the following configurations: + # + # * color scheme definitions + # * test runner to be used + # * test runner options + # * test collector to be used + # + # Except color scheme definitions, all of them are + # specified by command line option. + # + # Here are sample color scheme definitions: + # + # color_schemes: + # inverted: + # success: + # name: red + # bold: true + # failure: + # name: green + # bold: true + # other_scheme: + # ... + # + # Here are the syntax of color scheme definitions: + # + # color_schemes: + # SCHEME_NAME: + # EVENT_NAME: + # name: COLOR_NAME + # intensity: BOOLEAN + # bold: BOOLEAN + # italic: BOOLEAN + # underline: BOOLEAN + # ... + # ... + # + # SCHEME_NAME:: the name of the color scheme + # EVENT_NAME:: one of [success, failure, pending, + # omission, notification, error] + # COLOR_NAME:: one of [black, red, green, yellow, blue, + # magenta, cyan, white] + # BOOLEAN:: true or false + # + # You can use the above 'inverted' color scheme with the + # following configuration: + # + # runner: console + # console_options: + # color_scheme: inverted + # color_schemes: + # inverted: + # success: + # name: red + # bold: true + # failure: + # name: green + # bold: true + # + # == Questions? + # + # I'd really like to get feedback from all levels of Ruby + # practitioners about typos, grammatical errors, unclear statements, + # missing points, etc., in this document (or any other). + # + + module Unit + class << self + # Set true when Test::Unit has run. If set to true Test::Unit + # will not automatically run at exit. + # + # @deprecated Use Test::Unit::AutoRunner.need_auto_run= instead. + def run=(have_run) + AutoRunner.need_auto_run = (not have_run) + end + + # Already tests have run? + # + # @deprecated Use Test::Unit::AutoRunner.need_auto_run? instead. + def run? + not AutoRunner.need_auto_run? + end + + # @api private + @@at_start_hooks = [] + + # Regsiter a hook that is run before running tests. + # To register multiple hooks, call this method multiple times. + # + # Here is an example test case: + # Test::Unit.at_start do + # # ... + # end + # + # class TestMyClass1 < Test::Unit::TestCase + # class << self + # def startup + # # ... + # end + # end + # + # def setup + # # ... + # end + # + # def test_my_class1 + # # ... + # end + # + # def test_my_class2 + # # ... + # end + # end + # + # class TestMyClass2 < Test::Unit::TestCase + # class << self + # def startup + # # ... + # end + # end + # + # def setup + # # ... + # end + # + # def test_my_class1 + # # ... + # end + # + # def test_my_class2 + # # ... + # end + # end + # + # Here is a call order: + # * at_start + # * TestMyClass1.startup + # * TestMyClass1#setup + # * TestMyClass1#test_my_class1 + # * TestMyClass1#setup + # * TestMyClass1#test_my_class2 + # * TestMyClass2#setup + # * TestMyClass2#test_my_class1 + # * TestMyClass2#setup + # * TestMyClass2#test_my_class2 + # + # @example + # Test::Unit.at_start do + # puts "Start!" + # end + # + # @yield A block that is run before running tests. + # @yieldreturn [void] + # @return [void] + # + # @since 2.5.2 + def at_start(&hook) + @@at_start_hooks << hook + end + + # @api private + def run_at_start_hooks + @@at_start_hooks.each do |hook| + hook.call + end + end + + # @api private + @@at_exit_hooks = [] + + # Regsiter a hook that is run after running tests. + # To register multiple hooks, call this method multiple times. + # + # Here is an example test case: + # Test::Unit.at_exit do + # # ... + # end + # + # class TestMyClass1 < Test::Unit::TestCase + # class << self + # def shutdown + # # ... + # end + # end + # + # def teardown + # # ... + # end + # + # def test_my_class1 + # # ... + # end + # + # def test_my_class2 + # # ... + # end + # end + # + # class TestMyClass2 < Test::Unit::TestCase + # class << self + # def shutdown + # # ... + # end + # end + # + # def teardown + # # ... + # end + # + # def test_my_class1 + # # ... + # end + # + # def test_my_class2 + # # ... + # end + # end + # + # Here is a call order: + # * TestMyClass1#test_my_class1 + # * TestMyClass1#teardown + # * TestMyClass1#test_my_class2 + # * TestMyClass1#teardown + # * TestMyClass1.shutdown + # * TestMyClass2#test_my_class1 + # * TestMyClass2#teardown + # * TestMyClass2#test_my_class2 + # * TestMyClass2#teardown + # * TestMyClass2.shutdown + # * at_exit + # + # @example + # Test::Unit.at_exit do + # puts "Exit!" + # end + # + # @yield A block that is run after running tests. + # @yieldreturn [void] + # @return [void] + # + # @since 2.5.2 + def at_exit(&hook) + @@at_exit_hooks << hook + end + + # @api private + def run_at_exit_hooks + @@at_exit_hooks.each do |hook| + hook.call + end + end + end + end +end + +Module.new do + at_exit do + if $!.nil? and Test::Unit::AutoRunner.need_auto_run? + exit Test::Unit::AutoRunner.run + end + end +end diff --git a/testdata/vendor/ruby/test/unit/assertion-failed-error.rb b/testdata/vendor/ruby/test/unit/assertion-failed-error.rb new file mode 100644 index 000000000..474cfa291 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/assertion-failed-error.rb @@ -0,0 +1,25 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + + # Thrown by Test::Unit::Assertions when an assertion fails. + class AssertionFailedError < StandardError + attr_accessor :expected, :actual, :user_message + attr_accessor :inspected_expected, :inspected_actual + def initialize(message=nil, options=nil) + options ||= {} + @expected = options[:expected] + @actual = options[:actual] + @inspected_expected = options[:inspected_expected] + @inspected_actual = options[:inspected_actual] + @user_message = options[:user_message] + super(message) + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/assertions.rb b/testdata/vendor/ruby/test/unit/assertions.rb new file mode 100644 index 000000000..ce6525ccc --- /dev/null +++ b/testdata/vendor/ruby/test/unit/assertions.rb @@ -0,0 +1,2219 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# Copyright (c) 2009-2013 Kouhei Sutou. All rights reserved. +# License:: Ruby license. + +require 'test/unit/assertion-failed-error' +require 'test/unit/util/backtracefilter' +require 'test/unit/util/method-owner-finder' +require 'test/unit/diff' + +begin + require 'power_assert' +rescue LoadError, SyntaxError +end + +module Test + module Unit + + ## + # Test::Unit::Assertions contains the standard Test::Unit assertions. + # Assertions is included in Test::Unit::TestCase. + # + # To include it in your own code and use its functionality, you simply + # need to rescue Test::Unit::AssertionFailedError. Additionally you may + # override add_assertion to get notified whenever an assertion is made. + # + # Notes: + # + # * The message to each assertion, if given, will be propagated with the + # failure. + # * It is easy to add your own assertions based on assert_block(). + # + # @example Example Custom Assertion + # + # def deny(boolean, message = nil) + # message = build_message message, ' is not false or nil.', boolean + # assert_block message do + # not boolean + # end + # end + + module Assertions + + ## + # The assertion upon which all other assertions are based. Passes if the + # block yields true. + # + # @example + # assert_block "Couldn't do the thing" do + # do_the_thing + # end + def assert_block(message="assert_block failed.") + _wrap_assertion do + if (! yield) + raise AssertionFailedError.new(message.to_s) + end + end + end + + # @private + NOT_SPECIFIED = Object.new + + # @overload assert(object, message=nil) + # + # Asserts that `object` is not false nor nil. + # + # Normally, you don't need to use this assertion. Use more + # specific assertions such as #assert_equal and + # #assert_include. + # + # @example Pass patterns + # assert(true) # => pass + # assert([1, 2].include?(1)) # => pass + # + # @example Failure patterns + # assert(nil) # => failure + # assert(false) # => failure + # assert([1, 2].include?(5)) # => failure + # + # @param [Object] object The check target. + # @param [String] message The additional user message. It is + # showed when the assertion is failed. + # @return [void] + # + # @overload assert(message=nil) {} + # + # Asserts that the givens block returns not false nor nil. + # + # This style uses Power Assert. It means that you can see each + # object values in method chains on failure. See the following + # example about Power Assert. + # + # @example Power Assert + # coins = [1, 5, 50] + # target_coin = 10 + # assert do + # coins.include?(target_coin) + # end + # # => + # # coins.include?(target_coin) + # # | | | + # # | | 10 + # # | false + # # [1, 5, 50] + # + # We recommend you to use Power Assert for predicate method + # checks rather than existing assertions such as + # #assert_include and #assert_predicate. Power Assert shows + # useful message for debugging. + # + # We don't recommend you use Power Assert for equality + # check. You should use #assert_equal for the case. Because + # #assert_equal shows more useful message for debugging. + # + # @example Pass patterns + # assert {true} # => pass + # assert {[1, 2].include?(1)} # => pass + # + # @example Failure patterns + # assert {nil} # => failure + # assert {false} # => failure + # assert {[1, 2].include?(5)} # => failure + # + # @param [String] message The additional user message. It is + # showed when the assertion is failed. + # @yield [] Given no parameters to the block. + # @yieldreturn [Object] The checked object. + # @return [void] + def assert(object=NOT_SPECIFIED, message=nil, &block) + _wrap_assertion do + have_object = !NOT_SPECIFIED.equal?(object) + if block + message = object if have_object + if defined?(PowerAssert) + PowerAssert.start(block, :assertion_method => __callee__) do |pa| + pa_message = AssertionMessage.delayed_literal(&pa.message_proc) + assertion_message = build_message(message, "?", pa_message) + assert_block(assertion_message) do + pa.yield + end + end + else + assert(yield, message) + end + else + unless have_object + raise ArgumentError, "wrong number of arguments (0 for 1..2)" + end + assertion_message = nil + case message + when nil, String, Proc + when AssertionMessage + assertion_message = message + else + error_message = "assertion message must be String, Proc or " + error_message << "#{AssertionMessage}: " + error_message << "<#{message.inspect}>(<#{message.class}>)" + raise ArgumentError, error_message, filter_backtrace(caller) + end + assertion_message ||= build_message(message, + " is not true.", + object) + assert_block(assertion_message) do + object + end + end + end + end + + # Asserts that +object+ is false or nil. + # + # @note Just for minitest compatibility. :< + # + # @param [Object] object The object to be asserted. + # @return [void] + # + # @example Pass patterns + # refute(false) # => pass + # refute(nil) # => pass + # + # @example Failure patterns + # refute(true) # => failure + # refute("string") # => failure + # + # @since 2.5.3 + def refute(object, message=nil) + _wrap_assertion do + assertion_message = nil + case message + when nil, String, Proc + when AssertionMessage + assertion_message = message + else + error_message = "assertion message must be String, Proc or " + error_message << "#{AssertionMessage}: " + error_message << "<#{message.inspect}>(<#{message.class}>)" + raise ArgumentError, error_message, filter_backtrace(caller) + end + assert_block("refute should not be called with a block.") do + !block_given? + end + assertion_message ||= build_message(message, + " is neither nil or false.", + object) + assert_block(assertion_message) do + not object + end + end + end + + ## + # Passes if +expected+ == +actual+. + # + # Note that the ordering of arguments is important, since a helpful + # error message is generated when this one fails that tells you the + # values of expected and actual. + # + # @example + # assert_equal 'MY STRING', 'my string'.upcase + def assert_equal(expected, actual, message=nil) + diff = AssertionMessage.delayed_diff(expected, actual) + if expected.respond_to?(:encoding) and + actual.respond_to?(:encoding) and + expected.encoding != actual.encoding + format = <(?) expected but was +(?).? +EOT + full_message = build_message(message, format, + expected, expected.encoding.name, + actual, actual.encoding.name, + diff) + else + full_message = build_message(message, < expected but was +.? +EOT + end + begin + assert_block(full_message) { expected == actual } + rescue AssertionFailedError => failure + _set_failed_information(failure, expected, actual, message) + raise failure # For JRuby. :< + end + end + + ## + # Passes if the block raises one of the expected + # exceptions. When an expected exception is an Exception + # object, passes if expected_exception == actual_exception. + # + # @example + # assert_raise(RuntimeError, LoadError) do + # raise 'Boom!!!' + # end # -> pass + # + # assert_raise do + # raise Exception, 'Any exception should be raised!!!' + # end # -> pass + # + # assert_raise(RuntimeError.new("XXX")) {raise "XXX"} # -> pass + # assert_raise(MyError.new("XXX")) {raise "XXX"} # -> fail + # assert_raise(RuntimeError.new("ZZZ")) {raise "XXX"} # -> fail + def assert_raise(*args, &block) + assert_expected_exception = Proc.new do |*_args| + message, assert_exception_helper, actual_exception = _args + expected = assert_exception_helper.expected_exceptions + diff = AssertionMessage.delayed_diff(expected, actual_exception) + full_message = build_message(message, + " exception expected but was\n.?", + expected, actual_exception, diff) + begin + assert_block(full_message) do + expected == [] or + assert_exception_helper.expected?(actual_exception) + end + rescue AssertionFailedError => failure + _set_failed_information(failure, expected, actual_exception, + message) + raise failure # For JRuby. :< + end + end + _assert_raise(assert_expected_exception, *args, &block) + end + + # Just for minitest compatibility. :< + alias_method :assert_raises, :assert_raise + + ## + # Passes if the block raises one of the given + # exceptions or sub exceptions of the given exceptions. + # + # @example + # assert_raise_kind_of(SystemCallError) do + # raise Errno::EACCES + # end + def assert_raise_kind_of(*args, &block) + assert_expected_exception = Proc.new do |*_args| + message, assert_exception_helper, actual_exception = _args + expected = assert_exception_helper.expected_exceptions + full_message = build_message(message, + " family exception expected " + + "but was\n.", + expected, actual_exception) + assert_block(full_message) do + assert_exception_helper.expected?(actual_exception, :kind_of?) + end + end + _assert_raise(assert_expected_exception, *args, &block) + end + + + ## + # Passes if +object+.instance_of?(+klass+). When +klass+ is + # an array of classes, it passes if any class + # satisfies +object.instance_of?(class). + # + # @example + # assert_instance_of(String, 'foo') # -> pass + # assert_instance_of([Fixnum, NilClass], 100) # -> pass + # assert_instance_of([Numeric, NilClass], 100) # -> fail + def assert_instance_of(klass, object, message="") + _wrap_assertion do + if klass.is_a?(Array) + klasses = klass + else + klasses = [klass] + end + assert_block("The first parameter to assert_instance_of should be " + + "a Class or an Array of Class.") do + klasses.all? {|k| k.is_a?(Class)} + end + klass_message = AssertionMessage.maybe_container(klass) do |value| + "<#{value}>" + end + full_message = build_message(message, < expected to be instance_of\\? +? but was +. +EOT + assert_block(full_message) do + klasses.any? {|k| object.instance_of?(k)} + end + end + end + + ## + # Passes if +object+.instance_of?(+klass+) does not hold. + # When +klass+ is an array of classes, it passes if no class + # satisfies +object.instance_of?(class). + # + # @example + # assert_not_instance_of(String, 100) # -> pass + # assert_not_instance_of([Fixnum, NilClass], '100') # -> pass + # assert_not_instance_of([Numeric, NilClass], 100) # -> fail + # + # @since 3.0.0 + def assert_not_instance_of(klass, object, message="") + _wrap_assertion do + if klass.is_a?(Array) + klasses = klass + else + klasses = [klass] + end + assert_block("The first parameter to assert_not_instance_of should be " << + "a Class or an Array of Class.") do + klasses.all? {|k| k.is_a?(Class)} + end + klass_message = AssertionMessage.maybe_container(klass) do |value| + "<#{value}>" + end + full_message = build_message(message, + " expected to not be instance_of\\?\n" + + "? but was.", + object, + klass_message) + assert_block(full_message) do + klasses.none? {|k| object.instance_of?(k)} + end + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_instance_of, :assert_not_instance_of + + ## + # Passes if +object+ is nil. + # + # @example + # assert_nil [1, 2].uniq! + def assert_nil(object, message="") + full_message = build_message(message, < expected to be nil. +EOT + assert_block(full_message) { object.nil? } + end + + ## + # Passes if +object+.kind_of?(+klass+). When +klass+ is + # an array of classes or modules, it passes if any + # class or module satisfies +object.kind_of?(class_or_module). + # + # @example + # assert_kind_of(Object, 'foo') # -> pass + # assert_kind_of([Fixnum, NilClass], 100) # -> pass + # assert_kind_of([Fixnum, NilClass], "string") # -> fail + def assert_kind_of(klass, object, message="") + _wrap_assertion do + if klass.is_a?(Array) + klasses = klass + else + klasses = [klass] + end + assert_block("The first parameter to assert_kind_of should be " + + "a kind_of Module or an Array of a kind_of Module.") do + klasses.all? {|k| k.kind_of?(Module)} + end + klass_message = AssertionMessage.maybe_container(klass) do |value| + "<#{value}>" + end + full_message = build_message(message, + " expected to be kind_of\\?\n" + + "? but was\n" + + ".", + object, + klass_message, + object.class) + assert_block(full_message) do + klasses.any? {|k| object.kind_of?(k)} + end + end + end + + ## + # Passes if +object+.kind_of?(+klass+) does not hold. + # When +klass+ is an array of classes or modules, it passes only if all + # classes (and modules) do not satisfy +object.kind_of?(class_or_module). + # + # @example + # assert_not_kind_of(Fixnum, 'foo') # -> pass + # assert_not_kind_of([Fixnum, NilClass], '0') # -> pass + # assert_not_kind_of([Fixnum, NilClass], 100) # -> fail + # + # @since 3.0.0 + def assert_not_kind_of(klass, object, message="") + _wrap_assertion do + if klass.is_a?(Array) + klasses = klass + else + klasses = [klass] + end + assert_block("The first parameter to assert_not_kind_of should be " + + "a kind_of Module or an Array of a kind_of Module.") do + klasses.all? {|k| k.kind_of?(Module)} + end + klass_message = AssertionMessage.maybe_container(klass) do |value| + "<#{value}>" + end + full_message = build_message(message, + " expected to not be kind_of\\?\n" + + "? but was.", + object, + klass_message) + assert_block(full_message) do + klasses.none? {|k| object.kind_of?(k)} + end + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_kind_of, :assert_not_kind_of + + ## + # Passes if +object+ .respond_to? +method+ + # + # @example + # assert_respond_to 'bugbear', :slice + def assert_respond_to(object, method, message="") + _wrap_assertion do + full_message = build_message(message, + ".kind_of\\?(Symbol) or\n" + + ".respond_to\\?(:to_str) expected", + method, method) + assert_block(full_message) do + method.kind_of?(Symbol) or method.respond_to?(:to_str) + end + full_message = build_message(message, + ".respond_to\\?(?) expected\n" + + "(Class: )", + object, method, object.class) + assert_block(full_message) {object.respond_to?(method)} + end + end + + ## + # Passes if +object+ does not .respond_to? +method+. + # + # @example + # assert_not_respond_to('bugbear', :nonexistence) # -> pass + # assert_not_respond_to('bugbear', :size) # -> fail + def assert_not_respond_to(object, method, message="") + _wrap_assertion do + full_message = build_message(message, + ".kind_of\\?(Symbol) or\n" + + ".respond_to\\?(:to_str) expected", + method, method) + assert_block(full_message) do + method.kind_of?(Symbol) or method.respond_to?(:to_str) + end + full_message = build_message(message, + "!.respond_to\\?(?) expected\n" + + "(Class: )", + object, method, object.class) + assert_block(full_message) {!object.respond_to?(method)} + end + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :refute_respond_to, :assert_not_respond_to + + ## + # Passes if +pattern+ =~ +string+. + # + # @example + # assert_match(/\d+/, 'five, 6, seven') + def assert_match(pattern, string, message="") + _wrap_assertion do + pattern = case(pattern) + when String + Regexp.new(Regexp.escape(pattern)) + else + pattern + end + full_message = build_message(message, " expected to be =~\n.", + pattern, string) + assert_block(full_message) { pattern =~ string } + end + end + + ## + # Passes if +actual+ .equal? +expected+ (i.e. they are the same + # instance). + # + # @example + # o = Object.new + # assert_same o, o + def assert_same(expected, actual, message="") + full_message = build_message(message, < +with id expected to be equal\\? to + +with id . +EOT + assert_block(full_message) { actual.equal?(expected) } + end + + ## + # Compares the +object1+ with +object2+ using +operator+. + # + # Passes if object1.__send__(operator, object2) is true. + # + # @example + # assert_operator 5, :>=, 4 + def assert_operator(object1, operator, object2, message="") + _wrap_assertion do + full_message = build_message(nil, "\ngiven as the operator for #assert_operator must be a Symbol or #respond_to\\?(:to_str).", operator) + assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)} + full_message = build_message(message, < expected to be +? +. +EOT + assert_block(full_message) { object1.__send__(operator, object2) } + end + end + + ## + # Compares the +object1+ with +object2+ using +operator+. + # + # Passes if object1.__send__(operator, object2) is not true. + # + # @example + # assert_not_operator(5, :<, 4) # => pass + # assert_not_operator(5, :>, 4) # => fail + # + # @since 3.0.0 + def assert_not_operator(object1, operator, object2, message="") + _wrap_assertion do + full_message = build_message(nil, "\ngiven as the operator for #assert_not_operator must be a Symbol or #respond_to\\?(:to_str).", operator) + assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)} + full_message = build_message(message, < expected to not be +? +. +EOT + assert_block(full_message) { ! object1.__send__(operator, object2) } + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_operator, :assert_not_operator + + ## + # Passes if block does not raise an exception. + # + # @example + # assert_nothing_raised do + # [1, 2].uniq + # end + def assert_nothing_raised(*args) + _wrap_assertion do + if args.last.is_a?(String) + message = args.pop + else + message = "" + end + + assert_exception_helper = AssertExceptionHelper.new(self, args) + begin + yield + rescue Exception => e + if ((args.empty? && !e.instance_of?(AssertionFailedError)) || + assert_exception_helper.expected?(e)) + failure_message = build_message(message, "Exception raised:\n?", e) + assert_block(failure_message) {false} + else + raise + end + end + nil + end + end + + ## + # Flunk always fails. + # + # @example + # flunk 'Not done testing yet.' + def flunk(message="Flunked") + assert_block(build_message(message)){false} + end + + ## + # Passes if ! +actual+ .equal? +expected+ + # + # @example + # assert_not_same Object.new, Object.new + def assert_not_same(expected, actual, message="") + full_message = build_message(message, < +with id expected to not be equal\\? to + +with id . +EOT + assert_block(full_message) { !actual.equal?(expected) } + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :refute_same, :assert_not_same + + ## + # Passes if +expected+ != +actual+ + # + # @example + # assert_not_equal 'some string', 5 + def assert_not_equal(expected, actual, message="") + full_message = build_message(message, " expected to be != to\n.", expected, actual) + assert_block(full_message) { expected != actual } + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :refute_equal, :assert_not_equal + + ## + # Passes if ! +object+ .nil? + # + # @example + # assert_not_nil '1 two 3'.sub!(/two/, '2') + def assert_not_nil(object, message="") + full_message = build_message(message, " expected to not be nil.", object) + assert_block(full_message){!object.nil?} + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :refute_nil, :assert_not_nil + + ## + # Passes if +regexp+ !~ +string+ + # + # @example + # assert_not_match(/two/, 'one 2 three') # -> pass + # assert_not_match(/three/, 'one 2 three') # -> fail + def assert_not_match(regexp, string, message="") + _wrap_assertion do + assert_instance_of(Regexp, regexp, + " in assert_not_match(, ...) " + + "should be a Regexp.") + full_message = build_message(message, + " expected to not match\n.", + regexp, string) + assert_block(full_message) { regexp !~ string } + end + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :refute_match, :assert_not_match + + ## + # Deprecated. Use #assert_not_match instead. + # + # Passes if +regexp+ !~ +string+ + # + # @example + # assert_no_match(/two/, 'one 2 three') # -> pass + # assert_no_match(/three/, 'one 2 three') # -> fail + def assert_no_match(regexp, string, message="") + _wrap_assertion do + assert_instance_of(Regexp, regexp, + "The first argument to assert_no_match " + + "should be a Regexp.") + assert_not_match(regexp, string, message) + end + end + + # @private + class ThrowTagExtractor + @@have_uncaught_throw_error = const_defined?(:UncaughtThrowError) + + UncaughtThrowPatterns = { + NameError => /^uncaught throw `(.+)'$/, + ArgumentError => /^uncaught throw (`.+'|.+)$/, + ThreadError => /^uncaught throw `(.+)' in thread /, + } + + def initialize(error) + @error = error + end + + def extract_tag + tag = nil + if @@have_uncaught_throw_error + return nil unless @error.is_a?(UncaughtThrowError) + tag = @error.tag + else + pattern = UncaughtThrowPatterns[@error.class] + return nil if pattern.nil? + return nil unless pattern =~ @error.message + tag = $1 + end + normalize_tag(tag) + end + + private + def normalize_tag(tag) + case tag + when /\A:/ + tag[1..-1].intern + when /\A`(.+)'\z/ + $1.intern + when String + tag.intern + else + tag + end + end + end + + ## + # Passes if the block throws +expected_object+ + # + # @example + # assert_throw(:done) do + # throw(:done) + # end + def assert_throw(expected_object, message="", &proc) + _wrap_assertion do + begin + catch([]) {} + rescue TypeError + assert_instance_of(Symbol, expected_object, + "assert_throws expects the symbol that should be thrown for its first argument") + end + assert_block("Should have passed a block to assert_throw.") do + block_given? + end + caught = true + begin + catch(expected_object) do + proc.call + caught = false + end + full_message = build_message(message, + " should have been thrown.", + expected_object) + assert_block(full_message) {caught} + rescue => error + extractor = ThrowTagExtractor.new(error) + tag = extractor.extract_tag + raise if tag.nil? + full_message = build_message(message, + " expected to be thrown but\n" + + " was thrown.", + expected_object, tag) + flunk(full_message) + end + end + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :assert_throws, :assert_throw + + ## + # Passes if block does not throw anything. + # + # @example + # assert_nothing_thrown do + # [1, 2].uniq + # end + def assert_nothing_thrown(message="", &proc) + _wrap_assertion do + assert(block_given?, "Should have passed a block to assert_nothing_thrown") + begin + proc.call + rescue => error + extractor = ThrowTagExtractor.new(error) + tag = extractor.extract_tag + raise if tag.nil? + full_message = build_message(message, + " was thrown when nothing was expected", + tag) + flunk(full_message) + end + assert(true, "Expected nothing to be thrown") + end + end + + ## + # Passes if +expected_float+ and +actual_float+ are equal + # within +delta+ tolerance. + # + # @example + # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001 + def assert_in_delta(expected_float, actual_float, delta=0.001, message="") + _wrap_assertion do + _assert_in_delta_validate_arguments(expected_float, + actual_float, + delta) + full_message = _assert_in_delta_message(expected_float, + actual_float, + delta, + message) + assert_block(full_message) do + (expected_float.to_f - actual_float.to_f).abs <= delta.to_f + end + end + end + + ## + # Passes if +expected_float+ and +actual_float+ are + # not equal within +delta+ tolerance. + # + # @example + # assert_not_in_delta(0.05, (50000.0 / 10**6), 0.00002) # -> pass + # assert_not_in_delta(0.05, (50000.0 / 10**6), 0.00001) # -> fail + def assert_not_in_delta(expected_float, actual_float, delta=0.001, message="") + _wrap_assertion do + _assert_in_delta_validate_arguments(expected_float, + actual_float, + delta) + full_message = _assert_in_delta_message(expected_float, + actual_float, + delta, + message, + :negative_assertion => true) + assert_block(full_message) do + (expected_float.to_f - actual_float.to_f).abs > delta.to_f + end + end + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :refute_in_delta, :assert_not_in_delta + + private + def _assert_in_delta_validate_arguments(expected_float, + actual_float, + delta) + { + expected_float => "first float", + actual_float => "second float", + delta => "delta" + }.each do |float, name| + assert_respond_to(float, :to_f, + "The arguments must respond to to_f; " + + "the #{name} did not") + end + delta = delta.to_f + assert_operator(delta, :>=, 0.0, "The delta should not be negative") + end + + def _assert_in_delta_message(expected_float, actual_float, delta, + message, options={}) + if options[:negative_assertion] + format = <<-EOT + -/+ expected to not include +. +EOT + else + format = <<-EOT + -/+ expected to include +. +EOT + end + arguments = [expected_float, delta, actual_float] + normalized_expected = expected_float.to_f + normalized_actual = actual_float.to_f + normalized_delta = delta.to_f + relation_format = nil + relation_arguments = nil + if normalized_actual < normalized_expected - normalized_delta + relation_format = "< < -[?] <= +[?]>" + relation_arguments = [actual_float, + expected_float, delta, + normalized_expected - normalized_delta, + expected_float, delta, + normalized_expected + normalized_delta] + elsif normalized_actual <= normalized_expected + normalized_delta + relation_format = "<-[?] <= <= +[?]>" + relation_arguments = [expected_float, delta, + normalized_expected - normalized_delta, + actual_float, + expected_float, delta, + normalized_expected + normalized_delta] + else + relation_format = "<-[?] <= +[?] < >" + relation_arguments = [expected_float, delta, + normalized_expected - normalized_delta, + expected_float, delta, + normalized_expected + normalized_delta, + actual_float] + end + + if relation_format + format << <<-EOT + +Relation: +#{relation_format} +EOT + arguments.concat(relation_arguments) + end + + build_message(message, format, *arguments) + end + + public + ## + # Passes if +expected_float+ and +actual_float+ are equal + # within +epsilon+ relative error of +expected_float+. + # + # @example + # assert_in_epsilon(10000.0, 9900.0, 0.1) # -> pass + # assert_in_epsilon(10000.0, 9899.0, 0.1) # -> fail + def assert_in_epsilon(expected_float, actual_float, epsilon=0.001, + message="") + _wrap_assertion do + _assert_in_epsilon_validate_arguments(expected_float, + actual_float, + epsilon) + full_message = _assert_in_epsilon_message(expected_float, + actual_float, + epsilon, + message) + assert_block(full_message) do + normalized_expected_float = expected_float.to_f + if normalized_expected_float.zero? + delta = epsilon.to_f ** 2 + else + delta = normalized_expected_float * epsilon.to_f + end + delta = delta.abs + (normalized_expected_float - actual_float.to_f).abs <= delta + end + end + end + + ## + # Passes if +expected_float+ and +actual_float+ are + # not equal within +epsilon+ relative error of + # +expected_float+. + # + # @example + # assert_not_in_epsilon(10000.0, 9900.0, 0.1) # -> fail + # assert_not_in_epsilon(10000.0, 9899.0, 0.1) # -> pass + def assert_not_in_epsilon(expected_float, actual_float, epsilon=0.001, + message="") + _wrap_assertion do + _assert_in_epsilon_validate_arguments(expected_float, + actual_float, + epsilon) + full_message = _assert_in_epsilon_message(expected_float, + actual_float, + epsilon, + message, + :negative_assertion => true) + assert_block(full_message) do + normalized_expected_float = expected_float.to_f + delta = normalized_expected_float * epsilon.to_f + (normalized_expected_float - actual_float.to_f).abs > delta + end + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_in_epsilon, :assert_not_in_epsilon + + private + def _assert_in_epsilon_validate_arguments(expected_float, + actual_float, + epsilon) + { + expected_float => "first float", + actual_float => "second float", + epsilon => "epsilon" + }.each do |float, name| + assert_respond_to(float, :to_f, + "The arguments must respond to to_f; " + + "the #{name} did not") + end + epsilon = epsilon.to_f + assert_operator(epsilon, :>=, 0.0, "The epsilon should not be negative") + end + + def _assert_in_epsilon_message(expected_float, actual_float, epsilon, + message, options={}) + normalized_expected = expected_float.to_f + normalized_actual = actual_float.to_f + normalized_epsilon = epsilon.to_f + delta = normalized_expected * normalized_epsilon + + if options[:negative_assertion] + format = <<-EOT + -/+ ( * )[?] expected to not include +. +EOT + else + format = <<-EOT + -/+ ( * )[?] expected to include +. +EOT + end + arguments = [expected_float, expected_float, epsilon, delta, + actual_float] + + relation_format = nil + relation_arguments = nil + if normalized_actual < normalized_expected - delta + relation_format = "< < -(*)[?] <= +(*)[?]>" + relation_arguments = [actual_float, + expected_float, expected_float, epsilon, + normalized_expected - delta, + expected_float, expected_float, epsilon, + normalized_expected + delta] + elsif normalized_actual <= normalized_expected + delta + relation_format = "<-(*)[?] <= <= +(*)[?]>" + relation_arguments = [expected_float, expected_float, epsilon, + normalized_expected - delta, + actual_float, + expected_float, expected_float, epsilon, + normalized_expected + delta] + else + relation_format = "<-(*)[?] <= +(*)[?] < >" + relation_arguments = [expected_float, expected_float, epsilon, + normalized_expected - delta, + expected_float, expected_float, epsilon, + normalized_expected + delta, + actual_float] + end + + if relation_format + format << <<-EOT + +Relation: +#{relation_format} +EOT + arguments.concat(relation_arguments) + end + + build_message(message, format, *arguments) + end + + public + ## + # Passes if the method send returns a true value. + # + # +send_array+ is composed of: + # * A receiver + # * A method + # * Arguments to the method + # + # @example + # assert_send([[1, 2], :member?, 1]) # -> pass + # assert_send([[1, 2], :member?, 4]) # -> fail + def assert_send(send_array, message=nil) + _wrap_assertion do + assert_instance_of(Array, send_array, + "assert_send requires an array " + + "of send information") + assert_operator(send_array.size, :>=, 2, + "assert_send requires at least a receiver " + + "and a message name") + format = < expected to respond to + with a true value but was +. +EOT + receiver, message_name, *arguments = send_array + result = nil + full_message = + build_message(message, + format, + receiver, + AssertionMessage.literal(message_name.to_s), + arguments, + AssertionMessage.delayed_literal {result}) + assert_block(full_message) do + result = receiver.__send__(message_name, *arguments) + result + end + end + end + + ## + # Passes if the method send doesn't return a true value. + # + # +send_array+ is composed of: + # * A receiver + # * A method + # * Arguments to the method + # + # @example + # assert_not_send([[1, 2], :member?, 1]) # -> fail + # assert_not_send([[1, 2], :member?, 4]) # -> pass + def assert_not_send(send_array, message=nil) + _wrap_assertion do + assert_instance_of(Array, send_array, + "assert_not_send requires an array " + + "of send information") + assert_operator(send_array.size, :>=, 2, + "assert_not_send requires at least a receiver " + + "and a message name") + format = < expected to respond to + with not a true value but was +. +EOT + receiver, message_name, *arguments = send_array + result = nil + full_message = + build_message(message, + format, + receiver, + AssertionMessage.literal(message_name.to_s), + arguments, + AssertionMessage.delayed_literal {result}) + assert_block(full_message) do + result = receiver.__send__(message_name, *arguments) + not result + end + end + end + + ## + # Passes if +actual+ is a boolean value. + # + # @example + # assert_boolean(true) # -> pass + # assert_boolean(nil) # -> fail + def assert_boolean(actual, message=nil) + _wrap_assertion do + assert_block(build_message(message, + " or expected but was\n", + actual)) do + [true, false].include?(actual) + end + end + end + + ## + # Passes if +actual+ is true. + # + # @example + # assert_true(true) # -> pass + # assert_true(:true) # -> fail + def assert_true(actual, message=nil) + _wrap_assertion do + assert_block(build_message(message, + " expected but was\n", + actual)) do + actual == true + end + end + end + + ## + # Passes if +actual+ is false. + # + # @example + # assert_false(false) # -> pass + # assert_false(nil) # -> fail + def assert_false(actual, message=nil) + _wrap_assertion do + assert_block(build_message(message, + " expected but was\n", + actual)) do + actual == false + end + end + end + + ## + # Passes if expression "+expected+ +operator+ + # +actual+" is true. + # + # @example + # assert_compare(1, "<", 10) # -> pass + # assert_compare(1, ">=", 10) # -> fail + def assert_compare(expected, operator, actual, message=nil) + _wrap_assertion do + assert_send([["<", "<=", ">", ">="], :include?, operator.to_s]) + case operator.to_s + when "<" + operator_description = "less than" + when "<=" + operator_description = "less than or equal to" + when ">" + operator_description = "greater than" + when ">=" + operator_description = "greater than or equal to" + end + template = <<-EOT + #{operator} should be true + expected #{operator_description} +. +EOT + full_message = build_message(message, template, + expected, actual, + expected, actual) + assert_block(full_message) do + expected.__send__(operator, actual) + end + end + end + + ## + # Passes if assertion is failed in block. + # + # @example + # assert_fail_assertion {assert_equal("A", "B")} # -> pass + # assert_fail_assertion {assert_equal("A", "A")} # -> fail + def assert_fail_assertion(message=nil) + _wrap_assertion do + full_message = build_message(message, + "Failed assertion was expected.") + assert_block(full_message) do + begin + yield + false + rescue AssertionFailedError + true + end + end + end + end + + ## + # Passes if an exception is raised in block and its + # message is +expected+. + # + # @example + # assert_raise_message("exception") {raise "exception"} # -> pass + # assert_raise_message(/exc/i) {raise "exception"} # -> pass + # assert_raise_message("exception") {raise "EXCEPTION"} # -> fail + # assert_raise_message("exception") {} # -> fail + def assert_raise_message(expected, message=nil) + _wrap_assertion do + full_message = build_message(message, + " exception message expected " + + "but none was thrown.", + expected) + exception = nil + assert_block(full_message) do + begin + yield + false + rescue Exception => exception + true + end + end + + actual = exception.message + diff = AssertionMessage.delayed_diff(expected, actual) + full_message = + build_message(message, + " exception message expected but was\n" + + ".?", expected, actual, diff) + assert_block(full_message) do + if expected.is_a?(Regexp) + expected =~ actual + else + expected == actual + end + end + end + end + + ## + # Passes if +object+.const_defined?(+constant_name+) + # + # @example + # assert_const_defined(Test, :Unit) # -> pass + # assert_const_defined(Object, :Nonexistent) # -> fail + def assert_const_defined(object, constant_name, message=nil) + _wrap_assertion do + full_message = build_message(message, + ".const_defined\\?() expected.", + object, constant_name) + assert_block(full_message) do + object.const_defined?(constant_name) + end + end + end + + ## + # Passes if !+object+.const_defined?(+constant_name+) + # + # @example + # assert_not_const_defined(Object, :Nonexistent) # -> pass + # assert_not_const_defined(Test, :Unit) # -> fail + def assert_not_const_defined(object, constant_name, message=nil) + _wrap_assertion do + full_message = build_message(message, + "!.const_defined\\?() expected.", + object, constant_name) + assert_block(full_message) do + !object.const_defined?(constant_name) + end + end + end + + ## + # Passes if +object+.+predicate+ is _true_. + # + # @example + # assert_predicate([], :empty?) # -> pass + # assert_predicate([1], :empty?) # -> fail + def assert_predicate(object, predicate, message=nil) + _wrap_assertion do + assert_respond_to(object, predicate, message) + actual = object.__send__(predicate) + full_message = build_message(message, + ".? is true value expected but was\n" + + "", + object, + AssertionMessage.literal(predicate), + actual) + assert_block(full_message) do + actual + end + end + end + + ## + # Passes if +object+.+predicate+ is not _true_. + # + # @example + # assert_not_predicate([1], :empty?) # -> pass + # assert_not_predicate([], :empty?) # -> fail + def assert_not_predicate(object, predicate, message=nil) + _wrap_assertion do + assert_respond_to(object, predicate, message) + actual = object.__send__(predicate) + full_message = build_message(message, + ".? is false value expected but was\n" + + "", + object, + AssertionMessage.literal(predicate), + actual) + assert_block(full_message) do + not actual + end + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_predicate, :assert_not_predicate + + ## + # Passes if +object+#+alias_name+ is an alias method of + # +object+#+original_name+. + # + # @example + # assert_alias_method([], :length, :size) # -> pass + # assert_alias_method([], :size, :length) # -> pass + # assert_alias_method([], :each, :size) # -> fail + def assert_alias_method(object, alias_name, original_name, message=nil) + _wrap_assertion do + find_method_failure_message = Proc.new do |method_name| + build_message(message, + ".? doesn't exist\n" + + "(Class: )", + object, + AssertionMessage.literal(method_name), + object.class) + end + + alias_method = original_method = nil + assert_block(find_method_failure_message.call(alias_name)) do + begin + alias_method = object.method(alias_name) + true + rescue NameError + false + end + end + assert_block(find_method_failure_message.call(original_name)) do + begin + original_method = object.method(original_name) + true + rescue NameError + false + end + end + + full_message = build_message(message, + " is alias of\n" + + " expected", + alias_method, + original_method) + assert_block(full_message) do + alias_method == original_method + end + end + end + + ## + # Passes if +path+ exists. + # + # @example + # assert_path_exist("/tmp") # -> pass + # assert_path_exist("/bin/sh") # -> pass + # assert_path_exist("/nonexistent") # -> fail + def assert_path_exist(path, message=nil) + _wrap_assertion do + failure_message = build_message(message, + " expected to exist", + path) + assert_block(failure_message) do + File.exist?(path) + end + end + end + + ## + # Passes if +path+ doesn't exist. + # + # @example + # assert_path_not_exist("/nonexistent") # -> pass + # assert_path_not_exist("/tmp") # -> fail + # assert_path_not_exist("/bin/sh") # -> fail + def assert_path_not_exist(path, message=nil) + _wrap_assertion do + failure_message = build_message(message, + " expected to not exist", + path) + assert_block(failure_message) do + not File.exist?(path) + end + end + end + + ## + # Passes if +collection+ includes +object+. + # + # @example + # assert_include([1, 10], 1) # -> pass + # assert_include(1..10, 5) # -> pass + # assert_include([1, 10], 5) # -> fail + # assert_include(1..10, 20) # -> fail + def assert_include(collection, object, message=nil) + _wrap_assertion do + assert_respond_to(collection, :include?, + "The collection must respond to :include?.") + full_message = build_message(message, + " expected to include\n.", + collection, + object) + assert_block(full_message) do + collection.include?(object) + end + end + end + + # Just for minitest compatibility. :< + # + # @since 2.5.3 + alias_method :assert_includes, :assert_include + + ## + # Passes if +collection+ doesn't include +object+. + # + # @example + # assert_not_include([1, 10], 5) # -> pass + # assert_not_include(1..10, 20) # -> pass + # assert_not_include([1, 10], 1) # -> fail + # assert_not_include(1..10, 5) # -> fail + def assert_not_include(collection, object, message=nil) + _wrap_assertion do + assert_respond_to(collection, :include?, + "The collection must respond to :include?.") + full_message = build_message(message, + " expected to not include\n.", + collection, + object) + assert_block(full_message) do + not collection.include?(object) + end + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :assert_not_includes, :assert_not_include + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_includes, :assert_not_include + + ## + # Passes if +object+ is empty. + # + # @example + # assert_empty("") # -> pass + # assert_empty([]) # -> pass + # assert_empty({}) # -> pass + # assert_empty(" ") # -> fail + # assert_empty([nil]) # -> fail + # assert_empty({1 => 2}) # -> fail + def assert_empty(object, message=nil) + _wrap_assertion do + assert_respond_to(object, :empty?, + "The object must respond to :empty?.") + full_message = build_message(message, + " expected to be empty.", + object) + assert_block(full_message) do + object.empty? + end + end + end + + ## + # Passes if +object+ is not empty. + # + # @example + # assert_not_empty(" ") # -> pass + # assert_not_empty([nil]) # -> pass + # assert_not_empty({1 => 2}) # -> pass + # assert_not_empty("") # -> fail + # assert_not_empty([]) # -> fail + # assert_not_empty({}) # -> fail + def assert_not_empty(object, message=nil) + _wrap_assertion do + assert_respond_to(object, :empty?, + "The object must respond to :empty?.") + full_message = build_message(message, + " expected to not be empty.", + object) + assert_block(full_message) do + not object.empty? + end + end + end + + # Just for minitest compatibility. :< + # + # @since 3.0.0 + alias_method :refute_empty, :assert_not_empty + + ## + # Builds a failure message. +head+ is added before the +template+ and + # +arguments+ replaces the '?'s positionally in the template. + def build_message(head, template=nil, *arguments) + template &&= template.chomp + return AssertionMessage.new(head, template, arguments) + end + + private + def _wrap_assertion(&block) + @_assertion_wrapped ||= false + if @_assertion_wrapped + block.call + else + @_assertion_wrapped = true + begin + add_assertion + block.call + ensure + @_assertion_wrapped = false + end + end + end + + public + # Called whenever an assertion is made. Define this in classes + # that include Test::Unit::Assertions to record assertion + # counts. + # + # This is a public API for developers who extend test-unit. + # + # @return [void] + def add_assertion + end + + ## + # Select whether or not to use the pretty-printer. If this option is set + # to false before any assertions are made, pp.rb will not be required. + def self.use_pp=(value) + AssertionMessage.use_pp = value + end + + private + def _assert_raise(assert_expected_exception, *args, &block) + _wrap_assertion do + if args.last.is_a?(String) + message = args.pop + else + message = "" + end + + assert_exception_helper = AssertExceptionHelper.new(self, args) + expected = assert_exception_helper.expected_exceptions + actual_exception = nil + full_message = build_message(message, + " exception expected " + + "but none was thrown.", + expected) + assert_block(full_message) do + begin + yield + false + rescue Exception => actual_exception + true + end + end + assert_expected_exception.call(message, assert_exception_helper, + actual_exception) + actual_exception + end + end + + def _set_failed_information(failure, expected, actual, user_message) + failure.expected = expected + failure.actual = actual + failure.inspected_expected = AssertionMessage.convert(expected) + failure.inspected_actual = AssertionMessage.convert(actual) + failure.user_message = user_message + end + + class AssertionMessage + @use_pp = true + class << self + attr_accessor :use_pp + + def literal(value) + Literal.new(value) + end + + def delayed_literal(&block) + DelayedLiteral.new(block) + end + + def maybe_container(value, &formatter) + MaybeContainer.new(value, &formatter) + end + + MAX_DIFF_TARGET_STRING_SIZE = 1000 + def max_diff_target_string_size + return @@max_diff_target_string_size if @@max_diff_target_string_size + + size = ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] + if size + begin + size = Integer(size) + rescue ArgumentError + size = nil + end + end + size || MAX_DIFF_TARGET_STRING_SIZE + end + + @@max_diff_target_string_size = nil + def max_diff_target_string_size=(size) + @@max_diff_target_string_size = size + end + + def diff_target_string?(string) + if string.respond_to?(:bytesize) + string.bytesize < max_diff_target_string_size + else + string.size < max_diff_target_string_size + end + end + + def ensure_diffable_string(string) + if string.respond_to?(:encoding) and + !string.encoding.ascii_compatible? + string = string.dup.force_encoding("ASCII-8BIT") + end + string + end + + def prepare_for_diff(from, to) + if !from.is_a?(String) or !to.is_a?(String) + from = convert(from) + to = convert(to) + end + + if diff_target_string?(from) and diff_target_string?(to) + from = ensure_diffable_string(from) + to = ensure_diffable_string(to) + [from, to] + else + [nil, nil] + end + end + + def delayed_diff(from, to) + delayed_literal do + from, to = prepare_for_diff(from, to) + + diff = "" if from.nil? or to.nil? + diff ||= Diff.readable(from, to) + if /^[-+]/ !~ diff + diff = "" + elsif /^[ ?]/ =~ diff or /(?:.*\n){2,}/ =~ diff + diff = "\n\ndiff:\n#{diff}" + else + diff = "" + end + + if Diff.need_fold?(diff) + folded_diff = Diff.folded_readable(from, to) + diff << "\n\nfolded diff:\n#{folded_diff}" + end + + diff + end + end + + def convert(object) + if object.is_a?(Exception) + object = AssertExceptionHelper::WrappedException.new(object) + end + inspector = Inspector.new(object) + if use_pp + begin + require 'pp' unless defined?(PP) + begin + return PP.pp(inspector, '').chomp + rescue NameError + end + rescue LoadError + self.use_pp = false + end + end + inspector.inspect + end + end + + class Inspector + include Comparable + + class << self + def cached_new(object, inspected_objects) + inspected_objects[object.object_id] ||= + new(object, inspected_objects) + end + + @@inspector_classes = [] + def inspector_classes + @@inspector_classes + end + + def register_inspector_class(inspector_class) + @@inspector_classes << inspector_class + end + + def unregister_inspector_class(inspector_class) + @@inspector_classes.delete(inspector_class) + end + end + + attr_reader :object + def initialize(object, inspected_objects={}) + @inspected_objects = inspected_objects + @object = object + @inspected_objects[@object.object_id] = self + @inspect_target = inspect_target + end + + alias_method :native_inspect, :inspect + def inspect + @inspect_target.inspect + end + + def pretty_print(q) + @inspect_target.pretty_print(q) + end + + def pretty_print_cycle(q) + @inspect_target.pretty_print_cycle(q) + end + + def <=>(other) + if other.is_a?(self.class) + @object <=> other.object + else + @object <=> other + end + end + + private + def inspect_target + self.class.inspector_classes.each do |inspector_class| + if inspector_class.target?(@object) + return inspector_class.new(@object, @inspected_objects) + end + end + @object + end + end + + class NumericInspector + Inspector.register_inspector_class(self) + + class << self + def target?(object) + object.is_a?(Numeric) + end + end + + def initialize(numeric, inspected_objects) + @inspected_objects = inspected_objects + @numeric = numeric + end + + def inspect + @numeric.to_s + end + + def pretty_print(q) + q.text(@numeric.to_s) + end + + def pretty_print_cycle(q) + q.text(@numeric.to_s) + end + end + + class HashInspector + Inspector.register_inspector_class(self) + + class << self + def target?(object) + object.is_a?(Hash) or ENV.equal?(object) + end + end + + def initialize(hash, inspected_objects) + @inspected_objects = inspected_objects + @hash = {} + hash.each do |key, value| + key = Inspector.cached_new(key, @inspected_objects) + value = Inspector.cached_new(value, @inspected_objects) + @hash[key] = value + end + end + + def inspect + @hash.inspect + end + + def pretty_print(q) + q.group(1, '{', '}') do + q.seplist(self, nil, :each_pair) do |k, v| + q.group do + q.pp(k) + q.text('=>') + q.group(1) do + q.breakable('') + q.pp(v) + end + end + end + end + end + + def pretty_print_cycle(q) + @hash.pretty_print_cycle(q) + end + + def each_pair + keys = @hash.keys + begin + keys = keys.sort # FIXME: more cleverly + rescue ArgumentError + end + keys.each do |key| + yield(key, @hash[key]) + end + end + end + + class ArrayInspector + Inspector.register_inspector_class(self) + + class << self + def target?(object) + object.is_a?(Array) + end + end + + def initialize(array, inspected_objects) + @inspected_objects = inspected_objects + @array = array.collect do |element| + Inspector.cached_new(element, @inspected_objects) + end + end + + def inspect + @array.inspect + end + + def pretty_print(q) + q.group(1, '[', ']') do + q.seplist(self) do |v| + q.pp(v) + end + end + end + + def pretty_print_cycle(q) + @array.pretty_print_cycle(q) + end + + def each(&block) + @array.each(&block) + end + end + + class Literal + def initialize(value) + @value = value + end + + def inspect + @value.to_s + end + end + + class DelayedLiteral + def initialize(value) + @value = value + end + + def inspect + @value.call.to_s + end + end + + class MaybeContainer + def initialize(value, &formatter) + @value = value + @formatter = formatter + end + + def inspect + if @value.is_a?(Array) + values = @value.collect do |value| + @formatter.call(AssertionMessage.convert(value)) + end + "[#{values.join(', ')}]" + else + @formatter.call(AssertionMessage.convert(@value)) + end + end + end + + class Template + def self.create(string) + parts = (string ? string.scan(/(?=[^\\])\?|(?:\\\?|[^\?])+/m) : []) + self.new(parts) + end + + attr_reader :count + + def initialize(parts) + @parts = parts + @count = parts.find_all{|e| e == '?'}.size + end + + def result(parameters) + raise "The number of parameters does not match the number of substitutions." if(parameters.size != count) + params = parameters.dup + expanded_template = "" + @parts.each do |part| + if part == '?' + encoding_safe_concat(expanded_template, params.shift) + else + expanded_template << part.gsub(/\\\?/m, '?') + end + end + expanded_template + end + + private + if Object.const_defined?(:Encoding) + def encoding_safe_concat(buffer, parameter) + if Encoding.compatible?(buffer, parameter) + buffer << parameter + else + buffer << parameter.dup.force_encoding(buffer.encoding) + end + end + else + def encoding_safe_concat(buffer, parameter) + buffer << parameter + end + end + end + + include Util::BacktraceFilter + + def initialize(head, template_string, parameters) + @head = head + @template_string = template_string + @parameters = parameters + end + + def convert(object) + self.class.convert(object) + end + + def template + @template ||= Template.create(@template_string) + end + + def add_period(string) + (string =~ /\.\Z/ ? string : string + '.') + end + + def to_s + message_parts = [] + if (@head) + head = @head + head = head.call if head.respond_to?(:call) + head = head.to_s + unless(head.empty?) + message_parts << add_period(head) + end + end + tail = template.result(@parameters.collect{|e| convert(e)}) + message_parts << tail unless(tail.empty?) + message_parts.join("\n") + end + end + + class AssertExceptionHelper + class WrappedException + attr_reader :exception + def initialize(exception) + @exception = exception + end + + def inspect + if default_inspect? + "#{@exception.class.inspect}(<#{@exception.message}>)" + else + @exception.inspect + end + end + + def method_missing(name, *args, &block) + @exception.__send__(name, *args, &block) + end + + private + def default_inspect? + inspect_method = @exception.method(:inspect) + if inspect_method.respond_to?(:owner) and + inspect_method.owner == Exception + true + else + default_inspect_method = Exception.instance_method(:inspect) + default_inspect_method.bind(@exception).call == @exception.inspect + end + end + end + + def initialize(test_case, expected_exceptions) + @test_case = test_case + @expected_exceptions = expected_exceptions + @expected_classes, @expected_modules, @expected_objects = + split_expected_exceptions(expected_exceptions) + end + + def expected_exceptions + exceptions = @expected_exceptions.collect do |exception| + if exception.is_a?(Exception) + WrappedException.new(exception) + else + exception + end + end + if exceptions.size == 1 + exceptions[0] + else + exceptions + end + end + + def expected?(actual_exception, equality=nil) + equality ||= :instance_of? + expected_class?(actual_exception, equality) or + expected_module?(actual_exception) or + expected_object?(actual_exception) + end + + private + def split_expected_exceptions(expected_exceptions) + exception_modules = [] + exception_objects = [] + exception_classes = [] + expected_exceptions.each do |exception_type| + if exception_type.instance_of?(Module) + exception_modules << exception_type + elsif exception_type.is_a?(Exception) + exception_objects << exception_type + else + @test_case.__send__(:assert, + Exception >= exception_type, + "Should expect a class of exception, " + + "#{exception_type}") + exception_classes << exception_type + end + end + [exception_classes, exception_modules, exception_objects] + end + + def expected_class?(actual_exception, equality) + @expected_classes.any? do |expected_class| + actual_exception.__send__(equality, expected_class) + end + end + + def expected_module?(actual_exception) + @expected_modules.any? do |expected_module| + actual_exception.is_a?(expected_module) + end + end + + def expected_object?(actual_exception) + @expected_objects.any? do |expected_object| + expected_object == actual_exception or + fallback_exception_object_equal(expected_object, actual_exception) + end + end + + def fallback_exception_object_equal(expected_object, actual_exception) + owner = Util::MethodOwnerFinder.find(expected_object, :==) + if owner == Kernel or owner == Exception + expected_object.class == actual_exception.class and + expected_object.message == actual_exception.message + else + false + end + end + end + + # :startdoc: + end + end +end diff --git a/testdata/vendor/ruby/test/unit/attribute-matcher.rb b/testdata/vendor/ruby/test/unit/attribute-matcher.rb new file mode 100644 index 000000000..5b5597560 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/attribute-matcher.rb @@ -0,0 +1,26 @@ +module Test + module Unit + class AttributeMatcher + def initialize(test) + @test = test + end + + def match?(expression) + matched = instance_eval(expression) + if matched.nil? + false + else + matched + end + end + + def method_missing(name, *args) + if args.empty? + @test[name] + else + super + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/attribute.rb b/testdata/vendor/ruby/test/unit/attribute.rb new file mode 100644 index 000000000..cfc9e8d2d --- /dev/null +++ b/testdata/vendor/ruby/test/unit/attribute.rb @@ -0,0 +1,158 @@ +module Test + module Unit + module Attribute + class StringifyKeyHash < Hash + class << self + def stringify(object) + object.to_s + end + end + + def key?(key) + super(self.class.stringify(key)) + end + + def [](key) + super(self.class.stringify(key)) + end + + def []=(key, value) + super(self.class.stringify(key), value) + end + end + + class << self + def included(base) + base.extend(BaseClassMethods) + base.extend(ClassMethods) + end + end + + module BaseClassMethods + def attributes_table + {} + end + end + + module ClassMethods + def method_added(name) + super + return unless defined?(@current_attributes) + + attributes = {} + kept_attributes = StringifyKeyHash.new + @current_attributes.each do |attribute_name, attribute| + attributes[attribute_name] = attribute[:value] + kept_attributes[attribute_name] = attribute if attribute[:keep] + end + set_attributes(name, attributes) + @current_attributes = kept_attributes + end + + def attribute(name, value, options={}, *method_names) + unless options.is_a?(Hash) + method_names << options + options = {} + end + if method_names.empty? + current_attributes[name] = options.merge(:value => value) + else + method_names.each do |method_name| + set_attributes(method_name, {name => value}) + end + end + end + + def current_attributes + @current_attributes ||= StringifyKeyHash.new + end + + def current_attribute(name) + current_attributes[name] || StringifyKeyHash.new + end + + def attributes_table + @attributes_table ||= StringifyKeyHash.new + super.merge(@attributes_table) + end + + def set_attributes(method_name, new_attributes) + return if new_attributes.empty? + @attributes_table ||= StringifyKeyHash.new + @attributes_table[method_name] ||= StringifyKeyHash.new + current_attributes = @attributes_table[method_name] + new_attributes.each do |key, value| + observers = attribute_observers(key) || [] + observers.each do |observer| + observer.call(self, + StringifyKeyHash.stringify(key), + (attributes(method_name) || {})[key], + value, + method_name) + end + current_attributes[key] = value + end + end + + def attributes(method_name) + attributes = attributes_table[method_name] + ancestors.each do |ancestor| + next if ancestor == self + if ancestor.is_a?(Class) and ancestor < Test::Unit::Attribute + parent_attributes = ancestor.attributes(method_name) + if attributes + attributes = (parent_attributes || {}).merge(attributes) + else + attributes = parent_attributes + end + break + end + end + attributes || StringifyKeyHash.new + end + + def find_attribute(method_name, name, options={}) + recursive_p = options[:recursive] + recursive_p = true if recursive_p.nil? + + @attributes_table ||= StringifyKeyHash.new + if @attributes_table.key?(method_name) + attributes = @attributes_table[method_name] + if attributes.key?(name) + return attributes[name] + end + end + + return nil unless recursive_p + return nil if self == TestCase + + @cached_parent_test_case ||= ancestors.find do |ancestor| + ancestor != self and + ancestor.is_a?(Class) and + ancestor < Test::Unit::Attribute + end + + @cached_parent_test_case.find_attribute(method_name, name, options) + end + + @@attribute_observers = StringifyKeyHash.new + def register_attribute_observer(attribute_name, observer=Proc.new) + @@attribute_observers[attribute_name] ||= [] + @@attribute_observers[attribute_name] << observer + end + + def attribute_observers(attribute_name) + @@attribute_observers[attribute_name] + end + end + + def attributes + self.class.attributes(@method_name) || StringifyKeyHash.new + end + + def [](name) + self.class.find_attribute(@method_name, name) + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/auto-runner-loader.rb b/testdata/vendor/ruby/test/unit/auto-runner-loader.rb new file mode 100644 index 000000000..21f70edb2 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/auto-runner-loader.rb @@ -0,0 +1,17 @@ +require "test/unit/test-suite-creator" + +module Test + module Unit + module AutoRunnerLoader + @loaded = false + class << self + def check(test_case, method_name) + return if @loaded + return unless TestSuiteCreator.test_method?(test_case, method_name) + require "test/unit" + @loaded = true + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/autorunner.rb b/testdata/vendor/ruby/test/unit/autorunner.rb new file mode 100644 index 000000000..624c5995f --- /dev/null +++ b/testdata/vendor/ruby/test/unit/autorunner.rb @@ -0,0 +1,513 @@ +require "English" + +require "test/unit/color-scheme" +require "test/unit/priority" +require "test/unit/attribute-matcher" +require "test/unit/testcase" +require "optparse" + +module Test + module Unit + class AutoRunner + RUNNERS = {} + COLLECTORS = {} + ADDITIONAL_OPTIONS = [] + PREPARE_HOOKS = [] + + class << self + def register_runner(id, runner_builder=Proc.new) + RUNNERS[id] = runner_builder + RUNNERS[id.to_s] = runner_builder + end + + def runner(id) + RUNNERS[id.to_s] + end + + @@default_runner = nil + def default_runner + runner(@@default_runner) + end + + def default_runner=(id) + @@default_runner = id + end + + def register_collector(id, collector_builder=Proc.new) + COLLECTORS[id] = collector_builder + COLLECTORS[id.to_s] = collector_builder + end + + def collector(id) + COLLECTORS[id.to_s] + end + + def register_color_scheme(id, scheme) + ColorScheme[id] = scheme + end + + def setup_option(option_builder=Proc.new) + ADDITIONAL_OPTIONS << option_builder + end + + def prepare(hook=Proc.new) + PREPARE_HOOKS << hook + end + + def run(force_standalone=false, default_dir=nil, argv=ARGV, &block) + r = new(force_standalone || standalone?, &block) + r.base = default_dir + r.prepare + r.process_args(argv) + r.run + end + + def standalone? + return false unless("-e" == $0) + ObjectSpace.each_object(Class) do |klass| + return false if(klass < TestCase) + end + true + end + + @@need_auto_run = true + def need_auto_run? + @@need_auto_run + end + + def need_auto_run=(need) + @@need_auto_run = need + end + end + + register_collector(:descendant) do |auto_runner| + require "test/unit/collector/descendant" + collector = Collector::Descendant.new + collector.filter = auto_runner.filters + collector.collect($0.sub(/\.rb\Z/, "")) + end + + register_collector(:load) do |auto_runner| + require "test/unit/collector/load" + collector = Collector::Load.new + unless auto_runner.pattern.empty? + collector.patterns.replace(auto_runner.pattern) + end + unless auto_runner.exclude.empty? + collector.excludes.replace(auto_runner.exclude) + end + collector.base = auto_runner.base + collector.default_test_paths = auto_runner.default_test_paths + collector.filter = auto_runner.filters + collector.collect(*auto_runner.to_run) + end + + # JUST TEST! + # register_collector(:xml) do |auto_runner| + # require "test/unit/collector/xml" + # collector = Collector::XML.new + # collector.filter = auto_runner.filters + # collector.collect(auto_runner.to_run[0]) + # end + + # deprecated + register_collector(:object_space) do |auto_runner| + require "test/unit/collector/objectspace" + c = Collector::ObjectSpace.new + c.filter = auto_runner.filters + c.collect($0.sub(/\.rb\Z/, "")) + end + + # deprecated + register_collector(:dir) do |auto_runner| + require "test/unit/collector/dir" + c = Collector::Dir.new + c.filter = auto_runner.filters + unless auto_runner.pattern.empty? + c.pattern.replace(auto_runner.pattern) + end + unless auto_runner.exclude.empty? + c.exclude.replace(auto_runner.exclude) + end + c.base = auto_runner.base + $:.push(auto_runner.base) if auto_runner.base + c.collect(*(auto_runner.to_run.empty? ? ["."] : auto_runner.to_run)) + end + + attr_reader :suite, :runner_options + attr_accessor :filters, :to_run + attr_accessor :default_test_paths + attr_accessor :pattern, :exclude, :base, :workdir + attr_accessor :color_scheme, :listeners + attr_writer :runner, :collector + + def initialize(standalone) + @standalone = standalone + @runner = default_runner + @collector = default_collector + @filters = [] + @to_run = [] + @default_test_paths = [] + @color_scheme = ColorScheme.default + @runner_options = {} + @default_arguments = [] + @workdir = nil + @listeners = [] + config_file = "test-unit.yml" + if File.exist?(config_file) + load_config(config_file) + else + load_global_config + end + yield(self) if block_given? + end + + def prepare + PREPARE_HOOKS.each do |handler| + handler.call(self) + end + end + + def process_args(args=ARGV) + begin + args.unshift(*@default_arguments) + options.order!(args) {|arg| add_test_path(arg)} + rescue OptionParser::ParseError => e + puts e + puts options + exit(false) + end + not @to_run.empty? + end + + def options + @options ||= OptionParser.new do |o| + o.banner = "Test::Unit automatic runner." + o.banner << "\nUsage: #{$0} [options] [-- untouched arguments]" + + o.on("-r", "--runner=RUNNER", RUNNERS, + "Use the given RUNNER.", + "(" + keyword_display(RUNNERS) + ")") do |r| + @runner = r + end + + o.on("--collector=COLLECTOR", COLLECTORS, + "Use the given COLLECTOR.", + "(" + keyword_display(COLLECTORS) + ")") do |collector| + @collector = collector + end + + if (@standalone) + o.on("-b", "--basedir=DIR", "Base directory of test suites.") do |b| + @base = b + end + + o.on("-w", "--workdir=DIR", "Working directory to run tests.") do |w| + @workdir = w + end + + o.on("--default-test-path=PATH", + "Add PATH to the default test paths.", + "The PATH is used when user doesn't specify any test path.", + "You can specify this option multiple times.") do |path| + @default_test_paths << path + end + + o.on("-a", "--add=TORUN", Array, + "Add TORUN to the list of things to run;", + "can be a file or a directory.") do |paths| + paths.each do |path| + add_test_path(path) + end + end + + @pattern = [] + o.on("-p", "--pattern=PATTERN", Regexp, + "Match files to collect against PATTERN.") do |e| + @pattern << e + end + + @exclude = [] + o.on("-x", "--exclude=PATTERN", Regexp, + "Ignore files to collect against PATTERN.") do |e| + @exclude << e + end + end + + o.on("-n", "--name=NAME", String, + "Runs tests matching NAME.", + "Use '/PATTERN/' for NAME to use regular expression.") do |name| + name = (%r{\A/(.*)/\Z} =~ name ? Regexp.new($1) : name) + @filters << lambda do |test| + return true if name === test.method_name + test_name_without_class_name = test.name.gsub(/\(.+?\)\z/, "") + if test_name_without_class_name != test.method_name + return true if name === test_name_without_class_name + end + false + end + end + + o.on("--ignore-name=NAME", String, + "Ignores tests matching NAME.", + "Use '/PATTERN/' for NAME to use regular expression.") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + case n + when Regexp + @filters << proc {|t| n =~ t.method_name ? false : true} + else + @filters << proc {|t| n != t.method_name} + end + end + + o.on("-t", "--testcase=TESTCASE", String, + "Runs tests in TestCases matching TESTCASE.", + "Use '/PATTERN/' for TESTCASE to use regular expression.") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + @filters << lambda do |test| + match_test_case_name(test, n) + end + end + + o.on("--ignore-testcase=TESTCASE", String, + "Ignores tests in TestCases matching TESTCASE.", + "Use '/PATTERN/' for TESTCASE to use regular expression.") do |n| + n = (%r{\A/(.*)/\Z} =~ n ? Regexp.new($1) : n) + @filters << lambda do |test| + not match_test_case_name(test, n) + end + end + + o.on("--location=LOCATION", String, + "Runs tests that defined in LOCATION.", + "LOCATION is one of PATH:LINE, PATH or LINE") do |location| + if /\A\d+\z/ =~ location + path = nil + line = location.to_i + else + path, line, = location.split(/:(\d+)/, 2) + line = line.to_i unless line.nil? + end + add_location_filter(path, line) + end + + o.on("--attribute=EXPRESSION", String, + "Runs tests that matches EXPRESSION.", + "EXPRESSION is evaluated as Ruby's expression.", + "Test attribute name can be used with no receiver in EXPRESSION.", + "EXPRESSION examples:", + " !slow", + " tag == 'important' and !slow") do |expression| + @filters << lambda do |test| + matcher = AttributeMatcher.new(test) + matcher.match?(expression) + end + end + + priority_filter = Proc.new do |test| + if @filters == [priority_filter] + Priority::Checker.new(test).need_to_run? + else + nil + end + end + o.on("--[no-]priority-mode", + "Runs some tests based on their priority.") do |priority_mode| + if priority_mode + Priority.enable + @filters |= [priority_filter] + else + Priority.disable + @filters -= [priority_filter] + end + end + + o.on("--default-priority=PRIORITY", + Priority.available_values, + "Uses PRIORITY as default priority", + "(#{keyword_display(Priority.available_values)})") do |priority| + Priority.default = priority + end + + o.on("-I", "--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]", + "Appends directory list to $LOAD_PATH.") do |dirs| + $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR)) + end + + color_schemes = ColorScheme.all + o.on("--color-scheme=SCHEME", color_schemes, + "Use SCHEME as color scheme.", + "(#{keyword_display(color_schemes)})") do |scheme| + @color_scheme = scheme + end + + o.on("--config=FILE", + "Use YAML fomat FILE content as configuration file.") do |file| + load_config(file) + end + + o.on("--order=ORDER", TestCase::AVAILABLE_ORDERS, + "Run tests in a test case in ORDER order.", + "(#{keyword_display(TestCase::AVAILABLE_ORDERS)})") do |order| + TestCase.test_order = order + end + + assertion_message_class = Test::Unit::Assertions::AssertionMessage + o.on("--max-diff-target-string-size=SIZE", Integer, + "Shows diff if both expected result string size and " + + "actual result string size are " + + "less than or equal SIZE in bytes.", + "(#{assertion_message_class.max_diff_target_string_size})") do |size| + assertion_message_class.max_diff_target_string_size = size + end + + ADDITIONAL_OPTIONS.each do |option_builder| + option_builder.call(self, o) + end + + o.on("--", + "Stop processing options so that the", + "remaining options will be passed to the", + "test."){o.terminate} + + o.on("-h", "--help", "Display this help."){puts o; exit} + + o.on_tail + o.on_tail("Deprecated options:") + + o.on_tail("--console", "Console runner (use --runner).") do + warn("Deprecated option (--console).") + @runner = self.class.runner(:console) + end + + if RUNNERS[:fox] + o.on_tail("--fox", "Fox runner (use --runner).") do + warn("Deprecated option (--fox).") + @runner = self.class.runner(:fox) + end + end + + o.on_tail + end + end + + def keyword_display(keywords) + keywords = keywords.collect do |keyword, _| + keyword.to_s + end.uniq.sort + + i = 0 + keywords.collect do |keyword| + if (i > 0 and keyword[0] == keywords[i - 1][0]) or + ((i < keywords.size - 1) and (keyword[0] == keywords[i + 1][0])) + n = 2 + else + n = 1 + end + i += 1 + keyword.sub(/^(.{#{n}})([A-Za-z]+)(?=\w*$)/, '\\1[\\2]') + end.join(", ") + end + + def run + self.class.need_auto_run = false + suite = @collector[self] + return false if suite.nil? + return true if suite.empty? + runner = @runner[self] + return false if runner.nil? + @runner_options[:color_scheme] ||= @color_scheme + @runner_options[:listeners] ||= [] + @runner_options[:listeners].concat(@listeners) + change_work_directory do + runner.run(suite, @runner_options).passed? + end + end + + def load_config(file) + require "yaml" + config = YAML.load(File.read(file)) + runner_name = config["runner"] + @runner = self.class.runner(runner_name) || @runner + @collector = self.class.collector(config["collector"]) || @collector + (config["color_schemes"] || {}).each do |name, options| + ColorScheme[name] = options + end + runner_options = {} + (config["#{runner_name}_options"] || {}).each do |key, value| + key = key.to_sym + value = ColorScheme[value] if key == :color_scheme + if key == :arguments + @default_arguments.concat(value.split) + else + runner_options[key.to_sym] = value + end + end + @runner_options = @runner_options.merge(runner_options) + end + + private + def default_runner + runner = self.class.default_runner + if ENV["EMACS"] == "t" + runner ||= self.class.runner(:emacs) + else + runner ||= self.class.runner(:console) + end + runner + end + + def default_collector + self.class.collector(@standalone ? :load : :descendant) + end + + def global_config_file + File.expand_path("~/.test-unit.yml") + rescue ArgumentError + nil + end + + def load_global_config + file = global_config_file + load_config(file) if file and File.exist?(file) + end + + def change_work_directory(&block) + if @workdir + Dir.chdir(@workdir, &block) + else + yield + end + end + + def match_test_case_name(test, pattern) + test.class.ancestors.each do |test_class| + break if test_class == TestCase + return true if pattern === test_class.name + end + false + end + + def add_test_path(path) + if /:(\d+)\z/ =~ path + line = $1.to_i + path = $PREMATCH + add_location_filter(path, line) + end + @to_run << path + end + + def add_location_filter(path, line) + @filters << lambda do |test| + test.class.test_defined?(:path => path, + :line => line, + :method_name => test.method_name) + end + end + end + end +end + +require "test/unit/runner/console" +require "test/unit/runner/emacs" +require "test/unit/runner/xml" diff --git a/testdata/vendor/ruby/test/unit/code-snippet-fetcher.rb b/testdata/vendor/ruby/test/unit/code-snippet-fetcher.rb new file mode 100644 index 000000000..7969a07b9 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/code-snippet-fetcher.rb @@ -0,0 +1,58 @@ +module Test + module Unit + class CodeSnippetFetcher + def initialize + @sources = {} + end + + def fetch(path, line, options={}) + n_context_line = options[:n_context_line] || 3 + lines = source(path) + return [] if lines.nil? + min_line = [line - n_context_line, 1].max + max_line = [line + n_context_line, lines.length].min + window = min_line..max_line + window.collect do |n| + attributes = {:target_line? => (n == line)} + [n, lines[n - 1].chomp, attributes] + end + end + + def source(path) + @sources[path] ||= read_source(path) + end + + private + def read_source(path) + return nil unless File.exist?(path) + lines = [] + File.open(path) do |file| + first_line = file.gets + break if first_line.nil? + encoding = detect_encoding(first_line) + if encoding + first_line.force_encoding(encoding) + file.set_encoding(encoding, encoding) + end + lines << first_line + lines.concat(file.readlines) + end + lines + end + + def detect_encoding(first_line) + return nil unless first_line.respond_to?(:ascii_only?) + return nil unless first_line.ascii_only? + if /\b(?:en)?coding[:=]\s*([a-z\d_-]+)/i =~ first_line + begin + Encoding.find($1) + rescue ArgumentError + nil + end + else + nil + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/collector.rb b/testdata/vendor/ruby/test/unit/collector.rb new file mode 100644 index 000000000..022cedf79 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/collector.rb @@ -0,0 +1,73 @@ +module Test + module Unit + module Collector + def initialize + @filters = [] + end + + def filter=(filters) + @filters = case(filters) + when Proc + [filters] + when Array + filters + end + end + + def add_suite(destination, suite) + to_delete = suite.tests.find_all do |test| + test.is_a?(TestCase) and !include?(test) + end + suite.delete_tests(to_delete) + destination << suite unless suite.empty? + end + + def add_test_cases(suite, test_cases) + children_map = {} + test_cases.each do |test_case| + ancestor_classes = test_case.ancestors.find_all do |ancestor| + ancestor.is_a?(Class) + end + parent = ancestor_classes[1] + children_map[parent] ||= [] + children_map[parent] << test_case + end + + root_test_cases = children_map.keys - test_cases + root_test_cases.each do |root_test_case| + add_test_case(suite, root_test_case, children_map) + end + end + + def include?(test) + return true if(@filters.empty?) + @filters.each do |filter| + return false if filter[test] == false + end + true + end + + def sort(suites) + suites.sort_by do |suite| + [suite.priority, suite.name || suite.to_s] + end + end + + private + def add_test_case(suite, test_case, children_map) + children = children_map[test_case] + return if children.nil? + + sub_suites = [] + children.each do |child| + sub_suite = child.suite + add_test_case(sub_suite, child, children_map) + add_suite(sub_suites, sub_suite) + end + sort(sub_suites).each do |sub_suite| + suite << sub_suite + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/collector/descendant.rb b/testdata/vendor/ruby/test/unit/collector/descendant.rb new file mode 100644 index 000000000..b2de52863 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/collector/descendant.rb @@ -0,0 +1,19 @@ +require 'test/unit/collector' + +module Test + module Unit + module Collector + class Descendant + include Collector + + NAME = 'collected from the subclasses of TestCase' + + def collect(name=NAME) + suite = TestSuite.new(name) + add_test_cases(suite, TestCase::DESCENDANTS) + suite + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/collector/dir.rb b/testdata/vendor/ruby/test/unit/collector/dir.rb new file mode 100644 index 000000000..f84273abb --- /dev/null +++ b/testdata/vendor/ruby/test/unit/collector/dir.rb @@ -0,0 +1,108 @@ +require 'test/unit/testsuite' +require 'test/unit/collector' + +module Test + module Unit + module Collector + class Dir + include Collector + + attr_reader :pattern, :exclude + attr_accessor :base + + def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil) + super() + @dir = dir + @file = file + @object_space = object_space + @req = req + @pattern = [/\btest_.*\.rb\Z/m] + @exclude = [] + @base = nil + end + + def collect(*from) + basedir = @base + $:.push(basedir) if basedir + if(from.empty?) + recursive_collect('.', find_test_cases) + elsif(from.size == 1) + recursive_collect(from.first, find_test_cases) + else + suites = [] + from.each do |f| + suite = recursive_collect(f, find_test_cases) + suites << suite unless(suite.tests.empty?) + end + suite = TestSuite.new("[#{from.join(', ')}]") + sort(suites).each{|s| suite << s} + suite + end + ensure + $:.delete_at($:.rindex(basedir)) if basedir + end + + def find_test_cases(ignore=[]) + cases = [] + @object_space.each_object(Class) do |c| + cases << c if(c < TestCase && !ignore.include?(c)) + end + ignore.concat(cases) + cases + end + + def recursive_collect(name, already_gathered) + sub_suites = [] + path = realdir(name) + if @file.directory?(path) + dir_name = name unless name == '.' + @dir.entries(path).each do |e| + next if(e == '.' || e == '..') + e_name = dir_name ? @file.join(dir_name, e) : e + if @file.directory?(realdir(e_name)) + next if /\A(?:CVS|\.svn|\.git)\z/ =~ e + sub_suite = recursive_collect(e_name, already_gathered) + sub_suites << sub_suite unless(sub_suite.empty?) + else + next if /~\z/ =~ e_name or /\A\.\#/ =~ e + if @pattern and !@pattern.empty? + next unless @pattern.any? {|pat| pat =~ e_name} + end + if @exclude and !@exclude.empty? + next if @exclude.any? {|pat| pat =~ e_name} + end + collect_file(e_name, sub_suites, already_gathered) + end + end + else + collect_file(name, sub_suites, already_gathered) + end + suite = TestSuite.new(@file.basename(name)) + sort(sub_suites).each{|s| suite << s} + suite + end + + def collect_file(name, suites, already_gathered) + dir = @file.dirname(@file.expand_path(name, @base)) + $:.unshift(dir) + if(@req) + @req.require(name) + else + require(name) + end + find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)} + ensure + $:.delete_at($:.rindex(dir)) if(dir) + end + + def realdir(path) + if @base + @file.join(@base, path) + else + path + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/collector/load.rb b/testdata/vendor/ruby/test/unit/collector/load.rb new file mode 100644 index 000000000..9c0fcd0fc --- /dev/null +++ b/testdata/vendor/ruby/test/unit/collector/load.rb @@ -0,0 +1,200 @@ +require 'pathname' + +require 'test/unit/testsuite' +require 'test/unit/collector' + +module Test + module Unit + module Collector + class Load + include Collector + + attr_reader :patterns, :excludes, :base + attr_reader :default_test_paths + + def initialize + super + @system_excludes = [/~\z/, /\A\.\#/] + @system_directory_excludes = [/\A(?:CVS|\.svn|\.git)\z/] + @patterns = [/\Atest[_\-].+\.rb\z/m, /[_\-]test\.rb\z/] + @excludes = [] + @base = nil + @default_test_paths = [] + @require_failed_infos = [] + end + + def base=(base) + base = Pathname(base) unless base.nil? + @base = base + end + + def default_test_paths=(paths) + @default_test_paths = paths.collect do |path| + Pathname(path) + end + end + + def collect(*froms) + add_load_path(@base) do + froms = @default_test_paths if froms.empty? + froms = ["."] if froms.empty? + test_suites = [] + already_gathered = find_test_cases + froms.each do |from| + from = resolve_path(from) + if from.directory? + test_suite = collect_recursive(from, already_gathered) + test_suites << test_suite unless test_suite.tests.empty? + else + collect_file(from, test_suites, already_gathered) + end + end + add_require_failed_test_suite(test_suites) + + if test_suites.size > 1 + test_suite = TestSuite.new("[#{froms.join(', ')}]") + sort(test_suites).each do |sub_test_suite| + test_suite << sub_test_suite + end + else + test_suite = test_suites.first + end + + test_suite + end + end + + def find_test_cases(ignore=[]) + test_cases = [] + TestCase::DESCENDANTS.each do |test_case| + test_cases << test_case unless ignore.include?(test_case) + end + ignore.concat(test_cases) + test_cases + end + + private + def collect_recursive(path, already_gathered) + sub_test_suites = [] + + if path.directory? + directories, files = path.children.partition do |child| + child.directory? + end + + files.each do |child| + next if excluded_file?(child.basename.to_s) + collect_file(child, sub_test_suites, already_gathered) + end + + directories.each do |child| + next if excluded_directory?(child.basename.to_s) + sub_test_suite = collect_recursive(child, already_gathered) + sub_test_suites << sub_test_suite unless sub_test_suite.empty? + end + else + unless excluded_file?(path.basename.to_s) + collect_file(path, sub_test_suites, already_gathered) + end + end + + test_suite = TestSuite.new(path.basename.to_s) + sort(sub_test_suites).each do |sub_test_suite| + test_suite << sub_test_suite + end + test_suite + end + + def collect_file(path, test_suites, already_gathered) + @program_file ||= File.expand_path($0) + expanded_path = path.expand_path + return if @program_file == expanded_path.to_s + add_load_path(expanded_path.dirname) do + begin + require(path.basename.to_s) + rescue LoadError + @require_failed_infos << {:path => expanded_path, :exception => $!} + end + add_test_cases(test_suites, find_test_cases(already_gathered)) + end + end + + def resolve_path(path) + if @base + @base + path + else + Pathname(path) + end + end + + def add_load_path(path) + return yield if path.nil? + + path = path.to_s + begin + $LOAD_PATH.unshift(path) + yield + ensure + index = $LOAD_PATH.index(path) + $LOAD_PATH.delete_at(index) if index + end + end + + def excluded_directory?(base) + @system_directory_excludes.any? {|pattern| pattern =~ base} + end + + def excluded_file?(base) + return true if @system_excludes.any? {|pattern| pattern =~ base} + + patterns = @patterns || [] + unless patterns.empty? + return true unless patterns.any? {|pattern| pattern =~ base} + end + + excludes = @excludes || [] + unless excludes.empty? + return true if excludes.any? {|pattern| pattern =~ base} + end + + false + end + + def add_require_failed_test_suite(test_suites) + return if @require_failed_infos.empty? + + require_failed_infos = @require_failed_infos + require_failed_omissions = Class.new(Test::Unit::TestCase) + require_failed_omissions.class_eval do + class << self + def name + "RequireFailedOmissions" + end + end + + require_failed_infos.each do |info| + path = info[:path] + normalized_path = path.to_s.gsub(/[^a-z0-9\_]+/i, '_') + normalized_path = normalized_path.gsub(/\A_+/, '') + exception = info[:exception] + define_method("test_require_#{normalized_path}") do + @require_failed_exception = exception + omit("failed to load: <#{path}>: <#{exception.message}>") + end + end + + def priority + 100 + end + + def filter_backtrace(location) + super(@require_failed_exception.backtrace) + end + end + + add_suite(test_suites, require_failed_omissions.suite) + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/collector/objectspace.rb b/testdata/vendor/ruby/test/unit/collector/objectspace.rb new file mode 100644 index 000000000..eab313779 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/collector/objectspace.rb @@ -0,0 +1,34 @@ +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/collector' + +module Test + module Unit + module Collector + class ObjectSpace + include Collector + + NAME = 'collected from the ObjectSpace' + + def initialize(source=::ObjectSpace) + super() + @source = source + end + + def collect(name=NAME) + suite = TestSuite.new(name) + sub_suites = [] + @source.each_object(Class) do |klass| + if(Test::Unit::TestCase > klass) + add_suite(sub_suites, klass.suite) + end + end + sort(sub_suites).each{|s| suite << s} + suite + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/collector/xml.rb b/testdata/vendor/ruby/test/unit/collector/xml.rb new file mode 100644 index 000000000..cde452805 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/collector/xml.rb @@ -0,0 +1,249 @@ +#-- +# +# Author:: Kouhei Sutou +# Copyright:: +# * Copyright (c) 2011 Kouhei Sutou +# License:: Ruby license. + +# just test!!! don't use it yet!!! + +require 'test/unit/collector' + +require 'rexml/document' +require 'rexml/streamlistener' + +module Test + module Unit + module Collector + class XML + include Collector + + def collect(xml_log_path) + listener = Listener.new + File.open(xml_log_path) do |xml_log| + parser = REXML::Parsers::StreamParser.new(xml_log, listener) + parser.parse + end + suite = TestSuite.new("tests in #{xml_log_path}") + suites = listener.test_suites + sort(suites).each {|s| add_suite(suite, s)} + suite + end + + class Listener + include REXML::StreamListener + + attr_reader :test_suites + def initialize + @ns_stack = [{"xml" => :xml}] + @tag_stack = [["", :root]] + @text_stack = [''] + @state_stack = [:root] + @values = {} + @test_suites = [] + end + + def tag_start(name, attributes) + @text_stack.push('') + + ns = @ns_stack.last.dup + attrs = {} + attributes.each do |n, v| + if /\Axmlns(?:\z|:)/ =~ n + ns[$POSTMATCH] = v + else + attrs[n] = v + end + end + @ns_stack.push(ns) + + _parent_tag = parent_tag + prefix, local = split_name(name) + uri = _ns(ns, prefix) + @tag_stack.push([uri, local]) + + state = next_state(@state_stack.last, uri, local) + @state_stack.push(state) + @values = {} + case state + when :test_suite, :test_case + # do nothing + when :test + @n_pass_assertions = 0 if _parent_tag == "start-test" + when :backtrace + @backtrace = [] + @values_backup = @values + end + end + + def tag_end(name) + state = @state_stack.pop + text = @text_stack.pop + uri, local = @tag_stack.pop + no_action_states = [:root, :stream] + case state + when *no_action_states + # do nothing + when :test_suite + test_suite_end + when :complete_test_case + @test_suites.last << @test_case.suite + when :test_case + test_case_end + when :result + @result = @values + when :test + test_end + when :pass_assertion + @n_pass_assertions += 1 + when :backtrace + @values = @values_backup + @values["backtrace"] = @backtrace + when :entry + file = @values['file'] + line = @values['line'] + info = @values['info'] + @backtrace << "#{file}:#{line}: #{info}" + @values = {} + else + local = normalize_local(local) + @values[local] = text + end + @ns_stack.pop + end + + def text(data) + @text_stack.last << data + end + + private + def _ns(ns, prefix) + ns.fetch(prefix, "") + end + + NAME_SPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/ + def split_name(name) + name =~ NAME_SPLIT + [$1 || '', $2] + end + + STATE_TABLE = { + :root => [:stream], + :stream => [:ready_test_suite, + :start_test_suite, + :ready_test_case, + :start_test_case, + :start_test, + :pass_assertion, + :test_result, + :complete_test, + :complete_test_case, + :complete_test_suite, + :success], + :ready_test_suite => [:n_tests], + :start_test_suite => [:test_suite], + :ready_test_case => [:test_case, + :n_tests], + :start_test_case => [:test_case], + :start_test => [:test], + :pass_assertion => [:test], + :complete_test => [:test, :success], + :complete_test_case => [:test_case, + :elapsed, + :success], + :complete_test_suite => [:test_suite, + :success], + :test_suite => [:start_time, + :elapsed], + :test_case => [:name, + :start_time, + :elapsed], + :test => [:name, + :start_time, + :elapsed], + :test_result => [:test, + :result], + :result => [:test_case, + :test, + :status, + :backtrace, + :detail], + :backtrace => [:entry], + :entry => [:file, + :line, + :info], + } + def next_state(current_state, uri, local) + local = normalize_local(local) + valid_elements = STATE_TABLE[current_state] + if valid_elements.nil? + raise "unexpected element: #{current_path}" + end + next_state = local.to_sym + unless valid_elements.include?(next_state) + raise "unexpected element: #{current_path}" + end + next_state + end + + def current_path + locals = @tag_stack.collect do |uri, local| + local + end + ["", *locals].join("/") + end + + def normalize_local(local) + local.gsub(/-/, "_") + end + + def parent_tag + @tag_stack.last[1] + end + + def test_suite_end + return unless parent_tag == "start-test-suite" + suite = TestSuite.new + ["start_time", "elapsed_time", "n_tests"].each do |key| + if @values.has_key?(key) + suite.instance_variable_set("@#{key}", @values[key]) + end + end + @test_suites << suite + end + + def test_case_end + return unless parent_tag == "start-test-case" + name = @values["name"] + @test_case = Class.new(TestCase) do + define_method(:name) do + name + end + end + end + + def test_end + return unless parent_tag == "complete-test" + name = @values["name"] + n_pass_assertions = @n_pass_assertions + result = @result + @test_case.module_eval do + test + define_method(name) do + n_pass_assertions.times do + add_assertion + end + case result["status"] + when "omission" + add_omission(Omission.new(name, + result["backtrace"], + result["detail"])) + end + end + end + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/color-scheme.rb b/testdata/vendor/ruby/test/unit/color-scheme.rb new file mode 100644 index 000000000..a898f9d68 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/color-scheme.rb @@ -0,0 +1,198 @@ +require 'test/unit/color' + +module Test + module Unit + class ColorScheme + include Enumerable + + class << self + def default + if available_colors == 256 + default_for_256_colors + else + default_for_8_colors + end + end + + @@default_for_8_colors = nil + def default_for_8_colors + @@default_for_8_colors ||= + new("pass" => Color.new("green", :background => true) + + Color.new("white", :bold => true), + "pass-marker" => Color.new("green", :bold => true), + "failure" => Color.new("red", :background => true) + + Color.new("white", :bold => true), + "failure-marker" => Color.new("red"), + "pending" => Color.new("magenta", :background => true) + + Color.new("white", :bold => true), + "pending-marker" => Color.new("magenta"), + "omission" => Color.new("blue", :background => true) + + Color.new("white", :bold => true), + "omission-marker" => Color.new("blue"), + "notification" => Color.new("cyan", :background => true) + + Color.new("white", :bold => true), + "notification-marker" => Color.new("cyan"), + "error" => Color.new("black", :background => true) + + Color.new("yellow", :bold => true), + "error-marker" => Color.new("yellow"), + "case" => Color.new("blue", :background => true) + + Color.new("white", :bold => true), + "suite" => Color.new("green", :background => true) + + Color.new("white", :bold => true), + "diff-inserted-tag" => Color.new("red", :background => true) + + Color.new("black", :bold => true), + "diff-deleted-tag" => Color.new("green", :background => true) + + Color.new("black", :bold => true), + "diff-difference-tag" => Color.new("cyan", :background => true) + + Color.new("white", :bold => true), + "diff-inserted" => Color.new("red", :background => true) + + Color.new("white", :bold => true), + "diff-deleted" => Color.new("green", :background => true) + + Color.new("white", :bold => true)) + end + + @@default_for_256_colors = nil + def default_for_256_colors + @@default_for_256_colors ||= + new("pass" => Color.new("030", :background => true) + + Color.new("555", :bold => true), + "pass-marker" => Color.new("050", :bold => true), + "failure" => Color.new("300", :background => true) + + Color.new("555", :bold => true), + "failure-marker" => Color.new("500"), + "pending" => Color.new("303", :background => true) + + Color.new("555", :bold => true), + "pending-marker" => Color.new("303"), + "omission" => Color.new("001", :background => true) + + Color.new("555", :bold => true), + "omission-marker" => Color.new("001"), + "notification" => Color.new("011", :background => true) + + Color.new("555", :bold => true), + "notification-marker" => Color.new("011"), + "error" => Color.new("000", :background => true) + + Color.new("550", :bold => true), + "error-marker" => Color.new("550"), + "case" => Color.new("220", :background => true) + + Color.new("555", :bold => true), + "suite" => Color.new("110", :background => true) + + Color.new("555", :bold => true), + "diff-inserted-tag" => Color.new("500", :background => true) + + Color.new("000", :bold => true), + "diff-deleted-tag" => Color.new("050", :background => true) + + Color.new("000", :bold => true), + "diff-difference-tag" => Color.new("005", :background => true) + + Color.new("555", :bold => true), + "diff-inserted" => Color.new("300", :background => true) + + Color.new("555", :bold => true), + "diff-deleted" => Color.new("030", :background => true) + + Color.new("555", :bold => true)) + end + + @@schemes = {} + def all + @@schemes.merge("default" => default) + end + + def [](id) + @@schemes[id.to_s] + end + + def []=(id, scheme_or_spec) + if scheme_or_spec.is_a?(self) + scheme = scheme_or_spec + else + scheme = new(scheme_or_spec) + end + @@schemes[id.to_s] = scheme + end + + def available_colors + guess_available_colors_from_vte_version_env || + guess_available_colors_from_colorterm_env || + guess_available_colors_from_term_env || + 8 + end + + private + def guess_available_colors_from_vte_version_env + vte_version = ENV["VTE_VERSION"] + return nil if vte_version.nil? + + major = 0 + minor = 13 + micro = 0 + packed_version = major * 10000 + minor * 100 + micro + if vte_version.to_i >= packed_version + 256 + else + 8 + end + end + + def guess_available_colors_from_colorterm_env + case ENV["COLORTERM"] + when "gnome-terminal", "xfce4-terminal" + 256 + else + nil + end + end + + def guess_available_colors_from_term_env + case ENV["TERM"] + when /-256color\z/ + 256 + else + nil + end + end + end + + def initialize(scheme_spec) + @scheme = {} + scheme_spec.each do |key, color_spec| + self[key] = color_spec + end + end + + def [](name) + @scheme[name.to_s] + end + + def []=(name, color_spec) + @scheme[name.to_s] = make_color(color_spec) + end + + def each(&block) + @scheme.each(&block) + end + + def to_hash + hash = {} + @scheme.each do |key, color| + hash[key] = color + end + hash + end + + private + def make_color(color_spec) + if color_spec.is_a?(Color) or color_spec.is_a?(MixColor) + color_spec + else + color_name = nil + normalized_color_spec = {} + color_spec.each do |key, value| + key = key.to_sym + if key == :name + color_name = value + else + normalized_color_spec[key] = value + end + end + Color.new(color_name, normalized_color_spec) + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/color.rb b/testdata/vendor/ruby/test/unit/color.rb new file mode 100644 index 000000000..86972fc45 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/color.rb @@ -0,0 +1,134 @@ +module Test + module Unit + class Color + class Error < StandardError + end + + class ParseError < Error + end + + class << self + def parse_256_color(string) + case string + when /\A([0-5])([0-5])([0-5])\z/ + red, green, blue = $1, $2, $3 + red.to_i * 36 + green.to_i * 6 + blue.to_i + 16 + else + message = "must be 'RGB' format and R, G and B " + + "are in 0-5: #{string.inspect}" + raise ParseError, message + end + end + end + + NAMES = ["black", "red", "green", "yellow", + "blue", "magenta", "cyan", "white"] + + attr_reader :name + def initialize(name, options={}) + @name = name + if options.has_key?(:foreground) + if options[:foreground].nil? + @background = false + else + @background = !options[:foreground] + end + else + @background = options[:background] + end + @intensity = options[:intensity] + @bold = options[:bold] + @italic = options[:italic] + @underline = options[:underline] + end + + def foreground? + not background? + end + + def background? + @background + end + + def intensity? + @intensity + end + + def bold? + @bold + end + + def italic? + @italic + end + + def underline? + @underline + end + + def ==(other) + self.class === other and + [name, background?, intensity?, + bold?, italic?, underline?] == + [other.name, other.background?, other.intensity?, + other.bold?, other.italic?, other.underline?] + end + + def sequence + sequence = [] + if @name == "none" + elsif @name == "reset" + sequence << "0" + else + if NAMES.include?(@name) + color_parameter = foreground? ? 3 : 4 + color_parameter += 6 if intensity? + color = NAMES.index(@name) + sequence << "#{color_parameter}#{color}" + else + sequence << (foreground? ? "38" : "48") + sequence << "5" + sequence << self.class.parse_256_color(@name).to_s + end + end + sequence << "1" if bold? + sequence << "3" if italic? + sequence << "4" if underline? + sequence + end + + def escape_sequence + "\e[#{sequence.join(';')}m" + end + + def +(other) + MixColor.new([self, other]) + end + end + + class MixColor + attr_reader :colors + def initialize(colors) + @colors = colors + end + + def sequence + @colors.inject([]) do |result, color| + result + color.sequence + end + end + + def escape_sequence + "\e[#{sequence.join(';')}m" + end + + def +(other) + self.class.new([self, other]) + end + + def ==(other) + self.class === other and colors == other.colors + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/data.rb b/testdata/vendor/ruby/test/unit/data.rb new file mode 100644 index 000000000..9f71f0168 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/data.rb @@ -0,0 +1,262 @@ +module Test + module Unit + module Data + class << self + def included(base) + base.extend(ClassMethods) + end + end + + module ClassMethods + # This method provides Data-Driven-Test functionality. + # + # Define test data in the test code. + # + # @overload data(label, data) + # @param [String] label specify test case name. + # @param data specify test data. + # + # @example data(label, data) + # data("empty string", [true, ""]) + # data("plain string", [false, "hello"]) + # def test_empty?(data) + # expected, target = data + # assert_equal(expected, target.empty?) + # end + # + # @overload data(data_set) + # @param [Hash] data_set specify test data as a Hash that + # key is test label and value is test data. + # + # @example data(data_set) + # data("empty string" => [true, ""], + # "plain string" => [false, "hello"]) + # def test_empty?(data) + # expected, target = data + # assert_equal(expected, target.empty?) + # end + # + # @overload data(&block) + # @yieldreturn [Hash] return test data set as a Hash that + # key is test label and value is test data. + # + # @example data(&block) + # data do + # data_set = {} + # data_set["empty string"] = [true, ""] + # data_set["plain string"] = [false, "hello"] + # data_set + # end + # def test_empty?(data) + # expected, target = data + # assert_equal(expected, target.empty?) + # end + # + def data(*arguments, &block) + n_arguments = arguments.size + case n_arguments + when 0 + raise ArgumentError, "no block is given" unless block_given? + data_set = block + when 1 + data_set = arguments[0] + when 2 + data_set = {arguments[0] => arguments[1]} + else + message = "wrong number arguments(#{n_arguments} for 1..2)" + raise ArgumentError, message + end + current_data = current_attribute(:data)[:value] || [] + attribute(:data, current_data + [data_set]) + end + + # This method provides Data-Driven-Test functionality. + # + # Load test data from the file. This is shorthand to load + # test data from file. If you want to load complex file, you + # can use {#data} with block. + # + # @param [String] file_name full path to test data file. + # File format is automatically detected from filename extension. + # @raise [ArgumentError] if +file_name+ is not supported file format. + # @see Loader#load + # + # @example Load data from CSV file + # load_data("/path/to/test-data.csv") + # def test_empty?(data) + # assert_equal(data["expected"], data["target"].empty?) + # end + # + def load_data(file_name) + loader = Loader.new(self) + loader.load(file_name) + end + + class Loader + # @api private + def initialize(test_case) + @test_case = test_case + end + + # Load data from file. + # + # @param [String] file_name full path to test data file. + # File format is automatically detected from filename extension. + # @raise [ArgumentError] if +file_name+ is not supported file format. + # @see #load_csv + # @see #load_tsv + # @api private + def load(file_name) + case File.extname(file_name).downcase + when ".csv" + load_csv(file_name) + when ".tsv" + load_tsv(file_name) + else + raise ArgumentError, "unsupported file format: <#{file_name}>" + end + end + + # Load data from CSV file. + # + # There are 2 types of CSV file as following examples. + # First, there is a header on first row and it's first column is "label". + # Another, there is no header in the file. + # + # @example Load data from CSV file with header + # # test-data.csv: + # # label,expected,target + # # empty string,true,"" + # # plain string,false,hello + # # + # load_data("/path/to/test-data.csv") + # def test_empty?(data) + # assert_equal(data["expected"], data["target"].empty?) + # end + # + # @example Load data from CSV file without header + # # test-data-without-header.csv: + # # empty string,true,"" + # # plain string,false,hello + # # + # load_data("/path/to/test-data-without-header.csv") + # def test_empty?(data) + # expected, target = data + # assert_equal(expected, target.empty?) + # end + # + # @api private + def load_csv(file_name) + require 'csv' + first_row = true + header = nil + CSV.foreach(file_name) do |row| + if first_row + first_row = false + if row.first == "label" + header = row[1..-1] + next + end + end + + set_test_data(header, row) + end + end + + # Load data from TSV file. + # + # There are 2 types of TSV file as following examples. + # First, there is a header on first row and it's first column is "label". + # Another, there is no header in the file. + # + # @example Load data from TSV file with header + # # test-data.tsv: + # # label expected target + # # empty string true "" + # # plain string false hello + # # + # load_data("/path/to/test-data.tsv") + # def test_empty?(data) + # assert_equal(data["expected"], data["target"].empty?) + # end + # + # @example Load data from TSV file without header + # # test-data-without-header.tsv: + # # empty string true "" + # # plain string false hello + # # + # load_data("/path/to/test-data-without-header.tsv") + # def test_empty?(data) + # expected, target = data + # assert_equal(expected, target.empty?) + # end + # + # @api private + def load_tsv(file_name) + require "csv" + if CSV.const_defined?(:VERSION) + first_row = true + header = nil + CSV.foreach(file_name, :col_sep => "\t") do |row| + if first_row + first_row = false + if row.first == "label" + header = row[1..-1] + next + end + end + + set_test_data(header, row) + end + else + # for old CSV library + first_row = true + header = nil + CSV.open(file_name, "r", "\t") do |row| + if first_row + first_row = false + if row.first == "label" + header = row[1..-1] + next + end + end + + set_test_data(header, row) + end + end + end + + private + def normalize_value(value) + return true if value == "true" + return false if value == "false" + begin + Integer(value) + rescue ArgumentError + begin + Float(value) + rescue ArgumentError + value + end + end + end + + def set_test_data(header, row) + label = row.shift + if header + data = {} + header.each_with_index do |key, i| + data[key] = normalize_value(row[i]) + end + else + data = row.collect do |cell| + normalize_value(cell) + end + end + @test_case.data(label, data) + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/diff.rb b/testdata/vendor/ruby/test/unit/diff.rb new file mode 100644 index 000000000..8e7ff56c9 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/diff.rb @@ -0,0 +1,746 @@ +# port of Python's difflib. +# +# Copyright (c) 2001-2008 Python Software Foundation; All Rights Reserved +# Copyright (c) 2008-2011 Kouhei Sutou; All Rights Reserved +# +# It is free software, and is distributed under the Ruby +# license and/or the PSF license. See the COPYING file and +# PSFL file. + +module Test + module Unit + module Diff + class SequenceMatcher + def initialize(from, to, &junk_predicate) + @from = from + @to = to + @junk_predicate = junk_predicate + update_to_indexes + end + + def longest_match(from_start, from_end, to_start, to_end) + best_info = find_best_match_position(from_start, from_end, + to_start, to_end) + unless @junks.empty? + args = [from_start, from_end, to_start, to_end] + best_info = adjust_best_info_with_junk_predicate(false, best_info, + *args) + best_info = adjust_best_info_with_junk_predicate(true, best_info, + *args) + end + + best_info + end + + def blocks + @blocks ||= compute_blocks + end + + def operations + @operations ||= compute_operations + end + + def grouped_operations(context_size=nil) + context_size ||= 3 + _operations = operations.dup + _operations = [[:equal, 0, 0, 0, 0]] if _operations.empty? + expand_edge_equal_operations!(_operations, context_size) + + group_window = context_size * 2 + groups = [] + group = [] + _operations.each do |tag, from_start, from_end, to_start, to_end| + if tag == :equal and from_end - from_start > group_window + group << [tag, + from_start, + [from_end, from_start + context_size].min, + to_start, + [to_end, to_start + context_size].min] + groups << group + group = [] + from_start = [from_start, from_end - context_size].max + to_start = [to_start, to_end - context_size].max + end + group << [tag, from_start, from_end, to_start, to_end] + end + groups << group unless group.empty? + groups + end + + def ratio + @ratio ||= compute_ratio + end + + private + def update_to_indexes + @to_indexes = {} + @junks = {} + if @to.is_a?(String) + each = " "[0].is_a?(Integer) ? :each_byte : :each_char + else + each = :each + end + i = 0 + @to.__send__(each) do |item| + @to_indexes[item] ||= [] + @to_indexes[item] << i + i += 1 + end + + return if @junk_predicate.nil? + @to_indexes = @to_indexes.reject do |key, value| + junk = @junk_predicate.call(key) + @junks[key] = true if junk + junk + end + end + + def find_best_match_position(from_start, from_end, to_start, to_end) + best_from, best_to, best_size = from_start, to_start, 0 + sizes = {} + from_start.upto(from_end) do |from_index| + _sizes = {} + (@to_indexes[@from[from_index]] || []).each do |to_index| + next if to_index < to_start + break if to_index > to_end + size = _sizes[to_index] = (sizes[to_index - 1] || 0) + 1 + if size > best_size + best_from = from_index - size + 1 + best_to = to_index - size + 1 + best_size = size + end + end + sizes = _sizes + end + [best_from, best_to, best_size] + end + + def adjust_best_info_with_junk_predicate(should_junk, best_info, + from_start, from_end, + to_start, to_end) + best_from, best_to, best_size = best_info + while best_from > from_start and best_to > to_start and + (should_junk ? + @junks.has_key?(@to[best_to - 1]) : + !@junks.has_key?(@to[best_to - 1])) and + @from[best_from - 1] == @to[best_to - 1] + best_from -= 1 + best_to -= 1 + best_size += 1 + end + + while best_from + best_size < from_end and + best_to + best_size < to_end and + (should_junk ? + @junks.has_key?(@to[best_to + best_size]) : + !@junks.has_key?(@to[best_to + best_size])) and + @from[best_from + best_size] == @to[best_to + best_size] + best_size += 1 + end + + [best_from, best_to, best_size] + end + + def matches + @matches ||= compute_matches + end + + def compute_matches + matches = [] + queue = [[0, @from.size, 0, @to.size]] + until queue.empty? + from_start, from_end, to_start, to_end = queue.pop + match = longest_match(from_start, from_end - 1, to_start, to_end - 1) + match_from_index, match_to_index, size = match + unless size.zero? + if from_start < match_from_index and + to_start < match_to_index + queue.push([from_start, match_from_index, + to_start, match_to_index]) + end + matches << match + if match_from_index + size < from_end and + match_to_index + size < to_end + queue.push([match_from_index + size, from_end, + match_to_index + size, to_end]) + end + end + end + matches.sort_by do |(from_index, _, _)| + from_index + end + end + + def compute_blocks + blocks = [] + current_from_index = current_to_index = current_size = 0 + matches.each do |from_index, to_index, size| + if current_from_index + current_size == from_index and + current_to_index + current_size == to_index + current_size += size + else + unless current_size.zero? + blocks << [current_from_index, current_to_index, current_size] + end + current_from_index = from_index + current_to_index = to_index + current_size = size + end + end + unless current_size.zero? + blocks << [current_from_index, current_to_index, current_size] + end + + blocks << [@from.size, @to.size, 0] + blocks + end + + def compute_operations + from_index = to_index = 0 + operations = [] + blocks.each do |match_from_index, match_to_index, size| + tag = determine_tag(from_index, to_index, + match_from_index, match_to_index) + if tag != :equal + operations << [tag, + from_index, match_from_index, + to_index, match_to_index] + end + + from_index, to_index = match_from_index + size, match_to_index + size + if size > 0 + operations << [:equal, + match_from_index, from_index, + match_to_index, to_index] + end + end + operations + end + + def compute_ratio + matches = blocks.inject(0) {|result, block| result + block[-1]} + length = @from.length + @to.length + if length.zero? + 1.0 + else + 2.0 * matches / length + end + end + + def determine_tag(from_index, to_index, + match_from_index, match_to_index) + if from_index < match_from_index and to_index < match_to_index + :replace + elsif from_index < match_from_index + :delete + elsif to_index < match_to_index + :insert + else + :equal + end + end + + def expand_edge_equal_operations!(_operations, context_size) + tag, from_start, from_end, to_start, to_end = _operations[0] + if tag == :equal + _operations[0] = [tag, + [from_start, from_end - context_size].max, + from_end, + [to_start, to_end - context_size].max, + to_end] + end + + tag, from_start, from_end, to_start, to_end = _operations[-1] + if tag == :equal + _operations[-1] = [tag, + from_start, + [from_end, from_start + context_size].min, + to_start, + [to_end, to_start + context_size].min] + end + end + end + + class Differ + def initialize(from, to) + @from = from + @to = to + end + + private + def tag(mark, contents) + contents.collect {|content| "#{mark}#{content}"} + end + end + + class UTF8Line + class << self + # from http://unicode.org/reports/tr11/ + WIDE_CHARACTERS = + [0x1100..0x1159, 0x115F..0x115F, 0x2329..0x232A, + 0x2E80..0x2E99, 0x2E9B..0x2EF3, 0x2F00..0x2FD5, + 0x2FF0..0x2FFB, 0x3000..0x303E, 0x3041..0x3096, + 0x3099..0x30FF, 0x3105..0x312D, 0x3131..0x318E, + 0x3190..0x31B7, 0x31C0..0x31E3, 0x31F0..0x321E, + 0x3220..0x3243, 0x3250..0x32FE, 0x3300..0x4DB5, + 0x4E00..0x9FC3, 0xA000..0xA48C, 0xA490..0xA4C6, + 0xAC00..0xD7A3, 0xF900..0xFA2D, 0xFA30..0xFA6A, + 0xFA70..0xFAD9, 0xFE10..0xFE19, 0xFE30..0xFE52, + 0xFE54..0xFE66, 0xFE68..0xFE6B, 0xFF01..0xFF60, + 0xFFE0..0xFFE6, 0x20000..0x2FFFD, 0x30000..0x3FFFD, + ] + + AMBIGUOUS = + [0x00A1..0x00A1, 0x00A4..0x00A4, 0x00A7..0x00A8, + 0x00AA..0x00AA, 0x00AD..0x00AE, 0x00B0..0x00B4, + 0x00B6..0x00BA, 0x00BC..0x00BF, 0x00C6..0x00C6, + 0x00D0..0x00D0, 0x00D7..0x00D8, 0x00DE..0x00E1, + 0x00E6..0x00E6, 0x00E8..0x00EA, 0x00EC..0x00ED, + 0x00F0..0x00F0, 0x00F2..0x00F3, 0x00F7..0x00FA, + 0x00FC..0x00FC, 0x00FE..0x00FE, 0x0101..0x0101, + 0x0111..0x0111, 0x0113..0x0113, 0x011B..0x011B, + 0x0126..0x0127, 0x012B..0x012B, 0x0131..0x0133, + 0x0138..0x0138, 0x013F..0x0142, 0x0144..0x0144, + 0x0148..0x014B, 0x014D..0x014D, 0x0152..0x0153, + 0x0166..0x0167, 0x016B..0x016B, 0x01CE..0x01CE, + 0x01D0..0x01D0, 0x01D2..0x01D2, 0x01D4..0x01D4, + 0x01D6..0x01D6, 0x01D8..0x01D8, 0x01DA..0x01DA, + 0x01DC..0x01DC, 0x0251..0x0251, 0x0261..0x0261, + 0x02C4..0x02C4, 0x02C7..0x02C7, 0x02C9..0x02CB, + 0x02CD..0x02CD, 0x02D0..0x02D0, 0x02D8..0x02DB, + 0x02DD..0x02DD, 0x02DF..0x02DF, 0x0300..0x036F, + 0x0391..0x03A1, 0x03A3..0x03A9, 0x03B1..0x03C1, + 0x03C3..0x03C9, 0x0401..0x0401, 0x0410..0x044F, + 0x0451..0x0451, 0x2010..0x2010, 0x2013..0x2016, + 0x2018..0x2019, 0x201C..0x201D, 0x2020..0x2022, + 0x2024..0x2027, 0x2030..0x2030, 0x2032..0x2033, + 0x2035..0x2035, 0x203B..0x203B, 0x203E..0x203E, + 0x2074..0x2074, 0x207F..0x207F, 0x2081..0x2084, + 0x20AC..0x20AC, 0x2103..0x2103, 0x2105..0x2105, + 0x2109..0x2109, 0x2113..0x2113, 0x2116..0x2116, + 0x2121..0x2122, 0x2126..0x2126, 0x212B..0x212B, + 0x2153..0x2154, 0x215B..0x215E, 0x2160..0x216B, + 0x2170..0x2179, 0x2190..0x2199, 0x21B8..0x21B9, + 0x21D2..0x21D2, 0x21D4..0x21D4, 0x21E7..0x21E7, + 0x2200..0x2200, 0x2202..0x2203, 0x2207..0x2208, + 0x220B..0x220B, 0x220F..0x220F, 0x2211..0x2211, + 0x2215..0x2215, 0x221A..0x221A, 0x221D..0x2220, + 0x2223..0x2223, 0x2225..0x2225, 0x2227..0x222C, + 0x222E..0x222E, 0x2234..0x2237, 0x223C..0x223D, + 0x2248..0x2248, 0x224C..0x224C, 0x2252..0x2252, + 0x2260..0x2261, 0x2264..0x2267, 0x226A..0x226B, + 0x226E..0x226F, 0x2282..0x2283, 0x2286..0x2287, + 0x2295..0x2295, 0x2299..0x2299, 0x22A5..0x22A5, + 0x22BF..0x22BF, 0x2312..0x2312, 0x2460..0x24E9, + 0x24EB..0x254B, 0x2550..0x2573, 0x2580..0x258F, + 0x2592..0x2595, 0x25A0..0x25A1, 0x25A3..0x25A9, + 0x25B2..0x25B3, 0x25B6..0x25B7, 0x25BC..0x25BD, + 0x25C0..0x25C1, 0x25C6..0x25C8, 0x25CB..0x25CB, + 0x25CE..0x25D1, 0x25E2..0x25E5, 0x25EF..0x25EF, + 0x2605..0x2606, 0x2609..0x2609, 0x260E..0x260F, + 0x2614..0x2615, 0x261C..0x261C, 0x261E..0x261E, + 0x2640..0x2640, 0x2642..0x2642, 0x2660..0x2661, + 0x2663..0x2665, 0x2667..0x266A, 0x266C..0x266D, + 0x266F..0x266F, 0x273D..0x273D, 0x2776..0x277F, + 0xE000..0xF8FF, 0xFE00..0xFE0F, 0xFFFD..0xFFFD, + 0xE0100..0xE01EF, 0xF0000..0xFFFFD, 0x100000..0x10FFFD, + ] + + def wide_character?(character) + binary_search_ranges(character, WIDE_CHARACTERS) or + binary_search_ranges(character, AMBIGUOUS) + end + + private + def binary_search_ranges(character, ranges) + if ranges.size.zero? + false + elsif ranges.size == 1 + ranges[0].include?(character) + else + half = ranges.size / 2 + range = ranges[half] + if range.include?(character) + true + elsif character < range.begin + binary_search_ranges(character, ranges[0...half]) + else + binary_search_ranges(character, ranges[(half + 1)..-1]) + end + end + end + end + + def initialize(line) + @line = line + @characters = @line.unpack("U*") + end + + def [](*args) + result = @characters[*args] + if result.respond_to?(:pack) + result.pack("U*") + else + result + end + end + + def each(&block) + @characters.each(&block) + end + + def size + @characters.size + end + + def to_s + @line + end + + def compute_width(start, _end) + width = 0 + start.upto(_end - 1) do |i| + if self.class.wide_character?(@characters[i]) + width += 2 + else + width += 1 + end + end + width + end + end + + class ReadableDiffer < Differ + def diff(options={}) + @result = [] + operations.each do |tag, from_start, from_end, to_start, to_end| + case tag + when :replace + diff_lines(from_start, from_end, to_start, to_end) + when :delete + tag_deleted(@from[from_start...from_end]) + when :insert + tag_inserted(@to[to_start...to_end]) + when :equal + tag_equal(@from[from_start...from_end]) + else + raise "unknown tag: #{tag}" + end + end + @result + end + + private + def operations + @operations ||= nil + if @operations.nil? + matcher = SequenceMatcher.new(@from, @to) + @operations = matcher.operations + end + @operations + end + + def default_ratio + 0.74 + end + + def cut_off_ratio + 0.75 + end + + def tag(mark, contents) + contents.each do |content| + @result << "#{mark}#{content}" + end + end + + def tag_deleted(contents) + tag("- ", contents) + end + + def tag_inserted(contents) + tag("+ ", contents) + end + + def tag_equal(contents) + tag(" ", contents) + end + + def tag_difference(contents) + tag("? ", contents) + end + + def find_diff_line_info(from_start, from_end, to_start, to_end) + best_ratio = default_ratio + from_equal_index = to_equal_index = nil + from_best_index = to_best_index = nil + + to_start.upto(to_end - 1) do |to_index| + from_start.upto(from_end - 1) do |from_index| + if @from[from_index] == @to[to_index] + from_equal_index ||= from_index + to_equal_index ||= to_index + next + end + + matcher = SequenceMatcher.new(@from[from_index], @to[to_index], + &method(:space_character?)) + if matcher.ratio > best_ratio + best_ratio = matcher.ratio + from_best_index = from_index + to_best_index = to_index + end + end + end + + [best_ratio, + from_equal_index, to_equal_index, + from_best_index, to_best_index] + end + + def diff_lines(from_start, from_end, to_start, to_end) + info = find_diff_line_info(from_start, from_end, to_start, to_end) + best_ratio, from_equal_index, to_equal_index, *info = info + from_best_index, to_best_index = info + from_best_index ||= from_start + to_best_index ||= to_start + + if best_ratio < cut_off_ratio + if from_equal_index.nil? + if to_end - to_start < from_end - from_start + tag_inserted(@to[to_start...to_end]) + tag_deleted(@from[from_start...from_end]) + else + tag_deleted(@from[from_start...from_end]) + tag_inserted(@to[to_start...to_end]) + end + return + end + from_best_index = from_equal_index + to_best_index = to_equal_index + best_ratio = 1.0 + end + + _diff_lines(from_start, from_best_index, to_start, to_best_index) + diff_line(@from[from_best_index], @to[to_best_index]) + _diff_lines(from_best_index + 1, from_end, to_best_index + 1, to_end) + end + + def _diff_lines(from_start, from_end, to_start, to_end) + if from_start < from_end + if to_start < to_end + diff_lines(from_start, from_end, to_start, to_end) + else + tag_deleted(@from[from_start...from_end]) + end + else + tag_inserted(@to[to_start...to_end]) + end + end + + def line_operations(from_line, to_line) + if !from_line.respond_to?(:force_encoding) and $KCODE == "UTF8" + from_line = UTF8Line.new(from_line) + to_line = UTF8Line.new(to_line) + end + matcher = SequenceMatcher.new(from_line, to_line, + &method(:space_character?)) + [from_line, to_line, matcher.operations] + end + + def compute_width(line, start, _end) + if line.respond_to?(:encoding) and + Encoding.compatible?(Encoding::UTF_8, line.encoding) + utf8_line = line[start..._end].encode(Encoding::UTF_8) + width = 0 + utf8_line.each_codepoint do |unicode_codepoint| + if UTF8Line.wide_character?(unicode_codepoint) + width += 2 + else + width += 1 + end + end + width + elsif line.is_a?(UTF8Line) + line.compute_width(start, _end) + else + _end - start + end + end + + def diff_line(from_line, to_line) + from_tags = "" + to_tags = "" + from_line, to_line, _operations = line_operations(from_line, to_line) + _operations.each do |tag, from_start, from_end, to_start, to_end| + from_width = compute_width(from_line, from_start, from_end) + to_width = compute_width(to_line, to_start, to_end) + case tag + when :replace + from_tags << "^" * from_width + to_tags << "^" * to_width + when :delete + from_tags << "-" * from_width + when :insert + to_tags << "+" * to_width + when :equal + from_tags << " " * from_width + to_tags << " " * to_width + else + raise "unknown tag: #{tag}" + end + end + format_diff_point(from_line, to_line, from_tags, to_tags) + end + + def format_diff_point(from_line, to_line, from_tags, to_tags) + common = [n_leading_characters(from_line, ?\t), + n_leading_characters(to_line, ?\t)].min + common = [common, + n_leading_characters(from_tags[0, common], " "[0])].min + from_tags = from_tags[common..-1].rstrip + to_tags = to_tags[common..-1].rstrip + + tag_deleted([from_line]) + unless from_tags.empty? + tag_difference(["#{"\t" * common}#{from_tags}"]) + end + tag_inserted([to_line]) + unless to_tags.empty? + tag_difference(["#{"\t" * common}#{to_tags}"]) + end + end + + def n_leading_characters(string, character) + n = 0 + while string[n] == character + n += 1 + end + n + end + + def space_character?(character) + [" "[0], "\t"[0]].include?(character) + end + end + + class UnifiedDiffer < Differ + def diff(options={}) + groups = SequenceMatcher.new(@from, @to).grouped_operations + return [] if groups.empty? + return [] if same_content?(groups) + + show_context = options[:show_context] + show_context = true if show_context.nil? + result = ["--- #{options[:from_label]}".rstrip, + "+++ #{options[:to_label]}".rstrip] + groups.each do |operations| + result << format_summary(operations, show_context) + operations.each do |args| + operation_tag, from_start, from_end, to_start, to_end = args + case operation_tag + when :replace + result.concat(tag("-", @from[from_start...from_end])) + result.concat(tag("+", @to[to_start...to_end])) + when :delete + result.concat(tag("-", @from[from_start...from_end])) + when :insert + result.concat(tag("+", @to[to_start...to_end])) + when :equal + result.concat(tag(" ", @from[from_start...from_end])) + end + end + end + result + end + + private + def same_content?(groups) + return false if groups.size != 1 + group = groups[0] + return false if group.size != 1 + tag, from_start, from_end, to_start, to_end = group[0] + + tag == :equal and [from_start, from_end] == [to_start, to_end] + end + + def format_summary(operations, show_context) + _, first_from_start, _, first_to_start, _ = operations[0] + _, _, last_from_end, _, last_to_end = operations[-1] + summary = "@@ -%d,%d +%d,%d @@" % [first_from_start + 1, + last_from_end - first_from_start, + first_to_start + 1, + last_to_end - first_to_start,] + if show_context + interesting_line = find_interesting_line(first_from_start, + first_to_start, + :define_line?) + summary << " #{interesting_line}" if interesting_line + end + summary + end + + def find_interesting_line(from_start, to_start, predicate) + from_index = from_start + to_index = to_start + while from_index >= 0 or to_index >= 0 + [@from[from_index], @to[to_index]].each do |line| + return line if line and __send__(predicate, line) + end + + from_index -= 1 + to_index -= 1 + end + nil + end + + def define_line?(line) + /\A(?:[_a-zA-Z$]|\s*(?:class|module|def)\b)/ =~ line + end + end + + module_function + def need_fold?(diff) + /^[-+].{79}/ =~ diff + end + + def fold(string) + string.split(/\r?\n/).collect do |line| + line.gsub(/(.{78})/, "\\1\n") + end.join("\n") + end + + def folded_readable(from, to, options={}) + readable(fold(from), fold(to), options) + end + + def readable(from, to, options={}) + diff(ReadableDiffer, from, to, options) + end + + def unified(from, to, options={}) + diff(UnifiedDiffer, from, to, options) + end + + def diff(differ_class, from, to, options={}) + if from.respond_to?(:valid_encoding?) and not from.valid_encoding? + from = from.dup.force_encoding("ASCII-8BIT") + end + if to.respond_to?(:valid_encoding?) and not to.valid_encoding? + to = to.dup.force_encoding("ASCII-8BIT") + end + differ = differ_class.new(from.split(/\r?\n/), to.split(/\r?\n/)) + lines = differ.diff(options) + if Object.const_defined?(:EncodingError) + begin + lines.join("\n") + rescue EncodingError + lines.collect {|line| line.force_encoding("ASCII-8BIT")}.join("\n") + end + else + lines.join("\n") + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/error.rb b/testdata/vendor/ruby/test/unit/error.rb new file mode 100644 index 000000000..1b5652472 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/error.rb @@ -0,0 +1,158 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/util/backtracefilter' + +module Test + module Unit + + # Encapsulates an error in a test. Created by + # Test::Unit::TestCase when it rescues an exception thrown + # during the processing of a test. + class Error + include Util::BacktraceFilter + + attr_reader :test_name, :exception + attr_reader :method_name + + SINGLE_CHARACTER = 'E' + LABEL = "Error" + + # Creates a new Error with the given test_name and + # exception. + def initialize(test_name, exception, options={}) + @test_name = test_name + @exception = exception + @method_name = options[:method_name] + end + + # Returns a single character representation of an error. + def single_character_display + SINGLE_CHARACTER + end + + def label + LABEL + end + + # Returns the message associated with the error. + def message + "#{@exception.class.name}: #{@exception.message}" + end + + # Returns a brief version of the error description. + def short_display + "#@test_name: #{message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + backtrace_display = location.join("\n ") + "#{label}:\n#@test_name:\n#{message}\n #{backtrace_display}" + end + + def location + @location ||= filter_backtrace(@exception.backtrace) + end + alias_method :backtrace, :location # Deprecated + + # Overridden to return long_display. + def to_s + long_display + end + + def critical? + true + end + end + + module ErrorHandler + class << self + def included(base) + base.exception_handler(:handle_all_exception) + end + end + + NOT_PASS_THROUGH_EXCEPTIONS = [] + NOT_PASS_THROUGH_EXCEPTION_NAMES = ["Timeout::Error"] + PASS_THROUGH_EXCEPTIONS = [ + NoMemoryError, + SignalException, + Interrupt, + SystemExit, + ] + PASS_THROUGH_EXCEPTION_NAMES = [] + private + def handle_all_exception(exception) + return false if pass_through_exception?(exception) + + problem_occurred + add_error(exception) + true + end + + def pass_through_exception?(exception) + case exception + when *NOT_PASS_THROUGH_EXCEPTIONS + return false + end + case exception.class.name + when *NOT_PASS_THROUGH_EXCEPTION_NAMES + return false + end + + case exception + when *PASS_THROUGH_EXCEPTIONS + return true + end + case exception.class.name + when *PASS_THROUGH_EXCEPTION_NAMES + return true + end + + false + end + + def add_error(exception) + error = Error.new(name, exception, :method_name => @method_name) + current_result.add_error(error) + end + end + + module TestResultErrorSupport + attr_reader :errors + + # Records a Test::Unit::Error. + def add_error(error) + @errors << error + notify_fault(error) + notify_changed + end + + # Returns the number of errors this TestResult has + # recorded. + def error_count + @errors.size + end + + def error_occurred? + not @errors.empty? + end + + private + def initialize_containers + super + @errors = [] + @summary_generators << :error_summary + @problem_checkers << :error_occurred? + end + + def error_summary + "#{error_count} errors" + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/exception-handler.rb b/testdata/vendor/ruby/test/unit/exception-handler.rb new file mode 100644 index 000000000..9a5f1a2c4 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/exception-handler.rb @@ -0,0 +1,82 @@ +module Test + module Unit + module ExceptionHandler + @@exception_handlers = [] + class << self + def exception_handlers + @@exception_handlers + end + + def included(base) + base.extend(ClassMethods) + + observer = Proc.new do |test_case, _, _, value, method_name| + if value + @@exception_handlers.unshift(method_name) + else + @@exception_handlers.delete(method_name) + end + end + base.register_attribute_observer(:exception_handler, &observer) + end + end + + module ClassMethods + def exception_handlers + ExceptionHandler.exception_handlers + end + + # @overload exception_handler(method_name) + # Add an exception handler method. + # + # @param method_name [Symbol] + # The method name that handles exception raised in tests. + # @return [void] + # + # @overload exception_handler(&callback) + # Add an exception handler. + # + # @yield [test, exception] + # Gives the test and the exception. + # @yieldparam test [Test::Unit::TestCase] + # The test where the exception is raised. + # @yieldparam exception [Exception] + # The exception that is raised in running the test. + # @yieldreturn [Boolean] + # Whether the handler handles the exception or not. + # The handler must return _true_ if the handler handles + # test exception, _false_ otherwise. + # @return [void] + # + # This is a public API for developers who extend test-unit. + def exception_handler(*method_name_or_handlers, &block) + if block_given? + exception_handlers.unshift(block) + else + method_name_or_handlers.each do |method_name_or_handler| + if method_name_or_handler.respond_to?(:call) + handler = method_name_or_handler + exception_handlers.unshift(handler) + else + method_name = method_name_or_handler + attribute(:exception_handler, true, {}, method_name) + end + end + end + end + + def unregister_exception_handler(*method_name_or_handlers) + method_name_or_handlers.each do |method_name_or_handler| + if method_name_or_handler.respond_to?(:call) + handler = method_name_or_handler + exception_handlers.delete(handler) + else + method_name = method_name_or_handler + attribute(:exception_handler, false, {}, method_name) + end + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/failure.rb b/testdata/vendor/ruby/test/unit/failure.rb new file mode 100644 index 000000000..2e386cfc3 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/failure.rb @@ -0,0 +1,169 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + + # Encapsulates a test failure. Created by Test::Unit::TestCase + # when an assertion fails. + class Failure + attr_reader :test_name, :location, :message + attr_reader :method_name, :source_location + attr_reader :expected, :actual, :user_message + attr_reader :inspected_expected, :inspected_actual + + SINGLE_CHARACTER = 'F' + LABEL = "Failure" + + # Creates a new Failure with the given location and + # message. + def initialize(test_name, location, message, options={}) + @test_name = test_name + @location = location + @message = message + @method_name = options[:method_name] + @source_location = options[:source_location] + @expected = options[:expected] + @actual = options[:actual] + @inspected_expected = options[:inspected_expected] + @inspected_actual = options[:inspected_actual] + @user_message = options[:user_message] + end + + # Returns a single character representation of a failure. + def single_character_display + SINGLE_CHARACTER + end + + def label + LABEL + end + + # Returns a brief version of the error description. + def short_display + "#@test_name: #{@message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + if location.size == 1 + location_display = location[0].sub(/\A(.+:\d+).*/, ' [\\1]') + else + location_display = "\n [#{location.join("\n ")}]" + end + "#{label}:\n#@test_name#{location_display}:\n#@message" + end + + # Overridden to return long_display. + def to_s + long_display + end + + def critical? + true + end + + def diff + @diff ||= compute_diff + end + + private + def compute_diff + Assertions::AssertionMessage.delayed_diff(@expected, @actual).inspect + end + end + + module FailureHandler + class << self + def included(base) + base.exception_handler(:handle_assertion_failed_error) + end + end + + # Report a failure. + # + # This is a public API for developers who extend test-unit. + # + # @param message [String] The description about the failure. + # @param backtrace [Array] The backtrace for the failure. + # @option options [Object] :expected + # The expected value of the assertion. + # @option options [Object] :actual + # The actual value of the assertion. + # @option options [String] :inspected_expected + # The inspected expected value of the assertion. + # It is used for diff between expected and actual of the failure. + # @option options [String] :inspected_actual + # The inspected actual value of the assertion. + # It is used for diff between expected and actual of the failure. + # @option options [String] :user_message + # The message of the assertion from user. + # @option options [String] :method_name (@method_name) + # The method name of the test. + # @option options [Array] :source_location + # The location where the test is defined. It is the same + # format as Proc#source_location. That is, it's an array of + # path and and line number where the test definition is + # started. + # @return [void] + def add_failure(message, backtrace, options={}) + default_options = { + :method_name => @method_name, + :source_location => self[:source_location], + } + failure = Failure.new(name, filter_backtrace(backtrace), message, + default_options.merge(options)) + current_result.add_failure(failure) + end + + private + def handle_assertion_failed_error(exception) + return false unless exception.is_a?(AssertionFailedError) + problem_occurred + add_failure(exception.message, exception.backtrace, + :expected => exception.expected, + :actual => exception.actual, + :inspected_expected => exception.inspected_expected, + :inspected_actual => exception.inspected_actual, + :user_message => exception.user_message) + true + end + end + + module TestResultFailureSupport + attr_reader :failures + + # Records a Test::Unit::Failure. + def add_failure(failure) + @failures << failure + notify_fault(failure) + notify_changed + end + + # Returns the number of failures this TestResult has + # recorded. + def failure_count + @failures.size + end + + def failure_occurred? + not @failures.empty? + end + + private + def initialize_containers + super + @failures = [] + @summary_generators << :failure_summary + @problem_checkers << :failure_occurred? + end + + def failure_summary + "#{failure_count} failures" + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/fault-location-detector.rb b/testdata/vendor/ruby/test/unit/fault-location-detector.rb new file mode 100644 index 000000000..b783be17a --- /dev/null +++ b/testdata/vendor/ruby/test/unit/fault-location-detector.rb @@ -0,0 +1,100 @@ +# Copyright (C) 2012 Kouhei Sutou +# +# License: Ruby's + +require "English" + +module Test + module Unit + class FaultLocationDetector + def initialize(fault, code_snippet_fetcher) + @fault = fault + @code_snippet_fetcher = code_snippet_fetcher + extract_fault_information + end + + def split_backtrace_entry(entry) + match_data = /\A(.+):(\d+)(?::(.*))?\z/.match(entry) + return nil if match_data.nil? + file, line_number, context = match_data.to_a[1..-1] + line_number = line_number.to_i + if /\Ain `(.+?)'/ =~ context + method_name = $1 + if /\Ablock (?:\(.+?\) )?in / =~ method_name + method_name = $POSTMATCH + end + else + method_name = nil + end + [file, line_number, context, method_name] + end + + def target?(backtrace_entry) + file, line_number, context, method_name = + split_backtrace_entry(backtrace_entry) + _ = context + return false if file.nil? + + if @fault_source_location + target_source_location?(file, line_number, method_name) + elsif @fault_method_name + target_method?(method_name) + else + true + end + end + + private + def target_source_location?(file, line_number, method_name) + fault_file, fault_line_number = @fault_source_location + return false unless file.end_with?(fault_file) + + return false if line_number < fault_line_number + + lines = @code_snippet_fetcher.source(file) + return false if lines.nil? + + base_indent_level = nil + fault_line_number.step(lines.size) do |current_line_number| + line = lines[current_line_number - 1] + current_indent_level = guess_indent_level(line) + base_indent_level ||= current_indent_level + return true if current_line_number == line_number + + if current_line_number == fault_line_number + break if /(?:\send|\})\s*$/ =~ line + else + break if current_indent_level == base_indent_level + end + end + false + end + + def target_method?(method_name) + @fault_method_name == method_name + end + + def guess_indent_level(line) + if /\A(\s*)/ =~ line + $1.sub(/\t/, " " * 8).count(" ") + else + 0 + end + end + + def extract_fault_information + if @fault.respond_to?(:source_location) + @fault_source_location = @fault.source_location + else + @fault_source_location = nil + end + + if @fault.respond_to?(:method_name) + @fault_method_name = @fault.method_name + else + @fault_method_name = nil + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/fixture.rb b/testdata/vendor/ruby/test/unit/fixture.rb new file mode 100644 index 000000000..59228f52c --- /dev/null +++ b/testdata/vendor/ruby/test/unit/fixture.rb @@ -0,0 +1,295 @@ +module Test + module Unit + module Fixture + class << self + def included(base) + base.extend(ClassMethods) + + [:setup, :cleanup, :teardown].each do |type| + observer = lambda do |test_case, _, _, value, callback| + if value.nil? + test_case.fixture[type].unregister(callback) + else + test_case.fixture[type].register(callback, value) + end + end + base.register_attribute_observer(type, &observer) + end + end + end + + class Fixture + attr_reader :setup + attr_reader :cleanup + attr_reader :teardown + def initialize(test_case) + @test_case = test_case + @setup = HookPoint.new(@test_case, :setup, :after => :append) + @cleanup = HookPoint.new(@test_case, :cleanup, :before => :prepend) + @teardown = HookPoint.new(@test_case, :teardown, :before => :prepend) + @cached_before_callbacks = {} + @cached_after_callbacks = {} + end + + def [](type) + case type + when :setup + @setup + when :cleanup + @cleanup + when :teardown + @teardown + end + end + + def before_callbacks(type) + @cached_before_callbacks[type] ||= collect_before_callbacks(type) + end + + def after_callbacks(type) + @cached_after_callbacks[type] ||= collect_after_callbacks(type) + end + + private + def target_test_cases + @cached_target_test_cases ||= collect_target_test_cases + end + + def collect_before_callbacks(type) + prepend_callbacks = [] + append_callbacks = [] + target_test_cases.each do |ancestor| + prepend_callbacks << ancestor.fixture[type].before_prepend_callbacks + append_callbacks << ancestor.fixture[type].before_append_callbacks + end + + merge_callbacks(prepend_callbacks, append_callbacks) + end + + def collect_after_callbacks(type) + prepend_callbacks = [] + append_callbacks = [] + target_test_cases.each do |ancestor| + prepend_callbacks << ancestor.fixture[type].after_prepend_callbacks + append_callbacks << ancestor.fixture[type].after_append_callbacks + end + + merge_callbacks(prepend_callbacks, append_callbacks) + end + + def collect_target_test_cases + ancestors = @test_case.ancestors + base_index = ancestors.index(::Test::Unit::Fixture) + interested_ancestors = ancestors[0, base_index].find_all do |ancestor| + ancestor.is_a?(Class) + end + interested_ancestors.reverse + end + + def merge_callbacks(prepend_callbacks, append_callbacks) + all_callbacks = [] + prepend_callbacks.reverse_each do |callbacks| + all_callbacks.concat(callbacks) + end + append_callbacks.each do |callbacks| + all_callbacks.concat(callbacks) + end + all_callbacks + end + end + + class HookPoint + def initialize(test_case, type, default_options) + @test_case = test_case + @type = type + @default_options = default_options + @before_prepend_callbacks = [] + @before_append_callbacks = [] + @after_prepend_callbacks = [] + @after_append_callbacks = [] + @unregistered_callbacks = [] + end + + def register(method_name_or_callback, options=nil) + options ||= {} + unless valid_register_options?(options) + message = "must be {:before => :prepend}, " + + "{:before => :append}, {:after => :prepend} or " + + "{:after => :append}: #{options.inspect}" + raise ArgumentError, message + end + + if options.empty? + options = @default_options + end + before_how = options[:before] + after_how = options[:after] + if method_name_or_callback.respond_to?(:call) + callback = method_name_or_callback + method_name = callback_method_name(callback) + @test_case.__send__(:define_method, method_name, &callback) + else + method_name = method_name_or_callback + end + add_callback(method_name, before_how, after_how) + end + + def unregister(method_name_or_callback) + if method_name_or_callback.respond_to?(:call) + callback = method_name_or_callback + method_name = callback_method_name(callback) + else + method_name = method_name_or_callback + end + @unregistered_callbacks << method_name + end + + def before_prepend_callbacks + @before_prepend_callbacks - @unregistered_callbacks + end + + def before_append_callbacks + @before_append_callbacks - @unregistered_callbacks + end + + def after_prepend_callbacks + @after_prepend_callbacks - @unregistered_callbacks + end + + def after_append_callbacks + @after_append_callbacks - @unregistered_callbacks + end + + private + def valid_register_options?(options) + return true if options.empty? + return false if options.size > 1 + + key = options.keys.first + [:before, :after].include?(key) and + [:prepend, :append].include?(options[key]) + end + + def callback_method_name(callback) + "#{@type}_#{callback.object_id}" + end + + def add_callback(method_name_or_callback, before_how, after_how) + case before_how + when :prepend + @before_prepend_callbacks = + [method_name_or_callback] | @before_prepend_callbacks + when :append + @before_append_callbacks |= [method_name_or_callback] + else + case after_how + when :prepend + @after_prepend_callbacks = + [method_name_or_callback] | @after_prepend_callbacks + when :append + @after_append_callbacks |= [method_name_or_callback] + end + end + end + end + + module ClassMethods + def fixture + @fixture ||= Fixture.new(self) + end + + def setup(*method_names, &callback) + register_fixture(:setup, *method_names, &callback) + end + + def unregister_setup(*method_names_or_callbacks) + unregister_fixture(:setup, *method_names_or_callbacks) + end + + def cleanup(*method_names, &callback) + register_fixture(:cleanup, *method_names, &callback) + end + + def unregister_cleanup(*method_names_or_callbacks) + unregister_fixture(:cleanup, *method_names_or_callbacks) + end + + def teardown(*method_names, &callback) + register_fixture(:teardown, *method_names, &callback) + end + + def unregister_teardown(*method_names_or_callbacks) + unregister_fixture(:teardown, *method_names_or_callbacks) + end + + private + def register_fixture(fixture, *method_names, &callback) + options = {} + options = method_names.pop if method_names.last.is_a?(Hash) + callbacks = method_names + callbacks << callback if callback + attribute(fixture, options, *callbacks) + end + + def unregister_fixture(fixture, *method_names_or_callbacks) + attribute(fixture, nil, *method_names_or_callbacks) + end + end + + private + def run_fixture(type, options={}, &block) + fixtures = [ + self.class.fixture.before_callbacks(type), + type, + self.class.fixture.after_callbacks(type), + ].flatten + if block + runner = create_fixtures_runner(fixtures, options, &block) + runner.call + else + fixtures.each do |method_name| + run_fixture_callback(method_name, options) + end + end + end + + def create_fixtures_runner(fixtures, options, &block) + if fixtures.empty? + block + else + last_fixture = fixtures.pop + create_fixtures_runner(fixtures, options) do + block_is_called = false + run_fixture_callback(last_fixture, options) do + block_is_called = true + block.call + end + block.call unless block_is_called + end + end + end + + def run_fixture_callback(method_name, options, &block) + return unless respond_to?(method_name, true) + begin + __send__(method_name, &block) + rescue Exception + raise unless options[:handle_exception] + raise unless handle_exception($!) + end + end + + def run_setup(&block) + run_fixture(:setup, &block) + end + + def run_cleanup + run_fixture(:cleanup) + end + + def run_teardown + run_fixture(:teardown, :handle_exception => true) + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/notification.rb b/testdata/vendor/ruby/test/unit/notification.rb new file mode 100644 index 000000000..cb0937772 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/notification.rb @@ -0,0 +1,136 @@ +require 'test/unit/util/backtracefilter' + +module Test + module Unit + class Notification + include Util::BacktraceFilter + attr_reader :test_name, :location, :message + attr_reader :method_name + + SINGLE_CHARACTER = 'N' + LABEL = "Notification" + + # Creates a new Notification with the given location and + # message. + def initialize(test_name, location, message, options={}) + @test_name = test_name + @location = location + @message = message + @method_name = options[:method_name] + end + + # Returns a single character representation of a notification. + def single_character_display + SINGLE_CHARACTER + end + + def label + LABEL + end + + # Returns a brief version of the error description. + def short_display + "#{@test_name}: #{@message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + backtrace = filter_backtrace(location).join("\n") + "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" + end + + # Overridden to return long_display. + def to_s + long_display + end + + def critical? + false + end + end + + class NotifiedError < StandardError + end + + + module TestCaseNotificationSupport + class << self + def included(base) + base.class_eval do + include NotificationHandler + end + end + end + + # Notify some information. + # + # Example: + # def test_notification + # notify("I'm here!") + # # Reached here + # notify("Special!") if special_case? + # # Reached here too + # end + # + # options: + # :backtrace override backtrace. + def notify(message, options={}, &block) + backtrace = filter_backtrace(options[:backtrace] || caller) + notification = Notification.new(name, backtrace, message, + :method_name => @method_name) + add_notification(notification) + end + + private + def add_notification(notification) + current_result.add_notification(notification) + end + end + + module NotificationHandler + class << self + def included(base) + base.exception_handler(:handle_notified_error) + end + end + + private + def handle_notified_error(exception) + return false unless exception.is_a?(NotifiedError) + notification = Notification.new(name, + filter_backtrace(exception.backtrace), + exception.message) + add_notification(notification) + true + end + end + + module TestResultNotificationSupport + attr_reader :notifications + + # Records a Test::Unit::Notification. + def add_notification(notification) + @notifications << notification + notify_fault(notification) + notify_changed + end + + # Returns the number of notifications this TestResult has + # recorded. + def notification_count + @notifications.size + end + + private + def initialize_containers + super + @notifications = [] + @summary_generators << :notification_summary + end + + def notification_summary + "#{notification_count} notifications" + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/omission.rb b/testdata/vendor/ruby/test/unit/omission.rb new file mode 100644 index 000000000..76c517fe6 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/omission.rb @@ -0,0 +1,195 @@ +require 'test/unit/util/backtracefilter' + +module Test + module Unit + class Omission + include Util::BacktraceFilter + attr_reader :test_name, :location, :message + attr_reader :method_name + + SINGLE_CHARACTER = 'O' + LABEL = "Omission" + + # Creates a new Omission with the given location and + # message. + def initialize(test_name, location, message, options={}) + @test_name = test_name + @location = location + @message = message + @method_name = options[:method_name] + end + + # Returns a single character representation of a omission. + def single_character_display + SINGLE_CHARACTER + end + + def label + LABEL + end + + # Returns a brief version of the error description. + def short_display + "#{@test_name}: #{@message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + backtrace = filter_backtrace(location).join("\n") + "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" + end + + # Overridden to return long_display. + def to_s + long_display + end + + def critical? + true + end + end + + class OmittedError < StandardError + end + + + module TestCaseOmissionSupport + class << self + def included(base) + base.class_eval do + include OmissionHandler + end + end + end + + # Omit the test or part of the test. + # + # Example: + # def test_omission + # omit + # # Not reached here + # end + # + # def test_omission_with_here + # omit do + # # Not ran here + # end + # # Reached here + # end + def omit(message=nil, &block) + message ||= "omitted." + if block_given? + omission = Omission.new(name, filter_backtrace(caller), message, + :method_name => @method_name) + add_omission(omission) + else + raise OmittedError.new(message) + end + end + + # Omit the test or part of the test if _condition_ is + # true. + # + # Example: + # def test_omission + # omit_if("".empty?) + # # Not reached here + # end + # + # def test_omission_with_here + # omit_if(true) do + # # Not ran here + # end + # omit_if(false) do + # # Reached here + # end + # # Reached here too + # end + def omit_if(condition, *args, &block) + if condition + omit(*args, &block) + else + block.call if block + end + end + + # Omit the test or part of the test if _condition_ is + # not true. + # + # Example: + # def test_omission + # omit_unless("string".empty?) + # # Not reached here + # end + # + # def test_omission_with_here + # omit_unless(true) do + # # Reached here + # end + # omit_unless(false) do + # # Not ran here + # end + # # Reached here too + # end + def omit_unless(condition, *args, &block) + if condition + block.call if block + else + omit(*args, &block) + end + end + + private + def add_omission(omission) + current_result.add_omission(omission) + end + end + + module OmissionHandler + class << self + def included(base) + base.exception_handler(:handle_omitted_error) + end + end + + private + def handle_omitted_error(exception) + return false unless exception.is_a?(OmittedError) + omission = Omission.new(name, + filter_backtrace(exception.backtrace), + exception.message, + :method_name => @method_name) + add_omission(omission) + true + end + end + + module TestResultOmissionSupport + attr_reader :omissions + + # Records a Test::Unit::Omission. + def add_omission(omission) + @omissions << omission + notify_fault(omission) + notify_changed + end + + # Returns the number of omissions this TestResult has + # recorded. + def omission_count + @omissions.size + end + + private + def initialize_containers + super + @omissions = [] + @summary_generators << :omission_summary + end + + def omission_summary + "#{omission_count} omissions" + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/pending.rb b/testdata/vendor/ruby/test/unit/pending.rb new file mode 100644 index 000000000..b970678a7 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/pending.rb @@ -0,0 +1,154 @@ +require 'test/unit/util/backtracefilter' + +module Test + module Unit + class Pending + include Util::BacktraceFilter + attr_reader :test_name, :location, :message + attr_reader :method_name + + SINGLE_CHARACTER = 'P' + LABEL = "Pending" + + # Creates a new Pending with the given location and + # message. + def initialize(test_name, location, message, options={}) + @test_name = test_name + @location = location + @message = message + @method_name = options[:method_name] + end + + # Returns a single character representation of a pending. + def single_character_display + SINGLE_CHARACTER + end + + def label + LABEL + end + + # Returns a brief version of the error description. + def short_display + "#{@test_name}: #{@message.split("\n")[0]}" + end + + # Returns a verbose version of the error description. + def long_display + backtrace = filter_backtrace(location).join("\n") + "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" + end + + # Overridden to return long_display. + def to_s + long_display + end + + def critical? + true + end + end + + class PendedError < StandardError + end + + + module TestCasePendingSupport + class << self + def included(base) + base.class_eval do + include PendingHandler + end + end + end + + # Marks the test or part of the test is pending. + # + # Example: + # def test_pending + # pend + # # Not reached here + # end + # + # def test_pending_with_here + # pend do + # # Ran here + # # Fails if the block doesn't raise any error. + # # Because it means the block is passed unexpectedly. + # end + # # Reached here + # end + def pend(message=nil, &block) + message ||= "pended." + if block_given? + pending = nil + begin + yield + rescue Exception + pending = Pending.new(name, filter_backtrace(caller), message, + :method_name => @method_name) + add_pending(pending) + end + unless pending + flunk("Pending block should not be passed: #{message}") + end + else + raise PendedError.new(message) + end + end + + private + def add_pending(pending) + problem_occurred + current_result.add_pending(pending) + end + end + + module PendingHandler + class << self + def included(base) + base.exception_handler(:handle_pended_error) + end + end + + private + def handle_pended_error(exception) + return false unless exception.is_a?(PendedError) + pending = Pending.new(name, + filter_backtrace(exception.backtrace), + exception.message, + :method_name => @method_name) + add_pending(pending) + true + end + end + + module TestResultPendingSupport + attr_reader :pendings + + # Records a Test::Unit::Pending. + def add_pending(pending) + @pendings << pending + notify_fault(pending) + notify_changed + end + + # Returns the number of pendings this TestResult has + # recorded. + def pending_count + @pendings.size + end + + private + def initialize_containers + super + @pendings = [] + @summary_generators << :pending_summary + end + + def pending_summary + "#{pending_count} pendings" + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/priority.rb b/testdata/vendor/ruby/test/unit/priority.rb new file mode 100644 index 000000000..75065d170 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/priority.rb @@ -0,0 +1,192 @@ +require "fileutils" + +module Test + module Unit + module Priority + class << self + def included(base) + base.extend(ClassMethods) + + base.class_eval do + setup :priority_setup, :before => :prepend + teardown :priority_teardown, :after => :append + end + end + + @@enabled = false + def enabled? + @@enabled + end + + def enable + require "fileutils" + require "tmpdir" + @@enabled = true + end + + def disable + @@enabled = false + end + + @@default = :normal + def default + @@default || :normal + end + + def default=(default) + @@default = default + end + + def available_values + Checker.available_priorities + end + end + + class Checker + class << self + def have_priority?(name) + singleton_class = (class << self; self; end) + singleton_class.method_defined?(priority_check_method_name(name)) + end + + def need_to_run?(test) + priority = test[:priority] || Priority.default + if have_priority?(priority) + __send__(priority_check_method_name(priority), test) + else + true + end + end + + def available_priorities + methods(false).collect do |name| + /\Arun_priority_(.+)\?\z/ =~ name.to_s + $1 + end.compact + end + + def run_priority_must?(test) + true + end + + def run_priority_important?(test) + rand > 0.1 + end + + def run_priority_high?(test) + rand > 0.3 + end + + def run_priority_normal?(test) + rand > 0.5 + end + + def run_priority_low?(test) + rand > 0.75 + end + + def run_priority_never?(test) + false + end + + private + def priority_check_method_name(priority_name) + "run_priority_#{priority_name}?" + end + end + + attr_reader :test + def initialize(test) + @test = test + end + + def setup + FileUtils.rm_f(passed_file) + end + + def teardown + if @test.__send__(:passed?) + FileUtils.touch(passed_file) + else + FileUtils.rm_f(passed_file) + end + end + + def need_to_run? + !previous_test_success? or self.class.need_to_run?(@test) + end + + private + def previous_test_success? + File.exist?(passed_file) + end + + def result_dir + components = [ + ".test-result", + escape_class_name(@test.class.name || "AnonymousTestCase"), + escaped_method_name, + ] + parent_directories = [File.dirname($0), Dir.pwd] + if Process.respond_to?(:uid) + parent_directories << File.join(Dir.tmpdir, Process.uid.to_s) + end + parent_directories.each do |parent_directory| + dir = File.expand_path(File.join(parent_directory, *components)) + begin + FileUtils.mkdir_p(dir) + return dir + rescue Errno::EACCES + end + end + + raise Errno::EACCES, parent_directories.join(", ") + end + + def passed_file + File.join(result_dir, "passed") + end + + def escape_class_name(class_name) + class_name.gsub(/(?:[: \\\/])/, "_") + end + + def escaped_method_name + @test.method_name.to_s.gsub(/(?:[: ]|[!?=]$)/) do |matched| + case matched + when ":" + "_colon_" + when " " + "_" + when "!" + ".destructive" + when "?" + ".predicate" + when "=" + ".equal" + end + end + end + end + + module ClassMethods + def priority(name, *tests) + unless Checker.have_priority?(name) + raise ArgumentError, "unknown priority: #{name}" + end + attribute(:priority, name, {:keep => true}, *tests) + end + end + + def priority_setup + return unless Priority.enabled? + Checker.new(self).setup + end + + def priority_teardown + return unless Priority.enabled? + Checker.new(self).teardown + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/runner/console.rb b/testdata/vendor/ruby/test/unit/runner/console.rb new file mode 100644 index 000000000..461a95ae9 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/runner/console.rb @@ -0,0 +1,59 @@ +module Test + module Unit + AutoRunner.register_runner(:console) do |auto_runner| + require 'test/unit/ui/console/testrunner' + Test::Unit::UI::Console::TestRunner + end + + AutoRunner.setup_option do |auto_runner, opts| + require 'test/unit/ui/console/outputlevel' + + output_levels = [ + ["silent", UI::Console::OutputLevel::SILENT], + ["progress", UI::Console::OutputLevel::PROGRESS_ONLY], + ["important-only", UI::Console::OutputLevel::IMPORTANT_FAULTS_ONLY], + ["normal", UI::Console::OutputLevel::NORMAL], + ["verbose", UI::Console::OutputLevel::VERBOSE], + ] + opts.on('-v', '--verbose=[LEVEL]', output_levels, + "Set the output level (default is verbose).", + "(#{auto_runner.keyword_display(output_levels)})") do |level| + level ||= output_levels.assoc("verbose")[1] + auto_runner.runner_options[:output_level] = level + end + + use_color_options = [ + [:auto, :auto], + ["-", false], + ["no", false], + ["false", false], + ["+", true], + ["yes", true], + ["true", true], + ] + opts.on("--[no-]use-color=[auto]", use_color_options, + "Uses color output", + "(default is auto)") do |use_color| + case use_color + when nil + use_color = true + when :auto + use_color = nil + end + auto_runner.runner_options[:use_color] = use_color + end + + opts.on("--progress-row-max=MAX", Integer, + "Uses MAX as max terminal width for progress mark", + "(default is auto)") do |max| + auto_runner.runner_options[:progress_row_max] = max + end + + opts.on("--no-show-detail-immediately", + "Shows not passed test details immediately.", + "(default is yes)") do |boolean| + auto_runner.runner_options[:show_detail_immediately] = boolean + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/runner/emacs.rb b/testdata/vendor/ruby/test/unit/runner/emacs.rb new file mode 100644 index 000000000..c2546576d --- /dev/null +++ b/testdata/vendor/ruby/test/unit/runner/emacs.rb @@ -0,0 +1,8 @@ +module Test + module Unit + AutoRunner.register_runner(:emacs) do |auto_runner| + require 'test/unit/ui/emacs/testrunner' + Test::Unit::UI::Emacs::TestRunner + end + end +end diff --git a/testdata/vendor/ruby/test/unit/runner/xml.rb b/testdata/vendor/ruby/test/unit/runner/xml.rb new file mode 100644 index 000000000..aea03760c --- /dev/null +++ b/testdata/vendor/ruby/test/unit/runner/xml.rb @@ -0,0 +1,15 @@ +module Test + module Unit + AutoRunner.register_runner(:xml) do |auto_runner| + require 'test/unit/ui/xml/testrunner' + Test::Unit::UI::XML::TestRunner + end + + AutoRunner.setup_option do |auto_runner, opts| + opts.on("--output-file-descriptor=FD", Integer, + "Outputs to file descriptor FD") do |fd| + auto_runner.runner_options[:output_file_descriptor] = fd + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/test-suite-creator.rb b/testdata/vendor/ruby/test/unit/test-suite-creator.rb new file mode 100644 index 000000000..b7af9cff6 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/test-suite-creator.rb @@ -0,0 +1,89 @@ +#-- +# +# Author:: Kouhei Sutou +# Copyright:: +# * Copyright (c) 2011 Kouhei Sutou +# License:: Ruby license. + +module Test + module Unit + class TestSuiteCreator # :nodoc: + class << self + def test_method?(test_case, method_name) + /\Atest./ =~ method_name.to_s or + test_case.find_attribute(method_name, :test) + end + end + + def initialize(test_case) + @test_case = test_case + end + + def create + suite = TestSuite.new(@test_case.name, @test_case) + collect_test_names.each do |test_name| + data_sets = @test_case.find_attribute(test_name, :data, + :recursive => false) + if data_sets + data_sets.each do |data_set| + data_set = data_set.call if data_set.respond_to?(:call) + data_set.each do |label, data| + append_test(suite, test_name) do |test| + test.assign_test_data(label, data) + end + end + end + else + append_test(suite, test_name) + end + end + append_test(suite, "default_test") if suite.empty? + suite + end + + private + def append_test(suite, test_name) + test = @test_case.new(test_name) + yield(test) if block_given? + suite << test if test.valid? + end + + def collect_test_names + methods = @test_case.public_instance_methods(true) + super_test_case = @test_case.superclass + methods -= super_test_case.public_instance_methods(true) + methods |= @test_case.public_instance_methods(false) + method_names = methods.collect(&:to_s) + test_names = method_names.find_all do |method_name| + self.class.test_method?(@test_case, method_name) + end + __send__("sort_test_names_in_#{@test_case.test_order}_order", test_names) + end + + def sort_test_names_in_alphabetic_order(test_names) + test_names.sort + end + + def sort_test_names_in_random_order(test_names) + test_names.sort_by {rand(test_names.size)} + end + + def sort_test_names_in_defined_order(test_names) + added_method_names = @test_case.added_method_names + test_names.sort do |test1, test2| + test1_defined_order = added_method_names.index(test1) + test2_defined_order = added_method_names.index(test2) + if test1_defined_order and test2_defined_order + test1_defined_order <=> test2_defined_order + elsif test1_defined_order + 1 + elsif test2_defined_order + -1 + else + test1 <=> test2 + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/testcase.rb b/testdata/vendor/ruby/test/unit/testcase.rb new file mode 100644 index 000000000..53ec02301 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/testcase.rb @@ -0,0 +1,812 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: +# * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# * Copyright (c) 2008-2012 Kouhei Sutou +# License:: Ruby license. + +require 'test/unit/attribute' +require 'test/unit/fixture' +require 'test/unit/exception-handler' +require 'test/unit/assertions' +require 'test/unit/failure' +require 'test/unit/error' +require 'test/unit/pending' +require 'test/unit/omission' +require 'test/unit/notification' +require 'test/unit/priority' +require 'test/unit/data' +require 'test/unit/testsuite' +require 'test/unit/test-suite-creator' +require 'test/unit/assertion-failed-error' +require 'test/unit/auto-runner-loader' +require 'test/unit/util/backtracefilter' +require 'test/unit/util/output' +require 'test/unit/util/method-owner-finder' + +module Test + module Unit + + # Ties everything together. If you subclass and add your own + # test methods, it takes care of making them into tests and + # wrapping those tests into a suite. It also does the + # nitty-gritty of actually running an individual test and + # collecting its results into a Test::Unit::TestResult object. + # + # You can run two hooks before/after a TestCase run. + # + # Example: + # class TestMyClass < Test::Unit::TestCase + # class << self + # def startup + # ... + # end + # + # def shutdown + # ... + # end + # end + # + # def setup + # ... + # end + # + # def cleanup + # ... + # end + # + # def teardown + # ... + # end + # + # def test_my_method1 + # ... + # end + # + # def test_my_method2 + # ... + # end + # end + # + # Here is a call order: + # * startup + # * setup + # * test_my_method1 + # * cleanup + # * teardown + # * setup + # * test_my_method2 + # * cleanup + # * teardown + # * shutdown + class TestCase + include Attribute + include Fixture + include ExceptionHandler + include ErrorHandler + include FailureHandler + include TestCasePendingSupport + include TestCaseOmissionSupport + include TestCaseNotificationSupport + include Priority + include Data + include Assertions + include Util::BacktraceFilter + include Util::Output + + STARTED = name + "::STARTED" # :nodoc: + FINISHED = name + "::FINISHED" # :nodoc: + STARTED_OBJECT = name + "::STARTED::OBJECT" # :nodoc: + FINISHED_OBJECT = name + "::FINISHED::OBJECT" # :nodoc: + + DESCENDANTS = [] # :nodoc: + AVAILABLE_ORDERS = [:alphabetic, :random, :defined] # :nodoc: + + class << self + def inherited(sub_class) # :nodoc: + DESCENDANTS << sub_class + super + end + + @@added_method_names = {} + def method_added(name) # :nodoc: + super + added_method_names = (@@added_method_names[self] ||= {}) + stringified_name = name.to_s + if added_method_names.key?(stringified_name) + attribute(:redefined, {:backtrace => caller}, {}, stringified_name) + end + source_location = find_attribute(stringified_name, :source_location) + if source_location + path, line = source_location + elsif respond_to?(:caller_locations, true) + location = caller_locations(1, 1)[0] + path = location.absolute_path || location.path + line = location.lineno + else + # TODO: Remove me when Ruby 1.9 support is dropped + path, line, = caller[0].split(/:(\d+)/, 2) + line = line.to_i if line + end + method_locations << { + :method_name => stringified_name, + :path => File.expand_path(path), + :line => line, + } + added_method_names[stringified_name] = true + AutoRunnerLoader.check(self, stringified_name) + end + + def added_method_names # :nodoc: + (@@added_method_names[self] ||= {}).keys + end + + # Rolls up all of the test* methods in the fixture into + # one suite, creating a new instance of the fixture for + # each method. + def suite + suite_creator = TestSuiteCreator.new(self) + suite_creator.create + end + + # Called before every test case runs. Can be used + # to set up fixture information used in test case + # scope. + # + # Here is an example test case: + # class TestMyClass < Test::Unit::TestCase + # class << self + # def startup + # ... + # end + # end + # + # def setup + # ... + # end + # + # def test_my_class1 + # ... + # end + # + # def test_my_class2 + # ... + # end + # end + # + # Here is a call order: + # * startup + # * setup + # * test_my_class1 (or test_my_class2) + # * setup + # * test_my_class2 (or test_my_class1) + # + # Note that you should not assume test order. Tests + # should be worked in any order. + def startup + end + + # Called after every test case runs. Can be used to tear + # down fixture information used in test case scope. + # + # Here is an example test case: + # class TestMyClass < Test::Unit::TestCase + # class << self + # def shutdown + # ... + # end + # end + # + # def teardown + # ... + # end + # + # def test_my_class1 + # ... + # end + # + # def test_my_class2 + # ... + # end + # end + # + # Here is a call order: + # * test_my_class1 (or test_my_class2) + # * teardown + # * test_my_class2 (or test_my_class1) + # * teardown + # * shutdown + # + # Note that you should not assume test order. Tests + # should be worked in any order. + def shutdown + end + + @@test_orders = {} + + # Returns the current test order. This returns + # +:alphabetic+ by default. + def test_order + @@test_orders[self] || AVAILABLE_ORDERS.first + end + + # Sets the current test order. + # + # Here are the available _order_: + # [:alphabetic] + # Default. Tests are sorted in alphabetic order. + # [:random] + # Tests are sorted in random order. + # [:defined] + # Tests are sorted in defined order. + def test_order=(order) + @@test_orders[self] = order + end + + # Defines a test in declarative syntax or marks + # following method as a test method. + # + # In declarative syntax usage, the following two + # test definitions are the almost same: + # + # description "register user" + # def test_register_user + # ... + # end + # + # test "register user" do + # ... + # end + # + # In test method mark usage, the "my_test_method" is + # treated as a test method: + # + # test + # def my_test_method + # assert_equal("call me", ...) + # end + def test(*test_description_or_targets, &block) + if block_given? + test_description = test_description_or_targets.first + if test_description.nil? + raise ArgumentError, "test description is missing" + end + n_arguments = test_description_or_targets.size + if n_arguments > 1 + message = "wrong number of arguments (#{n_arguments} for 1)" + raise ArgumentError, message + end + method_name = "test: #{test_description}" + description(test_description, method_name) + attribute(:test, true, {}, method_name) + if block.respond_to?(:source_location) + attribute(:source_location, block.source_location, {}, method_name) + end + define_method(method_name, &block) + else + targets = test_description_or_targets + attribute(:test, true, {}, *targets) + targets.each do |target| + AutoRunnerLoader.check(self, target) + end + end + end + + # Describes a test. + # + # The following example associates "register a + # normal user" description with "test_register" + # test. + # + # description "register a normal user" + # def test_register + # ... + # end + def description(value, target=nil) + targets = [target].compact + attribute(:description, value, {}, *targets) + end + + # Defines a sub test case. + # + # This is a syntax sugar. The both of the following codes are + # the same in meaning: + # + # Standard: + # class TestParent < Test::UnitTestCase + # class TestChild < self + # def test_in_child + # end + # end + # end + # + # Syntax sugar: + # class TestParent < Test::UnitTestCase + # sub_test_case("TestChild") do + # def test_in_child + # end + # end + # end + # + # The difference of them are the following: + # + # * Test case created by {sub_test_case} is an anonymous class. + # So you can't refer the test case by name. + # * The class name of class style must follow + # constant naming rule in Ruby. But the name of test case + # created by {sub_test_case} doesn't need to follow the rule. + # For example, you can use a space in name such as "child test". + # + # @param name [String] The name of newly created sub test case. + # @yield + # The block is evaluated under the newly created sub test + # case class context. + # @return [Test::Unit::TestCase] Created sub test case class. + def sub_test_case(name, &block) + parent_test_case = self + sub_test_case = Class.new(self) do + singleton_class = class << self; self; end + singleton_class.__send__(:define_method, :name) do + [parent_test_case.name, name].compact.join("::") + end + end + sub_test_case.class_eval(&block) + sub_test_case + end + + # Checks whether a test that is matched the query is + # defined. + # + # @option query [String] :path (nil) + # the path where a test is defined in. + # @option query [Numeric] :line (nil) + # the line number where a test is defined at. + # @option query [String] :method_name (nil) + # the method name for a test. + def test_defined?(query) + query_path = query[:path] + query_line = query[:line] + query_method_name = query[:method_name] + + available_locations = target_method_locations(query_path) + if query_line + available_locations = available_locations.sort_by do |location| + -location[:line] + end + available_location = available_locations.find do |location| + query_line >= location[:line] + end + return false if available_location.nil? + return false if available_location[:test_case] != self + available_locations = [available_location] + end + if query_method_name + available_location = available_locations.find do |location| + query_method_name == location[:method_name] + end + return false if available_location.nil? + available_locations = [available_location] + end + + not available_locations.empty? + end + + private + # @private + @@method_locations = {} + # @private + def method_locations + @@method_locations[self] ||= [] + end + + # @private + def target_method_locations(path) + if path.nil? + self_location = method_locations.first + path = self_location[:path] if self_location + end + return [] if path.nil? + + target_locations = [] + @@method_locations.each do |test_case, locations| + locations.each do |location| + absolete_path = File.expand_path(path) + location_path = location[:path] + location_basename = File.basename(location_path) + if location_path == absolete_path or location_basename == path + target_locations << location.merge(:test_case => test_case) + end + end + end + target_locations + end + end + + attr_reader :method_name + + # Creates a new instance of the fixture for running the + # test represented by test_method_name. + def initialize(test_method_name) + @method_name = test_method_name + @internal_data = InternalData.new + end + + # Assigns test data to the test. It is used in internal. + def assign_test_data(label, data) # :nodoc: + @internal_data.assign_test_data(label, data) + end + + # Returns the test is valid test. It is used in internal. + def valid? # :nodoc: + return false unless respond_to?(@method_name) + test_method = method(@method_name) + if @internal_data.have_test_data? + return false unless test_method.arity == 1 + else + return false unless test_method.arity <= 0 + end + owner = Util::MethodOwnerFinder.find(self, @method_name) + if owner.class != Module and self.class != owner + return false + end + true + end + + # Runs the individual test method represented by this + # instance of the fixture, collecting statistics, failures + # and errors in result. + def run(result) + begin + @_result = result + @internal_data.test_started + yield(STARTED, name) + yield(STARTED_OBJECT, self) + processed_exception_in_setup = false + begin + tag = eval(":tag_#{self.object_id}") + catch(tag) do + run_setup do + begin + run_test + run_cleanup + add_pass + rescue Exception + @internal_data.interrupted + unless handle_exception($!) + processed_exception_in_setup = true + raise + end + throw(tag) + end + end + end + rescue Exception + if processed_exception_in_setup + raise + else + @internal_data.interrupted + raise unless handle_exception($!) + end + ensure + begin + run_teardown + rescue Exception + raise unless handle_exception($!) + end + end + @internal_data.test_finished + result.add_run + yield(FINISHED, name) + yield(FINISHED_OBJECT, self) + ensure + # @_result = nil # For test-spec's after_all :< + end + end + + # Called before every test method runs. Can be used + # to set up fixture information. + # + # You can add additional setup tasks by the following + # code: + # class TestMyClass < Test::Unit::TestCase + # def setup + # ... + # end + # + # setup + # def my_setup1 + # ... + # end + # + # setup do + # ... # setup callback1 + # end + # + # setup + # def my_setup2 + # ... + # end + # + # setup do + # ... # setup callback2 + # end + # + # def test_my_class + # ... + # end + # end + # + # Here is a call order: + # * setup + # * my_setup1 + # * setup callback1 + # * my_setup2 + # * setup callback2 + # * test_my_class + def setup + end + + # Called after every test method runs but the test + # method isn't marked as 'passed'. Can be used to + # clean up and/or verify tested condition. + # e.g. Can be used to verify mock. + # + # You can add additional cleanup tasks by the following + # code: + # class TestMyClass < Test::Unit::TestCase + # def cleanup + # ... + # end + # + # cleanup + # def my_cleanup1 + # ... + # end + # + # cleanup do + # ... # cleanup callback1 + # end + # + # cleanup + # def my_cleanup2 + # ... + # end + # + # cleanup do + # ... # cleanup callback2 + # end + # + # def test_my_class + # ... + # end + # end + # + # Here is a call order: + # * test_my_class + # * cleanup callback2 + # * my_cleanup2 + # * cleanup callback1 + # * my_cleanup1 + # * cleanup + def cleanup + end + + # Called after every test method runs. Can be used to tear + # down fixture information. + # + # You can add additional teardown tasks by the following + # code: + # class TestMyClass < Test::Unit::TestCase + # def teardown + # ... + # end + # + # teardown + # def my_teardown1 + # ... + # end + # + # teardown do + # ... # teardown callback1 + # end + # + # teardown + # def my_teardown2 + # ... + # end + # + # teardown do + # ... # teardown callback2 + # end + # + # def test_my_class + # ... + # end + # end + # + # Here is a call order: + # * test_my_class + # * teardown callback2 + # * my_teardown2 + # * teardown callback1 + # * my_teardown1 + # * teardown + def teardown + end + + def default_test + flunk("No tests were specified") + end + + def size + 1 + end + + # Returns a label of test data for the test. If the + # test isn't associated with any test data, it returns + # +nil+. + def data_label + @internal_data.test_data_label + end + + # Returns a human-readable name for the specific test that + # this instance of TestCase represents. + def name + if @internal_data.have_test_data? + "#{@method_name}[#{data_label}](#{self.class.name})" + else + "#{@method_name}(#{self.class.name})" + end + end + + # Returns a description for the test. A description + # will be associated by Test::Unit::TestCase.test or + # Test::Unit::TestCase.description. + # + # Returns a name for the test for no description test. + def description + self[:description] || name + end + + # Overridden to return #name. + def to_s + name + end + + # It's handy to be able to compare TestCase instances. + def ==(other) + return false unless other.kind_of?(self.class) + return false unless @method_name == other.method_name + return false unless data_label == other.data_label + self.class == other.class + end + + # Returns a Time at the test was started. + def start_time + @internal_data.start_time + end + + # Returns elapsed time for the test was ran. + def elapsed_time + @internal_data.elapsed_time + end + + # Returns whether the test is interrupted. + def interrupted? + @internal_data.interrupted? + end + + # Returns whether this individual test passed or + # not. Primarily for use in teardown so that artifacts + # can be left behind if the test fails. + def passed? + @internal_data.passed? + end + + # Notify that a problem is occurred in the test. It means that + # the test is a failed test. If any failed tests exist in test + # suites, the test process exits with failure exit status. + # + # This is a public API for developers who extend test-unit. + # + # @return [void] + def problem_occurred + @internal_data.problem_occurred + end + + # Notify that the test is passed. Normally, it is not needed + # because #run calls it automatically. If you want to override + # #run, it is not a good idea. Please contact test-unit + # developers. We will help you without your custom #run. For + # example, we may add a new hook in #run. + # + # This is a public API for developers who extend test-unit. + # + # @return [void] + def add_pass + current_result.add_pass + end + + private + def current_result + @_result + end + + def run_test + redefined_info = self[:redefined] + if redefined_info + notify("#{self.class}\##{@method_name} was redefined", + :backtrace => redefined_info[:backtrace]) + end + if @internal_data.have_test_data? + __send__(@method_name, @internal_data.test_data) + else + __send__(@method_name) + end + end + + def handle_exception(exception) + self.class.exception_handlers.each do |handler| + if handler.respond_to?(:call) + handled = handler.call(self, exception) + else + handled = __send__(handler, exception) + end + return true if handled + end + false + end + + def add_assertion + current_result.add_assertion + end + + class InternalData + attr_reader :start_time, :elapsed_time + attr_reader :test_data_label, :test_data + def initialize + @start_time = nil + @elapsed_time = nil + @passed = true + @interrupted = false + @test_data_label = nil + @test_data = nil + end + + def passed? + @passed + end + + def interrupted? + @interrupted + end + + def assign_test_data(label, data) + @test_data_label = label + @test_data = data + end + + def have_test_data? + not @test_data_label.nil? + end + + def test_started + @start_time = Time.now + end + + def test_finished + @elapsed_time = Time.now - @start_time + end + + def problem_occurred + @passed = false + end + + def interrupted + @interrupted = true + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/testresult.rb b/testdata/vendor/ruby/test/unit/testresult.rb new file mode 100644 index 000000000..317752878 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/testresult.rb @@ -0,0 +1,125 @@ +#-- +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit/util/observable' +require 'test/unit/failure' +require 'test/unit/error' +require 'test/unit/omission' +require 'test/unit/pending' +require 'test/unit/notification' + +module Test + module Unit + module NullResultContainerInitializer + private + def initialize_containers + end + end + + # Collects Test::Unit::Failure and Test::Unit::Error so that + # they can be displayed to the user. To this end, observers + # can be added to it, allowing the dynamic updating of, say, a + # UI. + class TestResult + include Util::Observable + include NullResultContainerInitializer + include TestResultFailureSupport + include TestResultErrorSupport + include TestResultPendingSupport + include TestResultOmissionSupport + include TestResultNotificationSupport + + FINISHED = name + "::FINISHED" + CHANGED = name + "::CHANGED" + PASS_ASSERTION = name + "::PASS_ASSERTION" + FAULT = name + "::FAULT" + + attr_reader :run_count, :pass_count, :assertion_count, :faults + + # Constructs a new, empty TestResult. + def initialize + @run_count, @pass_count, @assertion_count = 0, 0, 0 + @summary_generators = [] + @problem_checkers = [] + @faults = [] + initialize_containers + end + + # Records a test run. + def add_run + @run_count += 1 + notify_listeners(FINISHED, self) + notify_changed + end + + def add_pass + @pass_count += 1 + end + + # Records an individual assertion. + def add_assertion + @assertion_count += 1 + notify_listeners(PASS_ASSERTION, self) + notify_changed + end + + # Returns a string contain the recorded runs, assertions, + # failures and errors in this TestResult. + def summary + ["#{run_count} tests", + "#{assertion_count} assertions", + *@summary_generators.collect {|generator| __send__(generator)}].join(", ") + end + + # Returnes a string that shows result status. + def status + if passed? + if pending_count > 0 + "pending" + elsif omission_count > 0 + "omission" + elsif notification_count > 0 + "notification" + else + "pass" + end + elsif error_count > 0 + "error" + elsif failure_count > 0 + "failure" + end + end + + def to_s + summary + end + + # Returns whether or not this TestResult represents + # successful completion. + def passed? + @problem_checkers.all? {|checker| not __send__(checker)} + end + + def pass_percentage + n_tests = @run_count - omission_count + if n_tests.zero? + 0 + else + 100.0 * (@pass_count / n_tests.to_f) + end + end + + private + def notify_changed + notify_listeners(CHANGED, self) + end + + def notify_fault(fault) + @faults << fault + notify_listeners(FAULT, fault) + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/testsuite.rb b/testdata/vendor/ruby/test/unit/testsuite.rb new file mode 100644 index 000000000..495fc341c --- /dev/null +++ b/testdata/vendor/ruby/test/unit/testsuite.rb @@ -0,0 +1,175 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# Copyright:: Copyright (c) 2008-2011 Kouhei Sutou. All rights reserved. +# License:: Ruby license. + +require 'test/unit/error' + +module Test + module Unit + + # A collection of tests which can be #run. + # + # Note: It is easy to confuse a TestSuite instance with + # something that has a static suite method; I know because _I_ + # have trouble keeping them straight. Think of something that + # has a suite method as simply providing a way to get a + # meaningful TestSuite instance. + class TestSuite + attr_reader :name, :tests, :test_case, :start_time, :elapsed_time + + # Test suite that has higher priority is ran prior to + # test suites that have lower priority. + attr_accessor :priority + + STARTED = name + "::STARTED" + STARTED_OBJECT = name + "::STARTED::OBJECT" + FINISHED = name + "::FINISHED" + FINISHED_OBJECT = name + "::FINISHED::OBJECT" + + # Creates a new TestSuite with the given name. + def initialize(name="Unnamed TestSuite", test_case=nil) + @name = name + @tests = [] + @test_case = test_case + @n_tests = 0 + @priority = 0 + @start_time = nil + @elapsed_time = nil + @passed = true + end + + # Runs the tests and/or suites contained in this + # TestSuite. + def run(result, &progress_block) + @start_time = Time.now + yield(STARTED, name) + yield(STARTED_OBJECT, self) + run_startup(result) + while test = @tests.shift + @n_tests += test.size + run_test(test, result, &progress_block) + @passed = false unless test.passed? + end + ensure + begin + run_shutdown(result) + ensure + @elapsed_time = Time.now - @start_time + yield(FINISHED, name) + yield(FINISHED_OBJECT, self) + end + end + + # Adds the test to the suite. + def <<(test) + @tests << test + self + end + + def delete(test) + @tests.delete(test) + end + + def delete_tests(tests) + @tests -= tests + end + + # Retuns the rolled up number of tests in this suite; + # i.e. if the suite contains other suites, it counts the + # tests within those suites, not the suites themselves. + def size + total_size = @n_tests + @tests.each { |test| total_size += test.size } + total_size + end + + def empty? + size.zero? + end + + # Overridden to return the name given the suite at + # creation. + def to_s + @name + end + + # It's handy to be able to compare TestSuite instances. + def ==(other) + return false unless(other.kind_of?(self.class)) + return false unless(@name == other.name) + @tests == other.tests + end + + def passed? + @passed + end + + private + def run_startup(result) + return if @test_case.nil? or !@test_case.respond_to?(:startup) + begin + @test_case.startup + rescue Exception + raise unless handle_exception($!, result) + end + end + + def run_test(test, result) + finished_is_yielded = false + finished_object_is_yielded = false + previous_event_name = nil + test.run(result) do |event_name, *args| + case previous_event_name + when Test::Unit::TestCase::STARTED + if event_name != Test::Unit::TestCase::STARTED_OBJECT + yield(Test::Unit::TestCase::STARTED_OBJECT, test) + end + when Test::Unit::TestCase::FINISHED + if event_name != Test::Unit::TestCase::FINISHED_OBJECT + yield(Test::Unit::TestCase::FINISHED_OBJECT, test) + end + finished_object_is_yielded = true + end + + case event_name + when Test::Unit::TestCase::STARTED + finished_is_yielded = false + finished_object_is_yielded = false + when Test::Unit::TestCase::FINISHED + finished_is_yielded = true + end + + previous_event_name = event_name + yield(event_name, *args) + end + + if finished_is_yielded and not finished_object_is_yielded + yield(Test::Unit::TestCase::FINISHED_OBJECT, test) + end + end + + def run_shutdown(result) + return if @test_case.nil? or !@test_case.respond_to?(:shutdown) + begin + @test_case.shutdown + rescue Exception + raise unless handle_exception($!, result) + end + end + + def handle_exception(exception, result) + case exception + when *ErrorHandler::PASS_THROUGH_EXCEPTIONS + false + else + result.add_error(Error.new(@test_case.name, exception)) + @passed = false + true + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/console/outputlevel.rb b/testdata/vendor/ruby/test/unit/ui/console/outputlevel.rb new file mode 100644 index 000000000..de3ccfd83 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/console/outputlevel.rb @@ -0,0 +1,15 @@ +module Test + module Unit + module UI + module Console + module OutputLevel + SILENT = 0 + PROGRESS_ONLY = 1 + IMPORTANT_FAULTS_ONLY = 2 + NORMAL = 3 + VERBOSE = 4 + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/console/testrunner.rb b/testdata/vendor/ruby/test/unit/ui/console/testrunner.rb new file mode 100644 index 000000000..7b2450378 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/console/testrunner.rb @@ -0,0 +1,693 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: +# * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved. +# * Copyright (c) 2008-2013 Kouhei Sutou +# License:: Ruby license. + +begin + require 'io/console' +rescue LoadError +end + +require 'test/unit/color-scheme' +require 'test/unit/code-snippet-fetcher' +require 'test/unit/fault-location-detector' +require 'test/unit/diff' +require 'test/unit/ui/testrunner' +require 'test/unit/ui/testrunnermediator' +require 'test/unit/ui/console/outputlevel' + +module Test + module Unit + module UI + module Console + + # Runs a Test::Unit::TestSuite on the console. + class TestRunner < UI::TestRunner + include OutputLevel + + # Creates a new TestRunner for running the passed + # suite. If quiet_mode is true, the output while + # running is limited to progress dots, errors and + # failures, and the final result. io specifies + # where runner output should go to; defaults to + # $stdout. + def initialize(suite, options={}) + super + @output_level = @options[:output_level] || NORMAL + @output = @options[:output] || $stdout + @use_color = @options[:use_color] + @use_color = guess_color_availability if @use_color.nil? + @color_scheme = @options[:color_scheme] || ColorScheme.default + @reset_color = Color.new("reset") + @progress_row = 0 + @progress_row_max = @options[:progress_row_max] + @progress_row_max ||= guess_progress_row_max + @show_detail_immediately = @options[:show_detail_immediately] + @show_detail_immediately = true if @show_detail_immediately.nil? + @already_outputted = false + @indent = 0 + @top_level = true + @current_output_level = NORMAL + @faults = [] + @code_snippet_fetcher = CodeSnippetFetcher.new + @test_suites = [] + end + + private + def change_output_level(level) + old_output_level = @current_output_level + @current_output_level = level + yield + @current_output_level = old_output_level + end + + def setup_mediator + super + output_setup_end + end + + def output_setup_end + suite_name = @suite.to_s + suite_name = @suite.name if @suite.kind_of?(Module) + output("Loaded suite #{suite_name}") + end + + def attach_to_mediator + @mediator.add_listener(TestResult::FAULT, + &method(:add_fault)) + @mediator.add_listener(TestRunnerMediator::STARTED, + &method(:started)) + @mediator.add_listener(TestRunnerMediator::FINISHED, + &method(:finished)) + @mediator.add_listener(TestCase::STARTED_OBJECT, + &method(:test_started)) + @mediator.add_listener(TestCase::FINISHED_OBJECT, + &method(:test_finished)) + @mediator.add_listener(TestSuite::STARTED_OBJECT, + &method(:test_suite_started)) + @mediator.add_listener(TestSuite::FINISHED_OBJECT, + &method(:test_suite_finished)) + end + + def add_fault(fault) + @faults << fault + output_progress(fault.single_character_display, + fault_marker_color(fault)) + output_progress_in_detail(fault) if @show_detail_immediately + @already_outputted = true if fault.critical? + end + + def started(result) + @result = result + output_started + end + + def output_started + output("Started") + end + + def finished(elapsed_time) + nl if output?(NORMAL) and !output?(VERBOSE) + output_faults unless @show_detail_immediately + nl(PROGRESS_ONLY) + change_output_level(IMPORTANT_FAULTS_ONLY) do + output_statistics(elapsed_time) + end + end + + def output_faults + categorized_faults = categorize_faults + change_output_level(IMPORTANT_FAULTS_ONLY) do + output_faults_in_detail(categorized_faults[:need_detail_faults]) + end + output_faults_in_short("Omissions", Omission, + categorized_faults[:omissions]) + output_faults_in_short("Notifications", Notification, + categorized_faults[:notifications]) + end + + def max_digit(max_number) + (Math.log10(max_number) + 1).truncate + end + + def output_faults_in_detail(faults) + return if faults.nil? + digit = max_digit(faults.size) + faults.each_with_index do |fault, index| + nl + output_single("%#{digit}d) " % (index + 1)) + output_fault_in_detail(fault) + end + end + + def output_faults_in_short(label, fault_class, faults) + return if faults.nil? + digit = max_digit(faults.size) + nl + output_single(label, fault_class_color(fault_class)) + output(":") + faults.each_with_index do |fault, index| + output_single("%#{digit}d) " % (index + 1)) + output_fault_in_short(fault) + end + end + + def categorize_faults + faults = {} + @faults.each do |fault| + category = categorize_fault(fault) + faults[category] ||= [] + faults[category] << fault + end + faults + end + + def categorize_fault(fault) + case fault + when Omission + :omissions + when Notification + :notifications + else + :need_detail_faults + end + end + + def output_fault_in_detail(fault) + if fault.is_a?(Failure) and + fault.inspected_expected and fault.inspected_actual + output_single("#{fault.label}: ") + output(fault.test_name, fault_color(fault)) + output_fault_backtrace(fault) + output_failure_message(fault) + else + if fault.is_a?(Error) + output_single("#{fault.label}: ") + output_single(fault.test_name, fault_color(fault)) + output_fault_message(fault) + else + output_single(fault.label, fault_color(fault)) + output_fault_message(fault) + output(fault.test_name) + end + output_fault_backtrace(fault) + end + end + + def output_fault_message(fault) + message = fault.message + return if message.nil? + + if message.include?("\n") + output(":") + message.each_line do |line| + output(" #{line.chomp}") + end + else + output(": #{message}") + end + end + + def output_fault_backtrace(fault) + snippet_is_shown = false + detector = FaultLocationDetector.new(fault, @code_snippet_fetcher) + backtrace = fault.location + # workaround for test-spec. :< + # see also GitHub:#22 + backtrace ||= [] + backtrace.each_with_index do |entry, i| + output(entry) + next if snippet_is_shown + next unless detector.target?(entry) + file, line_number, = detector.split_backtrace_entry(entry) + snippet_is_shown = output_code_snippet(file, line_number, + fault_color(fault)) + end + end + + def output_code_snippet(file, line_number, target_line_color=nil) + lines = @code_snippet_fetcher.fetch(file, line_number) + return false if lines.empty? + + max_n = lines.collect {|n, line, attributes| n}.max + digits = (Math.log10(max_n) + 1).truncate + lines.each do |n, line, attributes| + if attributes[:target_line?] + line_color = target_line_color + current_line_mark = "=>" + else + line_color = nil + current_line_mark = "" + end + output(" %2s %*d: %s" % [current_line_mark, digits, n, line], + line_color) + end + true + end + + def output_failure_message(failure) + if failure.expected.respond_to?(:encoding) and + failure.actual.respond_to?(:encoding) and + failure.expected.encoding != failure.actual.encoding + need_encoding = true + else + need_encoding = false + end + output(failure.user_message) if failure.user_message + output_single("<") + output_single(failure.inspected_expected, color("pass")) + output_single(">") + if need_encoding + output_single("(") + output_single(failure.expected.encoding.name, color("pass")) + output_single(")") + end + output(" expected but was") + output_single("<") + output_single(failure.inspected_actual, color("failure")) + output_single(">") + if need_encoding + output_single("(") + output_single(failure.actual.encoding.name, color("failure")) + output_single(")") + end + output("") + from, to = prepare_for_diff(failure.expected, failure.actual) + if from and to + if need_encoding + unless from.valid_encoding? + from = from.dup.force_encoding("ASCII-8BIT") + end + unless to.valid_encoding? + to = to.dup.force_encoding("ASCII-8BIT") + end + end + from_lines = from.split(/\r?\n/) + to_lines = to.split(/\r?\n/) + if need_encoding + from_lines << "" + to_lines << "" + from_lines << "Encoding: #{failure.expected.encoding.name}" + to_lines << "Encoding: #{failure.actual.encoding.name}" + end + differ = ColorizedReadableDiffer.new(from_lines, to_lines, self) + if differ.need_diff? + output("") + output("diff:") + differ.diff + end + end + end + + def output_fault_in_short(fault) + output_single(fault.message, fault_color(fault)) + output(" [#{fault.test_name}]") + output(fault.location.first) + end + + def format_fault(fault) + fault.long_display + end + + def output_statistics(elapsed_time) + output("Finished in #{elapsed_time} seconds.") + output_summary_marker + output(@result) + output("%g%% passed" % @result.pass_percentage) + unless elapsed_time.zero? + output_summary_marker + test_throughput = @result.run_count / elapsed_time + assertion_throughput = @result.assertion_count / elapsed_time + throughput = [ + "%.2f tests/s" % test_throughput, + "%.2f assertions/s" % assertion_throughput, + ] + output(throughput.join(", ")) + end + end + + def output_summary_marker + term_width = guess_term_width + if term_width.zero? + marker_width = 6 + else + marker_width = term_width + end + output("-" * marker_width, summary_marker_color) + end + + def test_started(test) + return unless output?(VERBOSE) + + name = test.name.sub(/\(.+?\)\z/, '') + right_space = 8 * 2 + left_space = @progress_row_max - right_space + left_space = left_space - indent.size - name.size + tab_stop = "\t" * ([left_space - 1, 0].max / 8) + output_single("#{indent}#{name}:#{tab_stop}", nil, VERBOSE) + @test_start = Time.now + end + + def test_finished(test) + unless @already_outputted + output_progress(".", color("pass-marker")) + end + @already_outputted = false + + return unless output?(VERBOSE) + + output(": (%f)" % (Time.now - @test_start), nil, VERBOSE) + end + + def suite_name(prefix, suite) + name = suite.name + if name.nil? + "(anonymous)" + else + name.sub(/\A#{Regexp.escape(prefix)}/, "") + end + end + + def test_suite_started(suite) + last_test_suite = @test_suites.last + @test_suites << suite + if @top_level + @top_level = false + return + end + + output_single(indent, nil, VERBOSE) + if suite.test_case.nil? + _color = color("suite") + else + _color = color("case") + end + prefix = "#{last_test_suite.name}::" + output_single(suite_name(prefix, suite), _color, VERBOSE) + output(": ", nil, VERBOSE) + @indent += 2 + end + + def test_suite_finished(suite) + @indent -= 2 + @test_suites.pop + end + + def indent + if output?(VERBOSE) + " " * @indent + else + "" + end + end + + def nl(level=nil) + output("", nil, level) + end + + def output(something, color=nil, level=nil) + return unless output?(level) + output_single(something, color, level) + @output.puts + end + + def output_single(something, color=nil, level=nil) + return false unless output?(level) + if @use_color and color + something = "%s%s%s" % [color.escape_sequence, + something, + @reset_color.escape_sequence] + end + @output.write(something) + @output.flush + true + end + + def output_progress(mark, color=nil) + if output_single(mark, color, PROGRESS_ONLY) + return unless @progress_row_max > 0 + @progress_row += mark.size + if @progress_row >= @progress_row_max + nl unless @output_level == VERBOSE + @progress_row = 0 + end + end + end + + def output_progress_in_detail_marker(fault) + if @progress_row_max > 0 + output("=" * @progress_row_max) + else + nl + end + end + + def output_progress_in_detail(fault) + return if @output_level == SILENT + nl + output_progress_in_detail_marker(fault) + if categorize_fault(fault) == :need_detail_faults + output_fault_in_detail(fault) + else + output_fault_in_short(fault) + end + output_progress_in_detail_marker(fault) + @progress_row = 0 + end + + def output?(level) + (level || @current_output_level) <= @output_level + end + + def color(name) + _color = @color_scheme[name] + _color ||= @color_scheme["success"] if name == "pass" + _color ||= ColorScheme.default[name] + _color + end + + def fault_class_color_name(fault_class) + fault_class.name.split(/::/).last.downcase + end + + def fault_color(fault) + color(fault_class_color_name(fault.class)) + end + + def fault_marker_color(fault) + color("#{fault_class_color_name(fault.class)}-marker") + end + + def summary_marker_color + color("#{@result.status}-marker") + end + + def guess_color_availability + return false unless @output.tty? + return true if windows? and ruby_2_0_or_later? + case ENV["TERM"] + when /(?:term|screen)(?:-(?:256)?color)?\z/ + true + else + return true if ENV["EMACS"] == "t" + false + end + end + + def windows? + /mswin|mingw/ === RUBY_PLATFORM + end + + def ruby_2_0_or_later? + RUBY_VERSION >= "2.0.0" + end + + def guess_progress_row_max + term_width = guess_term_width + if term_width.zero? + if ENV["EMACS"] == "t" + -1 + else + 79 + end + else + term_width + end + end + + def guess_term_width + guess_term_width_from_io || guess_term_width_from_env || 0 + end + + def guess_term_width_from_io + if @output.respond_to?(:winsize) + begin + @output.winsize[1] + rescue SystemCallError + nil + end + else + nil + end + end + + def guess_term_width_from_env + env = ENV["COLUMNS"] || ENV["TERM_WIDTH"] + return nil if env.nil? + + begin + Integer(env) + rescue ArgumentError + nil + end + end + end + + class ColorizedReadableDiffer < Diff::ReadableDiffer + def initialize(from, to, runner) + @runner = runner + super(from, to) + end + + def need_diff?(options={}) + return false if one_line_all_change? + operations.each do |tag,| + return true if [:replace, :equal].include?(tag) + end + false + end + + private + def one_line_all_change? + return false if operations.size != 1 + + tag, from_start, from_end, to_start, to_end = operations.first + return false if tag != :replace + return false if [from_start, from_end] != [0, 1] + return false if [from_start, from_end] != [to_start, to_end] + + _, _, _line_operations = line_operations(@from.first, @to.first) + _line_operations.size == 1 + end + + def output_single(something, color=nil) + @runner.__send__(:output_single, something, color) + end + + def output(something, color=nil) + @runner.__send__(:output, something, color) + end + + def color(name) + @runner.__send__(:color, name) + end + + def cut_off_ratio + 0 + end + + def default_ratio + 0 + end + + def tag(mark, color_name, contents) + _color = color(color_name) + contents.each do |content| + output_single(mark, _color) + output_single(" ") + output(content) + end + end + + def tag_deleted(contents) + tag("-", "diff-deleted-tag", contents) + end + + def tag_inserted(contents) + tag("+", "diff-inserted-tag", contents) + end + + def tag_equal(contents) + tag(" ", "normal", contents) + end + + def tag_difference(contents) + tag("?", "diff-difference-tag", contents) + end + + def diff_line(from_line, to_line) + to_operations = [] + from_line, to_line, _operations = line_operations(from_line, to_line) + + no_replace = true + _operations.each do |tag,| + if tag == :replace + no_replace = false + break + end + end + + output_single("?", color("diff-difference-tag")) + output_single(" ") + _operations.each do |tag, from_start, from_end, to_start, to_end| + from_width = compute_width(from_line, from_start, from_end) + to_width = compute_width(to_line, to_start, to_end) + case tag + when :replace + output_single(from_line[from_start...from_end], + color("diff-deleted")) + if (from_width < to_width) + output_single(" " * (to_width - from_width)) + end + to_operations << Proc.new do + output_single(to_line[to_start...to_end], + color("diff-inserted")) + if (to_width < from_width) + output_single(" " * (from_width - to_width)) + end + end + when :delete + output_single(from_line[from_start...from_end], + color("diff-deleted")) + unless no_replace + to_operations << Proc.new {output_single(" " * from_width)} + end + when :insert + if no_replace + output_single(to_line[to_start...to_end], + color("diff-inserted")) + else + output_single(" " * to_width) + to_operations << Proc.new do + output_single(to_line[to_start...to_end], + color("diff-inserted")) + end + end + when :equal + output_single(from_line[from_start...from_end]) + unless no_replace + to_operations << Proc.new {output_single(" " * to_width)} + end + else + raise "unknown tag: #{tag}" + end + end + output("") + + unless to_operations.empty? + output_single("?", color("diff-difference-tag")) + output_single(" ") + to_operations.each do |operation| + operation.call + end + output("") + end + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/emacs/testrunner.rb b/testdata/vendor/ruby/test/unit/ui/emacs/testrunner.rb new file mode 100644 index 000000000..cde06a804 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/emacs/testrunner.rb @@ -0,0 +1,49 @@ +require 'test/unit/ui/console/testrunner' + +module Test + module Unit + module UI + module Emacs + class TestRunner < Console::TestRunner + private + def output_setup_end + end + + def output_started + end + + def format_fault(fault) + return super unless fault.respond_to?(:label) + format_method_name = "format_fault_#{fault.label.downcase}" + if respond_to?(format_method_name, true) + __send__(format_method_name, fault) + else + super + end + end + + def format_fault_failure(failure) + if failure.location.size == 1 + location = failure.location[0] + location_display = location.sub(/\A(.+:\d+).*/, ' [\\1]') + else + location_display = "\n" + failure.location.join("\n") + end + result = "#{failure.label}:\n" + result << "#{failure.test_name}#{location_display}:\n" + result << failure.message + result + end + + def format_fault_error(error) + result = "#{error.label}:\n" + result << "#{error.test_name}:\n" + result << "#{error.message}\n" + result << error.backtrace.join("\n") + result + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/testrunner.rb b/testdata/vendor/ruby/test/unit/ui/testrunner.rb new file mode 100644 index 000000000..975cad9a2 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/testrunner.rb @@ -0,0 +1,53 @@ +require 'test/unit/ui/testrunnerutilities' + +module Test + module Unit + module UI + class TestRunner + extend TestRunnerUtilities + + attr_reader :listeners + def initialize(suite, options={}) + if suite.respond_to?(:suite) + @suite = suite.suite + else + @suite = suite + end + @options = options + @listeners = @options[:listeners] || [] + end + + # Begins the test run. + def start + setup_mediator + attach_to_mediator + attach_listeners + start_mediator + end + + private + def setup_mediator + @mediator = TestRunnerMediator.new(@suite) + end + + def attach_listeners + @listeners.each do |listener| + listener.attach_to_mediator(@mediator) + end + end + + def start_mediator + @mediator.run + end + + def diff_target_string?(string) + Assertions::AssertionMessage.diff_target_string?(string) + end + + def prepare_for_diff(from, to) + Assertions::AssertionMessage.prepare_for_diff(from, to) + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/testrunnermediator.rb b/testdata/vendor/ruby/test/unit/ui/testrunnermediator.rb new file mode 100644 index 000000000..5c8bd03ff --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/testrunnermediator.rb @@ -0,0 +1,112 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +require 'test/unit' +require 'test/unit/util/observable' +require 'test/unit/testresult' + +module Test + module Unit + module UI + + # Provides an interface to write any given UI against, + # hopefully making it easy to write new UIs. + class TestRunnerMediator + RESET = name + "::RESET" + STARTED = name + "::STARTED" + FINISHED = name + "::FINISHED" + + include Util::Observable + + # Creates a new TestRunnerMediator initialized to run + # the passed suite. + def initialize(suite) + @suite = suite + end + + # Runs the suite the TestRunnerMediator was created + # with. + def run + AutoRunner.need_auto_run = false + + result = create_result + + Test::Unit.run_at_start_hooks + start_time = Time.now + begin + with_listener(result) do + notify_listeners(RESET, @suite.size) + notify_listeners(STARTED, result) + + run_suite(result) + end + ensure + elapsed_time = Time.now - start_time + notify_listeners(FINISHED, elapsed_time) + end + Test::Unit.run_at_exit_hooks + + result + end + + # Just for backward compatibility for NetBeans. + # NetBeans should not use monkey patching. NetBeans + # should use runner change public API. + # + # See GitHub#38 + # https://github.com/test-unit/test-unit/issues/38 + def run_suite(result=nil) + if result.nil? + run + else + @suite.run(result) do |channel, value| + notify_listeners(channel, value) + end + end + end + + private + # A factory method to create the result the mediator + # should run with. Can be overridden by subclasses if + # one wants to use a different result. + def create_result + TestResult.new + end + + def measure_time + begin_time = Time.now + yield + Time.now - begin_time + end + + def with_listener(result) + finished_listener = result.add_listener(TestResult::FINISHED) do |*args| + notify_listeners(TestResult::FINISHED, *args) + end + changed_listener = result.add_listener(TestResult::CHANGED) do |*args| + notify_listeners(TestResult::CHANGED, *args) + end + pass_assertion_listener = result.add_listener(TestResult::PASS_ASSERTION) do |*args| + notify_listeners(TestResult::PASS_ASSERTION, *args) + end + fault_listener = result.add_listener(TestResult::FAULT) do |*args| + notify_listeners(TestResult::FAULT, *args) + end + + begin + yield + ensure + result.remove_listener(TestResult::FAULT, fault_listener) + result.remove_listener(TestResult::CHANGED, changed_listener) + result.remove_listener(TestResult::FINISHED, finished_listener) + result.remove_listener(TestResult::PASS_ASSERTION, + pass_assertion_listener) + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/testrunnerutilities.rb b/testdata/vendor/ruby/test/unit/ui/testrunnerutilities.rb new file mode 100644 index 000000000..33d80fb10 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/testrunnerutilities.rb @@ -0,0 +1,41 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + module UI + + # Provides some utilities common to most, if not all, + # TestRunners. + # + #-- + # + # Perhaps there ought to be a TestRunner superclass? There + # seems to be a decent amount of shared code between test + # runners. + + module TestRunnerUtilities + + # Creates a new TestRunner and runs the suite. + def run(suite, options={}) + return new(suite, options).start + end + + # Takes care of the ARGV parsing and suite + # determination necessary for running one of the + # TestRunners from the command line. + def start_command_line_test + if ARGV.empty? + puts "You should supply the name of a test suite file to the runner" + exit + end + require ARGV[0].gsub(/.+::/, '') + new(eval(ARGV[0])).start + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/ui/xml/testrunner.rb b/testdata/vendor/ruby/test/unit/ui/xml/testrunner.rb new file mode 100644 index 000000000..ce8acc042 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/ui/xml/testrunner.rb @@ -0,0 +1,224 @@ +#-- +# +# Author:: Kouhei Sutou +# Copyright:: +# * Copyright (c) 2011 Kouhei Sutou +# License:: Ruby license. + +require 'erb' +require 'time' +require 'test/unit/ui/testrunner' +require 'test/unit/ui/testrunnermediator' + +module Test + module Unit + module UI + module XML + + # Runs a Test::Unit::TestSuite and outputs XML. + class TestRunner < UI::TestRunner + include ERB::Util + + # Creates a new TestRunner for running the passed + # suite. :output option specifies where runner + # output should go to; defaults to STDOUT. + def initialize(suite, options={}) + super + @output = @options[:output] || STDOUT + if @options[:output_file_descriptor] + @output = IO.new(@options[:output_file_descriptor], "w") + end + @already_outputted = false + @indent = 0 + @top_level = true + @current_test = nil + @current_test_suite = nil + @already_outputted = false + end + + private + def attach_to_mediator + @mediator.add_listener(TestResult::PASS_ASSERTION, + &method(:result_pass_assertion)) + @mediator.add_listener(TestResult::FAULT, + &method(:result_fault)) + @mediator.add_listener(TestRunnerMediator::STARTED, + &method(:started)) + @mediator.add_listener(TestRunnerMediator::FINISHED, + &method(:finished)) + @mediator.add_listener(TestCase::STARTED_OBJECT, + &method(:test_started)) + @mediator.add_listener(TestCase::FINISHED_OBJECT, + &method(:test_finished)) + @mediator.add_listener(TestSuite::STARTED_OBJECT, + &method(:test_suite_started)) + @mediator.add_listener(TestSuite::FINISHED_OBJECT, + &method(:test_suite_finished)) + end + + def result_pass_assertion(result) + open_tag("pass-assertion") do + output_test(@current_test) + end + end + + def result_fault(fault) + open_tag("test-result") do + open_tag("result") do + output_test_suite(@current_test_suite) + output_test(@current_test) + open_tag("backtrace") do + fault.location.each do |entry| + file, line, info = entry.split(/:/, 3) + open_tag("entry") do + add_content("file", file) + add_content("line", line) + add_content("info", info) + end + end + end + if fault.respond_to?(:expected) + add_content("expected", fault.expected) + end + if fault.respond_to?(:actual) + add_content("actual", fault.actual) + end + add_content("detail", fault.message) + add_content("status", fault.label.downcase) + end + end + @already_outputted = true if fault.critical? + end + + def started(result) + @result = result + output_started + end + + def output_started + open_tag("stream") + end + + def finished(elapsed_time) + add_content("success", @result.passed?) + close_tag("stream") + end + + def test_started(test) + @already_outputted = false + @current_test = test + open_tag("start-test") do + output_test(test) + end + end + + def test_finished(test) + unless @already_outputted + open_tag("test-result") do + output_test(test) + open_tag("result") do + output_test_suite(@current_test_suite) + output_test(test) + add_content("status", "success") + end + end + end + + open_tag("complete-test") do + output_test(test) + add_content("success", test.passed?) + end + @current_test = nil + end + + def test_suite_started(suite) + @current_test_suite = suite + if suite.test_case.nil? + open_tag("ready-test-suite") do + add_content("n-tests", suite.size) + end + open_tag("start-test-suite") do + output_test_suite(suite) + end + else + open_tag("ready-test-case") do + output_test_suite(suite) + add_content("n-tests", suite.size) + end + open_tag("start-test-case") do + output_test_suite(suite) + end + end + end + + def test_suite_finished(suite) + if suite.test_case.nil? + open_tag("complete-test-suite") do + output_test_suite(suite) + add_content("success", suite.passed?) + end + else + open_tag("complete-test-case") do + output_test_suite(suite) + add_content("success", suite.passed?) + end + end + @current_test_suite = nil + end + + def indent + " " * @indent + end + + def open_tag(name) + @output.puts("#{indent}<#{name}>") + @indent += 2 + if block_given? + yield + close_tag(name) + end + end + + def add_content(name, content) + return if content.nil? + case content + when Time + content = content.iso8601 + end + @output.puts("#{indent}<#{name}>#{h(content)}") + end + + def close_tag(name) + @indent -= 2 + @output.puts("#{indent}") + end + + def output_test(test) + open_tag("test") do + add_content("name", test.method_name) + add_content("start-time", test.start_time) + add_content("elapsed", test.elapsed_time) + end + end + + def output_test_suite(test_suite) + test_case = test_suite.test_case + if test_case.nil? + open_tag("test-suite") do + add_content("name", test_suite.name) + add_content("start-time", test_suite.start_time) + add_content("elapsed", test_suite.elapsed_time) + end + else + open_tag("test-case") do + add_content("name", test_suite.name) + add_content("start-time", test_suite.start_time) + add_content("elapsed", test_suite.elapsed_time) + end + end + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/util/backtracefilter.rb b/testdata/vendor/ruby/test/unit/util/backtracefilter.rb new file mode 100644 index 000000000..c8c299313 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/util/backtracefilter.rb @@ -0,0 +1,59 @@ +begin + require 'power_assert' +rescue LoadError, SyntaxError +end + +module Test + module Unit + module Util + module BacktraceFilter + TESTUNIT_FILE_SEPARATORS = %r{[\\/:]} + TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3] + TESTUNIT_RB_FILE = /\.rb\Z/ + + POWERASSERT_PREFIX = + defined?(PowerAssert) ? + PowerAssert.method(:start).source_location[0].split(TESTUNIT_FILE_SEPARATORS)[0..-2] : + nil + + module_function + def filter_backtrace(backtrace, prefix=nil) + return ["No backtrace"] unless backtrace + return backtrace if ENV["TEST_UNIT_ALL_BACKTRACE"] + + if prefix + split_prefixes = [prefix.split(TESTUNIT_FILE_SEPARATORS)] + else + split_prefixes = [TESTUNIT_PREFIX, POWERASSERT_PREFIX].compact + end + test_unit_internal_p = lambda do |entry| + components = entry.split(TESTUNIT_FILE_SEPARATORS) + split_prefixes.any? do |split_prefix| + split_entry = components[0, split_prefix.size] + next false unless split_entry[0..-2] == split_prefix[0..-2] + split_entry[-1].sub(TESTUNIT_RB_FILE, '') == split_prefix[-1] + end + end + + in_user_code = false + new_backtrace = backtrace.reverse.reject do |entry| + if test_unit_internal_p.call(entry) + in_user_code = true + true + else + not in_user_code + end + end.reverse + + if new_backtrace.empty? + new_backtrace = backtrace.reject do |entry| + test_unit_internal_p.call(entry) + end + new_backtrace = backtrace if new_backtrace.empty? + end + new_backtrace + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/util/method-owner-finder.rb b/testdata/vendor/ruby/test/unit/util/method-owner-finder.rb new file mode 100644 index 000000000..46a5b0cf9 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/util/method-owner-finder.rb @@ -0,0 +1,28 @@ +module Test + module Unit + module Util + module MethodOwnerFinder + module_function + def find(object, method_name) + method = object.method(method_name) + return method.owner if method.respond_to?(:owner) + + if /\((.+?)\)\#/ =~ method.to_s + owner_name = $1 + if /\A# ["stdout\n", "stderr\n"] + def capture_output + require 'stringio' + + output = StringIO.new + error = StringIO.new + stdout_save, stderr_save = $stdout, $stderr + $stdout, $stderr = output, error + begin + yield + [output.string, error.string] + ensure + $stdout, $stderr = stdout_save, stderr_save + end + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/util/procwrapper.rb b/testdata/vendor/ruby/test/unit/util/procwrapper.rb new file mode 100644 index 000000000..ad7252186 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/util/procwrapper.rb @@ -0,0 +1,48 @@ +#-- +# +# Author:: Nathaniel Talbott. +# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved. +# License:: Ruby license. + +module Test + module Unit + module Util + + # Allows the storage of a Proc passed through '&' in a + # hash. + # + # Note: this may be inefficient, since the hash being + # used is not necessarily very good. In Observable, + # efficiency is not too important, since the hash is + # only accessed when adding and removing listeners, + # not when notifying. + + class ProcWrapper + + # Creates a new wrapper for a_proc. + def initialize(a_proc) + @a_proc = a_proc + @hash = a_proc.inspect.sub(/^(#<#{a_proc.class}:)/){''}.sub(/(>)$/){''}.hex + end + + def hash + return @hash + end + + def ==(other) + case(other) + when ProcWrapper + return @a_proc == other.to_proc + else + return super + end + end + alias :eql? :== + + def to_proc + return @a_proc + end + end + end + end +end diff --git a/testdata/vendor/ruby/test/unit/version.rb b/testdata/vendor/ruby/test/unit/version.rb new file mode 100644 index 000000000..8e541fa06 --- /dev/null +++ b/testdata/vendor/ruby/test/unit/version.rb @@ -0,0 +1,5 @@ +module Test + module Unit + VERSION = '3.1.7' + end +end