File: tmstd/assertion.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: TmStd#3
  module: Assertion#19
has properties
module method: disable! / 1 #20
module method: disable? #27
module method: kind_of / 4 #32
module method: opt_kind_of / 4 #62
module method: tuple_of / 4 #92
module method: instance_of / 4 #176
module method: subclass_of / 4 #206
module method: nil / 3 #250
module method: not_nil / 3 #274
module method: boolean / 3 #300
module method: assert / 3 #326
module method: abort / 2 #345
constant: DISPLAY_WIDTH #361
constant: LINE_LENGTH #362
constant: TOP_LINE #364
constant: SEPARATE_LINE #365
constant: BOTTOM_LINE #366
module method: __print_box__ / 3 #369
module method: __print_line__ / 1 #488
  module: Exception#5
  class: Abstract#7
inherits from
  StandardError ( Builtin-Module )
  class: AssertionFail#9
inherits from
  Abstract ( TmStd::Exception )
  class: AssertionError#10
inherits from
  Abstract ( TmStd::Exception )
  class: SubclassResponsibility#11
inherits from
  Abstract ( TmStd::Exception )
  class: LogfileOpenError#13
inherits from
  Abstract ( TmStd::Exception )

Class Hierarchy

Object ( Builtin-Module )
Exception ( Builtin-Module )
StandardError ( Builtin-Module )
Abstract ( TmStd::Exception ) — #7
  AssertionFail    #9
  AssertionError    #10
  SubclassResponsibility    #11
  LogfileOpenError    #13

Code

   1  # $Id: assertion.rb,v 1.7 2012/04/17 02:49:40 machan Exp $
   2 
   3  module TmStd
   4 
   5  module Exception
   6 
   7  class Abstract < StandardError; end
   8 
   9  class AssertionFail             < Abstract; end
  10  class AssertionError            < Abstract; end
  11  class SubclassResponsibility    < Abstract; end
  12 
  13  class LogfileOpenError          < Abstract; end     # Need 'exception.rb'..
  14 
  15  end # TmStd::Exception
  16 
  17 
  18 
  19  module Assertion
  20      def self.disable!(yes_or_no = true)
  21          @disable = if yes_or_no then true else false end
  22 
  23          nil
  24      end
  25 
  26 
  27      def self.disable?
  28          @disable
  29      end
  30 
  31 
  32      def self.kind_of(actual, expected, msg_fmt = nil, *msg_args)
  33          if Assertion.disable?
  34              return actual
  35          end
  36 
  37          unless expected.kind_of?(Class)
  38              raise TmStd::Exception::AssertionError
  39          end
  40          unless (! msg_fmt) || msg_fmt.kind_of?(String)
  41              raise TmStd::Exception::AssertionError
  42          end
  43 
  44          unless actual.kind_of?(expected)
  45              Assertion.__print_box__(
  46                  'A is kind of E',
  47                  {
  48                      :message        => [msg_fmt, msg_args],
  49                      :expected_type  => expected.to_s
  50                  }, {
  51                      :actual_type    => actual.class.to_s,
  52                      :actual_value   => actual.to_s
  53                  }
  54              )
  55              raise TmStd::Exception::AssertionFail
  56          end
  57 
  58          actual
  59      end
  60 
  61 
  62      def self.opt_kind_of(actual, expected, msg_fmt = nil, *msg_args)
  63          if Assertion.disable?
  64              return actual
  65          end
  66 
  67          unless expected.kind_of?(Class)
  68              raise TmStd::Exception::AssertionError
  69          end
  70          unless (! msg_fmt) || msg_fmt.kind_of?(String)
  71              raise TmStd::Exception::AssertionError
  72          end
  73 
  74          unless (! actual) || actual.kind_of?(expected)
  75              Assertion.__print_box__(
  76                  'A is kind of E, or nil',
  77                  {
  78                      :message        => [msg_fmt, msg_args],
  79                      :expected_type  => expected.to_s
  80                  }, {
  81                      :actual_type    => actual.class.to_s,
  82                      :actual_value   => actual.to_s
  83                  }
  84              )
  85              raise TmStd::Exception::AssertionFail
  86          end
  87 
  88          actual
  89      end
  90 
  91 
  92      def self.tuple_of(actual, expected, msg_fmt = nil, *msg_args)
  93          if Assertion.disable?
  94              return actual
  95          end
  96 
  97          unless expected.kind_of?(Array)
  98              raise TmStd::Exception::AssertionError
  99          end
 100          unless expected.length >= 2
 101              raise TmStd::Exception::AssertionError
 102          end
 103          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 104              raise TmStd::Exception::AssertionError
 105          end
 106 
 107          unless actual.kind_of?(Array)
 108              Assertion.__print_box__(
 109                  'A is kind of Array (tuple-of)',
 110                  {
 111                      :message        => [msg_fmt, msg_args],
 112                      :expected_type  => 'Array'
 113                  }, {
 114                      :actual_type    => actual.class.to_s,
 115                      :actual_value   => actual.to_s
 116                  }
 117              )
 118              raise TmStd::Exception::AssertionFail
 119          end
 120 
 121          unless actual.length == expected.length
 122              Assertion.__print_box__(
 123                  format("Length of A is %d (tuple-of)", expected.length),
 124                  {
 125                      :message        => [msg_fmt, msg_args],
 126                      :expected_type  => format(
 127                          "[%s] (Array)",
 128                          expected.map { |c| c.to_s }.join(', ')
 129                      )
 130                  }, {
 131                      :actual_type    => format(
 132                          "[%s] (Array)",
 133                          actual.map { |v| v.class.to_s }.join(', ')
 134                      ),
 135                      :actual_value   => format(
 136                          "[\n  %s\n]",
 137                          actual.map { |v| v.to_s }.join(",\n  ")
 138                      )
 139                  }
 140              )
 141              raise TmStd::Exception::AssertionFail
 142          end
 143 
 144          (0 .. (actual.length - 1)).each do |i|
 145              unless actual[i].kind_of?(expected[i])
 146                  Assertion.__print_box__(
 147                      format(
 148                          "the #%d of A is kind of %s (tuple-of)",
 149                          i + 1, expected[i]
 150                      ),
 151                      {
 152                          :message        => [msg_fmt, msg_args],
 153                          :expected_type  => format(
 154                              "[%s] (Array)",
 155                              expected.map { |c| c.to_s }.join(', ')
 156                          )
 157                      }, {
 158                          :actual_type    => format(
 159                              "[%s] (Array)",
 160                              actual.map { |v| v.class.to_s }.join(', ')
 161                          ),
 162                          :actual_value   => format(
 163                              "[\n  %s\n]",
 164                              actual.map { |v| v.to_s }.join(",\n  ")
 165                          )
 166                      }
 167                  )
 168                  raise TmStd::Exception::AssertionFail
 169              end
 170          end
 171 
 172          actual
 173      end
 174 
 175 
 176      def self.instance_of(actual, expected, msg_fmt = nil, *msg_args)
 177          if Assertion.disable?
 178              return actual
 179          end
 180 
 181          unless expected.kind_of?(Class)
 182              raise TmStd::Exception::AssertionError
 183          end
 184          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 185              raise TmStd::Exception::AssertionError
 186          end
 187 
 188          unless actual.instance_of?(expected)
 189              Assertion.__print_box__(
 190                  'A is instance of E',
 191                  {
 192                      :message        => [msg_fmt, msg_args],
 193                      :expected_type  => expected.to_s
 194                  }, {
 195                      :actual_type    => actual.class.to_s,
 196                      :actual_value   => actual.to_s
 197                  }
 198              )
 199              raise TmStd::Exception::AssertionFail
 200          end
 201 
 202          actual
 203      end
 204 
 205 
 206      def self.subclass_of(actual, expected, msg_fmt = nil, *msg_args)
 207          if Assertion.disable?
 208              return actual
 209          end
 210 
 211          unless expected.kind_of?(Class)
 212              raise TmStd::Exception::AssertionError
 213          end
 214          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 215              raise TmStd::Exception::AssertionError
 216          end
 217 
 218          unless actual.kind_of?(Class)
 219              Assertion.__print_box__(
 220                  'A is kind of Class (subclass-of)',
 221                  {
 222                      :message        => [msg_fmt, msg_args],
 223                      :expected_type  => 'Class or Module'
 224                  }, {
 225                      :actual_type    => actual.class.to_s,
 226                      :actual_value   => actual.to_s
 227                  }
 228              )
 229              raise TmStd::Exception::AssertionFail
 230          end
 231 
 232          unless actual <= expected
 233              Assertion.__print_box__(
 234                  'A is subclass of E',
 235                  {
 236                      :message        => [msg_fmt, msg_args],
 237                      :expected_type  => expected.to_s
 238                  }, {
 239                      :actual_type    => actual.class.to_s,
 240                      :actual_value   => actual.to_s
 241                  }
 242              )
 243              raise TmStd::Exception::AssertionFail
 244          end
 245 
 246          actual
 247      end
 248 
 249 
 250      def self.nil(actual = nil, msg_fmt = nil, *msg_args)
 251          return nil if Assertion.disable?
 252 
 253          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 254              raise TmStd::Exception::AssertionError
 255          end
 256 
 257          unless actual.equal?(nil)
 258              Assertion.__print_box__(
 259                  'A is nil',
 260                  {
 261                      :message        => [msg_fmt, msg_args]
 262                  }, {
 263                      :actual_type    => actual.class.to_s,
 264                      :actual_value   => actual.to_s
 265                  }
 266              )
 267              raise TmStd::Exception::AssertionFail
 268          end
 269 
 270          nil
 271      end
 272 
 273 
 274      def self.not_nil(actual, msg_fmt = nil, *msg_args)
 275          if Assertion.disable?
 276              return actual
 277          end
 278 
 279          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 280              raise TmStd::Exception::AssertionError
 281          end
 282 
 283          unless (! actual.equal?(nil))
 284              Assertion.__print_box__(
 285                  "A isn't nil",
 286                  {
 287                      :message        => [msg_fmt, msg_args]
 288                  }, {
 289                      :actual_type    => actual.class.to_s,
 290                      :actual_value   => actual.to_s
 291                  }
 292              )
 293              raise TmStd::Exception::AssertionFail
 294          end
 295 
 296          actual
 297      end
 298 
 299 
 300      def self.boolean(actual, msg_fmt = nil, *msg_args)
 301          if Assertion.disable?
 302              return actual
 303          end
 304 
 305          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 306              raise TmStd::Exception::AssertionError
 307          end
 308 
 309          unless actual == true || actual == false
 310              Assertion.__print_box__(
 311                  'A is true or false',
 312                  {
 313                      :message        => [msg_fmt, msg_args]
 314                  }, {
 315                      :actual_type    => actual.class.to_s,
 316                      :actual_value   => actual.to_s
 317                  }
 318              )
 319              raise TmStd::Exception::AssertionFail
 320          end
 321 
 322          actual
 323      end
 324 
 325 
 326      def self.assert(cond, msg_fmt = nil, *msg_args)
 327          return nil if Assertion.disable?
 328 
 329          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 330              raise TmStd::Exception::AssertionError
 331          end
 332 
 333          unless cond
 334              Assertion.__print_box__(
 335                  nil,
 336                  { :message => [msg_fmt, msg_args] }
 337              )
 338              raise TmStd::Exception::AssertionFail
 339          end
 340 
 341          nil
 342      end
 343 
 344 
 345      def self.abort(msg_fmt = nil, *msg_args)
 346          unless (! msg_fmt) || msg_fmt.kind_of?(String)
 347              raise TmStd::Exception::AssertionError
 348          end
 349 
 350          Assertion.__print_box__(
 351              nil,
 352              { :message => [msg_fmt, msg_args] }
 353          )
 354          raise TmStd::Exception::AssertionFail
 355 
 356          nil
 357      end
 358 
 359 
 360 
 361      DISPLAY_WIDTH   = 80
 362      LINE_LENGTH     = DISPLAY_WIDTH - 2
 363 
 364      TOP_LINE        = '+' + ('=' * (LINE_LENGTH - 1))
 365      SEPARATE_LINE   = '|' + ('-' * (LINE_LENGTH - 1))
 366      BOTTOM_LINE     = '+' + ('=' * (LINE_LENGTH - 1))
 367 
 368 
 369      def self.__print_box__(title, rows, opt_rows = {})
 370          if title && (! title.kind_of?(String))
 371              raise TmStd::Exception::AssertionError
 372          end
 373          unless rows.kind_of?(Hash)
 374              raise TmStd::Exception::AssertionError
 375          end
 376          unless opt_rows.kind_of?(Hash)
 377              raise TmStd::Exception::AssertionError
 378          end
 379 
 380          message         = nil
 381          expected_type   = nil
 382          actual_type     = nil
 383          actual_value    = nil
 384          for key, val in rows.merge(opt_rows)
 385              unless key.kind_of?(Symbol)
 386                  raise TmStd::Exception::AssertionError
 387              end
 388 
 389              case key
 390              when :message
 391                  unless val.kind_of?(Array)
 392                      raise TmStd::Exception::AssertionError
 393                  end
 394                  unless val.length == 2
 395                      raise TmStd::Exception::AssertionError
 396                  end
 397                  msg_fmt, msg_args = val
 398 
 399                  unless (! msg_fmt) || msg_fmt.kind_of?(String)
 400                      raise TmStd::Exception::AssertionError
 401                  end
 402                  unless (! msg_args) || msg_args.kind_of?(Array)
 403                      raise TmStd::Exception::AssertionError
 404                  end
 405 
 406                  message = if msg_fmt
 407                                  format(msg_fmt, *msg_args)
 408                              else
 409                                  nil
 410                              end
 411              when :expected_type
 412                  unless val.kind_of?(String)
 413                      raise TmStd::Exception::AssertionError
 414                  end
 415 
 416                  expected_type = val
 417              when :actual_type
 418                  unless val.kind_of?(String)
 419                      raise TmStd::Exception::AssertionError
 420                  end
 421 
 422                  actual_type = val
 423              when :actual_value
 424                  unless val.kind_of?(String)
 425                      raise TmStd::Exception::AssertionError
 426                  end
 427 
 428                  actual_value = val
 429              else
 430                  raise TmStd::Exception::AssertionError
 431              end
 432          end
 433          rows_is_empty       = [message, expected_type].all?     { |x| ! x }
 434          opt_rows_is_empty   = [actual_type, actual_value].all?  { |x| ! x }
 435          box_is_empty        = rows_is_empty && opt_rows_is_empty
 436 
 437          formated_title =
 438              if title
 439                  format " ASSERTION FAIL!! : %s. ", title
 440              else
 441                  ' ASSERTION FAIL!! '
 442              end
 443          len = (LINE_LENGTH / 2).to_i - (formated_title.length / 2).to_i
 444          top_line = [
 445              TOP_LINE[0, len], formated_title, TOP_LINE[(len * -1), len]
 446          ].join
 447 
 448 
 449          $stderr.puts ''
 450 
 451          $stderr.puts top_line
 452 
 453          if box_is_empty
 454              return
 455          end
 456 
 457          if msg_fmt
 458              $stderr.puts "|[MESSAGE]"
 459              Assertion.__print_line__ format(msg_fmt, *msg_args)
 460          end
 461 
 462          if expected_type
 463              $stderr.puts "|[EXPECTED(E) TYPE]"
 464              Assertion.__print_line__ expected_type
 465          end
 466 
 467          if (! rows_is_empty) && (! opt_rows_is_empty)
 468              $stderr.puts SEPARATE_LINE
 469          end
 470 
 471          unless opt_rows_is_empty
 472              if actual_type
 473                  $stderr.puts "|[ACTUAL(A) TYPE]"
 474                  Assertion.__print_line__ actual_type
 475              end
 476 
 477              if actual_value
 478                  $stderr.puts "|[ACTUAL(A) VALUE]"
 479                  Assertion.__print_line__ actual_value
 480              end
 481          end
 482          $stderr.puts BOTTOM_LINE
 483 
 484          nil
 485      end
 486 
 487 
 488      def self.__print_line__(str)
 489          unless str.kind_of?(String)
 490              raise TmStd::Exception::AssertionError
 491          end
 492 
 493          str.each_line do |line|
 494              $stderr.puts '|  ' + line
 495          end
 496 
 497          nil
 498      end
 499  end # TmStd::Assertion
 500 
 501 
 502  end # TmStd