Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocks fail to compile for methods with free variables #48

Closed
postmodern opened this issue Dec 13, 2022 · 8 comments
Closed

Mocks fail to compile for methods with free variables #48

postmodern opened this issue Dec 13, 2022 · 8 comments
Assignees
Labels
bug Something isn't working

Comments

@postmodern
Copy link

I was trying to test chars.cr against Crystal 1.6.2 and Spectator 0.11.4, but got this strange error coming from deep within enumerable.cr. The beginning of the error is a macro expansion of a method stub. I assume I need to update how I'm defining the stubs?

    mock Chars::CharSet do
      stub :|, other : Chars::CharSet
    end

    let(other) { described_class.new }
    let(return_value) { described_class.new }

    it "must call #+" do
      expect(subject).to receive(:|).with(other).and_return(return_value)

      expect(subject + other).to be(return_value)
    end

Error Trace

$ crystal spec --error-trace 
There was a problem expanding macro 'finished'

Called macro defined in macro 'define_subtype'

 46 | macro finished

Which expanded to:

 > 1 |             stub_type Chars::CharSet
 > 2 | 
 > 3 |             stub(:|, other : Chars::CharSet)
 > 4 |           
Error: expanding macro


There was a problem expanding macro 'stub_type'

Called macro defined in lib/spectator/src/spectator/mocks/stubbable.cr:339:13

 339 | private macro stub_type(type_name = @type)

Which expanded to:

 >    1 |       
 >    2 |       
 >    3 |         
 >    4 |           default_stub  def colorize(
 >    5 |             r : UInt8, g : UInt8, b : UInt8, 
 >    6 |             
 >    7 |             
 >    8 |           )
 >    9 |             super
 >   10 |           end
 >   11 |         
 >   12 |           default_stub  def colorize(
 >   13 |             fore : UInt8, 
 >   14 |             
 >   15 |             
 >   16 |           )
 >   17 |             super
 >   18 |           end
 >   19 |         
 >   20 |           default_stub  def colorize(
 >   21 |             fore : Symbol, 
 >   22 |             
 >   23 |             
 >   24 |           )
 >   25 |             super
 >   26 |           end
 >   27 |         
 >   28 |           default_stub  def colorize(
 >   29 |             fore : Color, 
 >   30 |             
 >   31 |             
 >   32 |           )
 >   33 |             super
 >   34 |           end
 >   35 |         
 >   36 |           default_stub  def colorize(
 >   37 |             
 >   38 |             
 >   39 |             
 >   40 |           ) : Colorize::Object
 >   41 |             super
 >   42 |           end
 >   43 |         
 >   44 | 
 >   45 |         
 >   46 |       
 >   47 |         
 >   48 |           abstract_stub  def ==(
 >   49 |             other, 
 >   50 |             
 >   51 |             
 >   52 |           )
 >   53 |             super
 >   54 |           end
 >   55 |         
 >   56 |           default_stub  def !=(
 >   57 |             other, 
 >   58 |             
 >   59 |             
 >   60 |           )
 >   61 |             super
 >   62 |           end
 >   63 |         
 >   64 |           default_stub  def !~(
 >   65 |             other, 
 >   66 |             
 >   67 |             
 >   68 |           )
 >   69 |             super
 >   70 |           end
 >   71 |         
 >   72 |           default_stub  def ===(
 >   73 |             other : JSON::Any, 
 >   74 |             
 >   75 |             
 >   76 |           )
 >   77 |             super
 >   78 |           end
 >   79 |         
 >   80 |           default_stub  def ===(
 >   81 |             other, 
 >   82 |             
 >   83 |             
 >   84 |           )
 >   85 |             super
 >   86 |           end
 >   87 |         
 >   88 |           default_stub  def =~(
 >   89 |             other, 
 >   90 |             
 >   91 |             
 >   92 |           )
 >   93 |             super
 >   94 |           end
 >   95 |         
 >   96 |           abstract_stub  def hash(
 >   97 |             hasher, 
 >   98 |             
 >   99 |             
 >  100 |           )
 >  101 |             super
 >  102 |           end
 >  103 |         
 >  104 |           default_stub  def hash(
 >  105 |             
 >  106 |             
 >  107 |             
 >  108 |           )
 >  109 |             super
 >  110 |           end
 >  111 |         
 >  112 |           abstract_stub  def to_s(
 >  113 |             io : IO, 
 >  114 |             
 >  115 |             
 >  116 |           ) : Nil
 >  117 |             super
 >  118 |           end
 >  119 |         
 >  120 |           default_stub  def to_s(
 >  121 |             
 >  122 |             
 >  123 |             
 >  124 |           ) : String
 >  125 |             super
 >  126 |           end
 >  127 |         
 >  128 |           default_stub  def inspect(
 >  129 |             io : IO, 
 >  130 |             
 >  131 |             
 >  132 |           ) : Nil
 >  133 |             super
 >  134 |           end
 >  135 |         
 >  136 |           default_stub  def inspect(
 >  137 |             
 >  138 |             
 >  139 |             
 >  140 |           ) : String
 >  141 |             super
 >  142 |           end
 >  143 |         
 >  144 |           default_stub  def pretty_print(
 >  145 |             pp : PrettyPrint, 
 >  146 |             
 >  147 |             
 >  148 |           ) : Nil
 >  149 |             super
 >  150 |           end
 >  151 |         
 >  152 |           default_stub  def pretty_inspect(
 >  153 |             width = 79, newline = "\n", indent = 0, 
 >  154 |             
 >  155 |             
 >  156 |           ) : String
 >  157 |             super
 >  158 |           end
 >  159 |         
 >  160 |           default_stub  def tap(
 >  161 |             
 >  162 |             
 >  163 |             &
 >  164 |           )
 >  165 |             super { |*__temp_1063| yield *__temp_1063 }
 >  166 |           end
 >  167 |         
 >  168 |           default_stub  def try(
 >  169 |             
 >  170 |             
 >  171 |             &
 >  172 |           )
 >  173 |             super { |*__temp_1063| yield *__temp_1063 }
 >  174 |           end
 >  175 |         
 >  176 |           default_stub  def in?(
 >  177 |             collection : Object, 
 >  178 |             
 >  179 |             
 >  180 |           ) : Bool
 >  181 |             super
 >  182 |           end
 >  183 |         
 >  184 |           default_stub  def in?(
 >  185 |             *values : Object, 
 >  186 |             
 >  187 |             
 >  188 |           ) : Bool
 >  189 |             super
 >  190 |           end
 >  191 |         
 >  192 |           default_stub  def not_nil!(
 >  193 |             
 >  194 |             
 >  195 |             
 >  196 |           )
 >  197 |             super
 >  198 |           end
 >  199 |         
 >  200 |           default_stub  def itself(
 >  201 |             
 >  202 |             
 >  203 |             
 >  204 |           )
 >  205 |             super
 >  206 |           end
 >  207 |         
 >  208 |           abstract_stub  def dup(
 >  209 |             
 >  210 |             
 >  211 |             
 >  212 |           )
 >  213 |             super
 >  214 |           end
 >  215 |         
 >  216 |           default_stub  def unsafe_as(
 >  217 |             type : T.class, 
 >  218 |             
 >  219 |             
 >  220 |           ) forall T
 >  221 |             super
 >  222 |           end
 >  223 |         
 >  224 |           default_stub  def crystal_type_id(
 >  225 |             
 >  226 |             
 >  227 |             
 >  228 |           ) : Int32
 >  229 |             super
 >  230 |           end
 >  231 |         
 >  232 |           default_stub  def to_json(
 >  233 |             io : IO, 
 >  234 |             
 >  235 |             
 >  236 |           ) : Nil
 >  237 |             super
 >  238 |           end
 >  239 |         
 >  240 |           default_stub  def to_json(
 >  241 |             
 >  242 |             
 >  243 |             
 >  244 |           ) : String
 >  245 |             super
 >  246 |           end
 >  247 |         
 >  248 |           default_stub  def to_pretty_json(
 >  249 |             indent : String = "  ", 
 >  250 |             
 >  251 |             
 >  252 |           ) : String
 >  253 |             super
 >  254 |           end
 >  255 |         
 >  256 |           default_stub  def to_pretty_json(
 >  257 |             io : IO, indent : String = "  ", 
 >  258 |             
 >  259 |             
 >  260 |           ) : Nil
 >  261 |             super
 >  262 |           end
 >  263 |         
 >  264 | 
 >  265 |         
 >  266 |           default_stub protected def self.set_crystal_type_id(
 >  267 |             ptr, 
 >  268 |             
 >  269 |             
 >  270 |           )
 >  271 |             super
 >  272 |           end
 >  273 |         
 >  274 |           default_stub  def self.from_json(
 >  275 |             string_or_io, root : String, 
 >  276 |             
 >  277 |             
 >  278 |           )
 >  279 |             super
 >  280 |           end
 >  281 |         
 >  282 |           default_stub  def self.from_json(
 >  283 |             string_or_io, 
 >  284 |             
 >  285 |             
 >  286 |           )
 >  287 |             super
 >  288 |           end
 >  289 |         
 >  290 |       
 >  291 |         
 >  292 |           default_stub  def object_id(
 >  293 |             
 >  294 |             
 >  295 |             
 >  296 |           ) : UInt64
 >  297 |             super
 >  298 |           end
 >  299 |         
 >  300 |           default_stub  def ==(
 >  301 |             other : self, 
 >  302 |             
 >  303 |             
 >  304 |           )
 >  305 |             super
 >  306 |           end
 >  307 |         
 >  308 |           default_stub  def ==(
 >  309 |             other : JSON::Any, 
 >  310 |             
 >  311 |             
 >  312 |           )
 >  313 |             super
 >  314 |           end
 >  315 |         
 >  316 |           default_stub  def ==(
 >  317 |             other, 
 >  318 |             
 >  319 |             
 >  320 |           )
 >  321 |             super
 >  322 |           end
 >  323 |         
 >  324 |           default_stub  def same?(
 >  325 |             other : Reference, 
 >  326 |             
 >  327 |             
 >  328 |           ) : Bool
 >  329 |             super
 >  330 |           end
 >  331 |         
 >  332 |           default_stub  def same?(
 >  333 |             other : Nil, 
 >  334 |             
 >  335 |             
 >  336 |           )
 >  337 |             super
 >  338 |           end
 >  339 |         
 >  340 |           default_stub  def dup(
 >  341 |             
 >  342 |             
 >  343 |             
 >  344 |           )
 >  345 |             super
 >  346 |           end
 >  347 |         
 >  348 |           default_stub  def hash(
 >  349 |             hasher, 
 >  350 |             
 >  351 |             
 >  352 |           )
 >  353 |             super
 >  354 |           end
 >  355 |         
 >  356 |           default_stub  def inspect(
 >  357 |             io : IO, 
 >  358 |             
 >  359 |             
 >  360 |           ) : Nil
 >  361 |             super
 >  362 |           end
 >  363 |         
 >  364 |           default_stub  def pretty_print(
 >  365 |             pp, 
 >  366 |             
 >  367 |             
 >  368 |           ) : Nil
 >  369 |             super
 >  370 |           end
 >  371 |         
 >  372 |           default_stub  def to_s(
 >  373 |             io : IO, 
 >  374 |             
 >  375 |             
 >  376 |           ) : Nil
 >  377 |             super
 >  378 |           end
 >  379 |         
 >  380 |           default_stub private def exec_recursive(
 >  381 |             method, 
 >  382 |             
 >  383 |             &
 >  384 |           )
 >  385 |             super { |*__temp_1063| yield *__temp_1063 }
 >  386 |           end
 >  387 |         
 >  388 |           default_stub private def exec_recursive_clone(
 >  389 |             
 >  390 |             
 >  391 |             &
 >  392 |           )
 >  393 |             super { |*__temp_1063| yield *__temp_1063 }
 >  394 |           end
 >  395 |         
 >  396 | 
 >  397 |         
 >  398 |       
 >  399 |         
 >  400 |           abstract_stub  def each(
 >  401 |             
 >  402 |             
 >  403 |             & : (T ->)
 >  404 |           )
 >  405 |             super { |*__temp_1063| yield *__temp_1063 }
 >  406 |           end
 >  407 |         
 >  408 |           default_stub  def all?(
 >  409 |             
 >  410 |             
 >  411 |             & : (T ->)
 >  412 |           ) : Bool
 >  413 |             super { |*__temp_1063| yield *__temp_1063 }
 >  414 |           end
 >  415 |         
 >  416 |           default_stub  def all?(
 >  417 |             pattern, 
 >  418 |             
 >  419 |             
 >  420 |           ) : Bool
 >  421 |             super
 >  422 |           end
 >  423 |         
 >  424 |           default_stub  def all?(
 >  425 |             
 >  426 |             
 >  427 |             
 >  428 |           ) : Bool
 >  429 |             super
 >  430 |           end
 >  431 |         
 >  432 |           default_stub  def any?(
 >  433 |             
 >  434 |             
 >  435 |             & : (T ->)
 >  436 |           ) : Bool
 >  437 |             super { |*__temp_1063| yield *__temp_1063 }
 >  438 |           end
 >  439 |         
 >  440 |           default_stub  def any?(
 >  441 |             pattern, 
 >  442 |             
 >  443 |             
 >  444 |           ) : Bool
 >  445 |             super
 >  446 |           end
 >  447 |         
 >  448 |           default_stub  def any?(
 >  449 |             
 >  450 |             
 >  451 |             
 >  452 |           ) : Bool
 >  453 |             super
 >  454 |           end
 >  455 |         
 >  456 |           default_stub  def chunks(
 >  457 |             
 >  458 |             
 >  459 |             &block : (T -> U)
 >  460 |           ) forall U
 >  461 |             super { |*__temp_1063| yield *__temp_1063 }
 >  462 |           end
 >  463 |         
 >  464 |           default_stub private def chunks_internal(
 >  465 |             original_block : (T -> U), 
 >  466 |             
 >  467 |             &
 >  468 |           ) forall U
 >  469 |             super { |*__temp_1063| yield *__temp_1063 }
 >  470 |           end
 >  471 |         
 >  472 |           default_stub  def compact_map(
 >  473 |             
 >  474 |             
 >  475 |             & : (T -> _)
 >  476 |           )
 >  477 |             super { |*__temp_1063| yield *__temp_1063 }
 >  478 |           end
 >  479 |         
 >  480 |           default_stub  def count(
 >  481 |             
 >  482 |             
 >  483 |             & : (T ->)
 >  484 |           ) : Int32
 >  485 |             super { |*__temp_1063| yield *__temp_1063 }
 >  486 |           end
 >  487 |         
 >  488 |           default_stub  def count(
 >  489 |             item, 
 >  490 |             
 >  491 |             
 >  492 |           ) : Int32
 >  493 |             super
 >  494 |           end
 >  495 |         
 >  496 |           default_stub  def cycle(
 >  497 |             n, 
 >  498 |             
 >  499 |             & : (T ->)
 >  500 |           ) : Nil
 >  501 |             super { |*__temp_1063| yield *__temp_1063 }
 >  502 |           end
 >  503 |         
 >  504 |           default_stub  def cycle(
 >  505 |             
 >  506 |             
 >  507 |             & : (T ->)
 >  508 |           ) : Nil
 >  509 |             super { |*__temp_1063| yield *__temp_1063 }
 >  510 |           end
 >  511 |         
 >  512 |           default_stub  def each_cons(
 >  513 |             count : Int, reuse = false, 
 >  514 |             
 >  515 |             &
 >  516 |           )
 >  517 |             super { |*__temp_1063| yield *__temp_1063 }
 >  518 |           end
 >  519 |         
 >  520 |           default_stub private def each_cons_internal(
 >  521 |             count : Int, reuse, cons, 
 >  522 |             
 >  523 |             &
 >  524 |           )
 >  525 |             super { |*__temp_1063| yield *__temp_1063 }
 >  526 |           end
 >  527 |         
 >  528 |           default_stub  def each_cons_pair(
 >  529 |             
 >  530 |             
 >  531 |             & : (T, T ->)
 >  532 |           ) : Nil
 >  533 |             super { |*__temp_1063| yield *__temp_1063 }
 >  534 |           end
 >  535 |         
 >  536 |           default_stub  def each_slice(
 >  537 |             count : Int, reuse = false, 
 >  538 |             
 >  539 |             &
 >  540 |           )
 >  541 |             super { |*__temp_1063| yield *__temp_1063 }
 >  542 |           end
 >  543 |         
 >  544 |           default_stub private def each_slice_internal(
 >  545 |             count : Int, type, reuse, 
 >  546 |             
 >  547 |             &
 >  548 |           )
 >  549 |             super { |*__temp_1063| yield *__temp_1063 }
 >  550 |           end
 >  551 |         
 >  552 |           default_stub  def each_with_index(
 >  553 |             offset = 0, 
 >  554 |             
 >  555 |             &
 >  556 |           )
 >  557 |             super { |*__temp_1063| yield *__temp_1063 }
 >  558 |           end
 >  559 |         
 >  560 |           default_stub  def each_with_object(
 >  561 |             obj : U, 
 >  562 |             
 >  563 |             & : (T, U ->)
 >  564 |           ) : U forall U
 >  565 |             super { |*__temp_1063| yield *__temp_1063 }
 >  566 |           end
 >  567 |         
 >  568 |           default_stub  def find(
 >  569 |             if_none = nil, 
 >  570 |             
 >  571 |             & : (T ->)
 >  572 |           )
 >  573 |             super { |*__temp_1063| yield *__temp_1063 }
 >  574 |           end
 >  575 |         
 >  576 |           default_stub  def find!(
 >  577 |             
 >  578 |             
 >  579 |             & : (T ->)
 >  580 |           ) : T
 >  581 |             super { |*__temp_1063| yield *__temp_1063 }
 >  582 |           end
 >  583 |         
 >  584 |           default_stub  def first(
 >  585 |             
 >  586 |             
 >  587 |             &
 >  588 |           )
 >  589 |             super { |*__temp_1063| yield *__temp_1063 }
 >  590 |           end
 >  591 |         
 >  592 |           default_stub  def first(
 >  593 |             count : Int, 
 >  594 |             
 >  595 |             
 >  596 |           ) : Array(T)
 >  597 |             super
 >  598 |           end
 >  599 |         
 >  600 |           default_stub  def first(
 >  601 |             
 >  602 |             
 >  603 |             
 >  604 |           ) : T
 >  605 |             super
 >  606 |           end
 >  607 |         
 >  608 |           default_stub  def first?(
 >  609 |             
 >  610 |             
 >  611 |             
 >  612 |           ) : T | ::Nil
 >  613 |             super
 >  614 |           end
 >  615 |         
 >  616 |           default_stub  def flat_map(
 >  617 |             
 >  618 |             
 >  619 |             & : (T -> _)
 >  620 |           )
 >  621 |             super { |*__temp_1063| yield *__temp_1063 }
 >  622 |           end
 >  623 |         
 >  624 |           default_stub private def flat_map_type(
 >  625 |             elem, 
 >  626 |             
 >  627 |             
 >  628 |           )
 >  629 |             super
 >  630 |           end
 >  631 |         
 >  632 |           default_stub  def group_by(
 >  633 |             
 >  634 |             
 >  635 |             & : (T -> U)
 >  636 |           ) forall U
 >  637 |             super { |*__temp_1063| yield *__temp_1063 }
 >  638 |           end
 >  639 |         
 >  640 |           default_stub  def in_groups_of(
 >  641 |             size : Int, filled_up_with : U = nil, 
 >  642 |             
 >  643 |             
 >  644 |           ) forall U
 >  645 |             super
 >  646 |           end
 >  647 |         
 >  648 |           default_stub  def in_groups_of(
 >  649 |             size : Int, filled_up_with : U = nil, reuse = false, 
 >  650 |             
 >  651 |             &
 >  652 |           ) forall U
 >  653 |             super { |*__temp_1063| yield *__temp_1063 }
 >  654 |           end
 >  655 |         
 >  656 |           default_stub  def includes?(
 >  657 |             obj, 
 >  658 |             
 >  659 |             
 >  660 |           ) : Bool
 >  661 |             super
 >  662 |           end
 >  663 |         
 >  664 |           default_stub  def index(
 >  665 |             
 >  666 |             
 >  667 |             & : (T ->)
 >  668 |           ) : Int32 | ::Nil
 >  669 |             super { |*__temp_1063| yield *__temp_1063 }
 >  670 |           end
 >  671 |         
 >  672 |           default_stub  def index(
 >  673 |             obj, 
 >  674 |             
 >  675 |             
 >  676 |           ) : Int32 | ::Nil
 >  677 |             super
 >  678 |           end
 >  679 |         
 >  680 |           default_stub  def index!(
 >  681 |             
 >  682 |             
 >  683 |             & : (T ->)
 >  684 |           ) : Int32
 >  685 |             super { |*__temp_1063| yield *__temp_1063 }
 >  686 |           end
 >  687 |         
 >  688 |           default_stub  def index!(
 >  689 |             obj, 
 >  690 |             
 >  691 |             
 >  692 |           ) : Int32
 >  693 |             super
 >  694 |           end
 >  695 |         
 >  696 |           default_stub  def index_by(
 >  697 |             
 >  698 |             
 >  699 |             & : (T -> U)
 >  700 |           ) : Hash(U, T) forall U
 >  701 |             super { |*__temp_1063| yield *__temp_1063 }
 >  702 |           end
 >  703 |         
 >  704 |           default_stub  def reduce(
 >  705 |             memo, 
 >  706 |             
 >  707 |             &
 >  708 |           )
 >  709 |             super { |*__temp_1063| yield *__temp_1063 }
 >  710 |           end
 >  711 |         
 >  712 |           default_stub  def reduce(
 >  713 |             
 >  714 |             
 >  715 |             &
 >  716 |           )
 >  717 |             super { |*__temp_1063| yield *__temp_1063 }
 >  718 |           end
 >  719 |         
 >  720 |           default_stub  def reduce?(
 >  721 |             
 >  722 |             
 >  723 |             &
 >  724 |           )
 >  725 |             super { |*__temp_1063| yield *__temp_1063 }
 >  726 |           end
 >  727 |         
 >  728 |           default_stub  def accumulate(
 >  729 |             initial : U, 
 >  730 |             
 >  731 |             
 >  732 |           ) : Array(U) forall U
 >  733 |             super
 >  734 |           end
 >  735 |         
 >  736 |           default_stub  def accumulate(
 >  737 |             
 >  738 |             
 >  739 |             
 >  740 |           ) : Array(T)
 >  741 |             super
 >  742 |           end
 >  743 |         
 >  744 |           default_stub  def accumulate(
 >  745 |             initial : U, 
 >  746 |             
 >  747 |             &block : (U, T -> U)
 >  748 |           ) : Array(U) forall U
 >  749 |             super { |*__temp_1063| yield *__temp_1063 }
 >  750 |           end
 >  751 |         
 >  752 |           default_stub  def accumulate(
 >  753 |             
 >  754 |             
 >  755 |             &block : (T, T -> T)
 >  756 |           ) : Array(T)
 >  757 |             super { |*__temp_1063| yield *__temp_1063 }
 >  758 |           end
 >  759 |         
 >  760 |           default_stub  def join(
 >  761 |             io : IO, separator = "", 
 >  762 |             
 >  763 |             
 >  764 |           ) : Nil
 >  765 |             super
 >  766 |           end
 >  767 |         
 >  768 |           default_stub  def join(
 >  769 |             separator, io : IO, 
 >  770 |             
 >  771 |             
 >  772 |           ) : Nil
 >  773 |             super
 >  774 |           end
 >  775 |         
 >  776 |           default_stub  def join(
 >  777 |             separator = "", 
 >  778 |             
 >  779 |             
 >  780 |           ) : String
 >  781 |             super
 >  782 |           end
 >  783 |         
 >  784 |           default_stub  def join(
 >  785 |             io : IO, separator = "", 
 >  786 |             
 >  787 |             & : (T, IO ->)
 >  788 |           )
 >  789 |             super { |*__temp_1063| yield *__temp_1063 }
 >  790 |           end
 >  791 |         
 >  792 |           default_stub  def join(
 >  793 |             separator, io : IO, 
 >  794 |             
 >  795 |             &
 >  796 |           )
 >  797 |             super { |*__temp_1063| yield *__temp_1063 }
 >  798 |           end
 >  799 |         
 >  800 |           default_stub  def join(
 >  801 |             separator = "", 
 >  802 |             
 >  803 |             & : (T ->)
 >  804 |           )
 >  805 |             super { |*__temp_1063| yield *__temp_1063 }
 >  806 |           end
 >  807 |         
 >  808 |           default_stub  def map(
 >  809 |             
 >  810 |             
 >  811 |             & : (T -> U)
 >  812 |           ) : Array(U) forall U
 >  813 |             super { |*__temp_1063| yield *__temp_1063 }
 >  814 |           end
 >  815 |         
 >  816 |           default_stub  def map_with_index(
 >  817 |             offset = 0, 
 >  818 |             
 >  819 |             & : (T, Int32 -> U)
 >  820 |           ) : Array(U) forall U
 >  821 |             super { |*__temp_1063| yield *__temp_1063 }
 >  822 |           end
 >  823 |         
 >  824 |           default_stub  def max(
 >  825 |             
 >  826 |             
 >  827 |             
 >  828 |           ) : T
 >  829 |             super
 >  830 |           end
 >  831 |         
 >  832 |           default_stub  def max?(
 >  833 |             
 >  834 |             
 >  835 |             
 >  836 |           ) : T | ::Nil
 >  837 |             super
 >  838 |           end
 >  839 |         
 >  840 |           default_stub  def max_by(
 >  841 |             
 >  842 |             
 >  843 |             & : (T -> U)
 >  844 |           ) : T forall U
 >  845 |             super { |*__temp_1063| yield *__temp_1063 }
 >  846 |           end
 >  847 |         
 >  848 |           default_stub  def max_by?(
 >  849 |             
 >  850 |             
 >  851 |             & : (T -> U)
 >  852 |           ) : T | ::Nil forall U
 >  853 |             super { |*__temp_1063| yield *__temp_1063 }
 >  854 |           end
 >  855 |         
 >  856 |           default_stub private def max_by_internal(
 >  857 |             
 >  858 |             
 >  859 |             & : (T -> U)
 >  860 |           ) forall U
 >  861 |             super { |*__temp_1063| yield *__temp_1063 }
 >  862 |           end
 >  863 |         
 >  864 |           default_stub  def max_of(
 >  865 |             
 >  866 |             
 >  867 |             & : (T -> U)
 >  868 |           ) : U forall U
 >  869 |             super { |*__temp_1063| yield *__temp_1063 }
 >  870 |           end
 >  871 |         
 >  872 |           default_stub  def max_of?(
 >  873 |             
 >  874 |             
 >  875 |             & : (T -> U)
 >  876 |           ) : U | ::Nil forall U
 >  877 |             super { |*__temp_1063| yield *__temp_1063 }
 >  878 |           end
 >  879 |         
 >  880 |           default_stub private def max_of_internal(
 >  881 |             
 >  882 |             
 >  883 |             & : (T -> U)
 >  884 |           ) forall U
 >  885 |             super { |*__temp_1063| yield *__temp_1063 }
 >  886 |           end
 >  887 |         
 >  888 |           default_stub  def min(
 >  889 |             
 >  890 |             
 >  891 |             
 >  892 |           ) : T
 >  893 |             super
 >  894 |           end
 >  895 |         
 >  896 |           default_stub  def min?(
 >  897 |             
 >  898 |             
 >  899 |             
 >  900 |           ) : T | ::Nil
 >  901 |             super
 >  902 |           end
 >  903 |         
 >  904 |           default_stub  def min_by(
 >  905 |             
 >  906 |             
 >  907 |             & : (T -> U)
 >  908 |           ) : T forall U
 >  909 |             super { |*__temp_1063| yield *__temp_1063 }
 >  910 |           end
 >  911 |         
 >  912 |           default_stub  def min_by?(
 >  913 |             
 >  914 |             
 >  915 |             & : (T -> U)
 >  916 |           ) : T | ::Nil forall U
 >  917 |             super { |*__temp_1063| yield *__temp_1063 }
 >  918 |           end
 >  919 |         
 >  920 |           default_stub private def min_by_internal(
 >  921 |             
 >  922 |             
 >  923 |             & : (T -> U)
 >  924 |           ) forall U
 >  925 |             super { |*__temp_1063| yield *__temp_1063 }
 >  926 |           end
 >  927 |         
 >  928 |           default_stub  def min_of(
 >  929 |             
 >  930 |             
 >  931 |             & : (T -> U)
 >  932 |           ) : U forall U
 >  933 |             super { |*__temp_1063| yield *__temp_1063 }
 >  934 |           end
 >  935 |         
 >  936 |           default_stub  def min_of?(
 >  937 |             
 >  938 |             
 >  939 |             & : (T -> U)
 >  940 |           ) : U | ::Nil forall U
 >  941 |             super { |*__temp_1063| yield *__temp_1063 }
 >  942 |           end
 >  943 |         
 >  944 |           default_stub private def min_of_internal(
 >  945 |             
 >  946 |             
 >  947 |             & : (T -> U)
 >  948 |           ) forall U
 >  949 |             super { |*__temp_1063| yield *__temp_1063 }
 >  950 |           end
 >  951 |         
 >  952 |           default_stub  def minmax(
 >  953 |             
 >  954 |             
 >  955 |             
 >  956 |           ) : ::Tuple(T, T)
 >  957 |             super
 >  958 |           end
 >  959 |         
 >  960 |           default_stub  def minmax?(
 >  961 |             
 >  962 |             
 >  963 |             
 >  964 |           ) : ::Tuple(T | ::Nil, T | ::Nil)
 >  965 |             super
 >  966 |           end
 >  967 |         
 >  968 |           default_stub  def minmax_by(
 >  969 |             
 >  970 |             
 >  971 |             & : (T -> U)
 >  972 |           ) : ::Tuple(T, T) forall U
 >  973 |             super { |*__temp_1063| yield *__temp_1063 }
 >  974 |           end
 >  975 |         
 >  976 |           default_stub  def minmax_by?(
 >  977 |             
 >  978 |             
 >  979 |             & : (T -> U)
 >  980 |           ) : ::Tuple(T, T) | ::Tuple(Nil, Nil) forall U
 >  981 |             super { |*__temp_1063| yield *__temp_1063 }
 >  982 |           end
 >  983 |         
 >  984 |           default_stub private def minmax_by_internal(
 >  985 |             
 >  986 |             
 >  987 |             & : (T -> U)
 >  988 |           ) forall U
 >  989 |             super { |*__temp_1063| yield *__temp_1063 }
 >  990 |           end
 >  991 |         
 >  992 |           default_stub  def minmax_of(
 >  993 |             
 >  994 |             
 >  995 |             & : (T -> U)
 >  996 |           ) : ::Tuple(U, U) forall U
 >  997 |             super { |*__temp_1063| yield *__temp_1063 }
 >  998 |           end
 >  999 |         
 > 1000 |           default_stub  def minmax_of?(
 > 1001 |             
 > 1002 |             
 > 1003 |             & : (T -> U)
 > 1004 |           ) : ::Tuple(U, U) | ::Tuple(Nil, Nil) forall U
 > 1005 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1006 |           end
 > 1007 |         
 > 1008 |           default_stub private def minmax_of_internal(
 > 1009 |             
 > 1010 |             
 > 1011 |             & : (T -> U)
 > 1012 |           ) forall U
 > 1013 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1014 |           end
 > 1015 |         
 > 1016 |           default_stub private def compare_or_raise(
 > 1017 |             value, memo, 
 > 1018 |             
 > 1019 |             
 > 1020 |           )
 > 1021 |             super
 > 1022 |           end
 > 1023 |         
 > 1024 |           default_stub  def none?(
 > 1025 |             
 > 1026 |             
 > 1027 |             & : (T ->)
 > 1028 |           ) : Bool
 > 1029 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1030 |           end
 > 1031 |         
 > 1032 |           default_stub  def none?(
 > 1033 |             pattern, 
 > 1034 |             
 > 1035 |             
 > 1036 |           ) : Bool
 > 1037 |             super
 > 1038 |           end
 > 1039 |         
 > 1040 |           default_stub  def none?(
 > 1041 |             
 > 1042 |             
 > 1043 |             
 > 1044 |           ) : Bool
 > 1045 |             super
 > 1046 |           end
 > 1047 |         
 > 1048 |           default_stub  def one?(
 > 1049 |             
 > 1050 |             
 > 1051 |             & : (T ->)
 > 1052 |           ) : Bool
 > 1053 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1054 |           end
 > 1055 |         
 > 1056 |           default_stub  def one?(
 > 1057 |             pattern, 
 > 1058 |             
 > 1059 |             
 > 1060 |           ) : Bool
 > 1061 |             super
 > 1062 |           end
 > 1063 |         
 > 1064 |           default_stub  def one?(
 > 1065 |             
 > 1066 |             
 > 1067 |             
 > 1068 |           ) : Bool
 > 1069 |             super
 > 1070 |           end
 > 1071 |         
 > 1072 |           default_stub  def partition(
 > 1073 |             
 > 1074 |             
 > 1075 |             & : (T ->)
 > 1076 |           ) : ::Tuple(Array(T), Array(T))
 > 1077 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1078 |           end
 > 1079 |         
 > 1080 |           default_stub  def reject(
 > 1081 |             
 > 1082 |             
 > 1083 |             & : (T ->)
 > 1084 |           )
 > 1085 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1086 |           end
 > 1087 |         
 > 1088 |           default_stub  def reject(
 > 1089 |             type : U.class, 
 > 1090 |             
 > 1091 |             
 > 1092 |           ) forall U
 > 1093 |             super
 > 1094 |           end
 > 1095 |         
 > 1096 |           default_stub  def reject(
 > 1097 |             pattern, 
 > 1098 |             
 > 1099 |             
 > 1100 |           ) : Array(T)
 > 1101 |             super
 > 1102 |           end
 > 1103 |         
 > 1104 |           default_stub  def sample(
 > 1105 |             n : Int, random = Random::DEFAULT, 
 > 1106 |             
 > 1107 |             
 > 1108 |           ) : Array(T)
 > 1109 |             super
 > 1110 |           end
 > 1111 |         
 > 1112 |           default_stub  def sample(
 > 1113 |             random = Random::DEFAULT, 
 > 1114 |             
 > 1115 |             
 > 1116 |           ) : T
 > 1117 |             super
 > 1118 |           end
 > 1119 |         
 > 1120 |           default_stub  def select(
 > 1121 |             
 > 1122 |             
 > 1123 |             & : (T ->)
 > 1124 |           )
 > 1125 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1126 |           end
 > 1127 |         
 > 1128 |           default_stub  def select(
 > 1129 |             type : U.class, 
 > 1130 |             
 > 1131 |             
 > 1132 |           ) : Array(U) forall U
 > 1133 |             super
 > 1134 |           end
 > 1135 |         
 > 1136 |           default_stub  def select(
 > 1137 |             pattern, 
 > 1138 |             
 > 1139 |             
 > 1140 |           ) : Array(T)
 > 1141 |             super
 > 1142 |           end
 > 1143 |         
 > 1144 |           default_stub  def size(
 > 1145 |             
 > 1146 |             
 > 1147 |             
 > 1148 |           ) : Int32
 > 1149 |             super
 > 1150 |           end
 > 1151 |         
 > 1152 |           default_stub  def empty?(
 > 1153 |             
 > 1154 |             
 > 1155 |             
 > 1156 |           ) : Bool
 > 1157 |             super
 > 1158 |           end
 > 1159 |         
 > 1160 |           default_stub  def skip(
 > 1161 |             count : Int, 
 > 1162 |             
 > 1163 |             
 > 1164 |           )
 > 1165 |             super
 > 1166 |           end
 > 1167 |         
 > 1168 |           default_stub  def skip_while(
 > 1169 |             
 > 1170 |             
 > 1171 |             & : (T ->)
 > 1172 |           ) : Array(T)
 > 1173 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1174 |           end
 > 1175 |         
 > 1176 |           default_stub  def sum(
 > 1177 |             initial, 
 > 1178 |             
 > 1179 |             
 > 1180 |           )
 > 1181 |             super
 > 1182 |           end
 > 1183 |         
 > 1184 |           default_stub  def sum(
 > 1185 |             
 > 1186 |             
 > 1187 |             
 > 1188 |           )
 > 1189 |             super
 > 1190 |           end
 > 1191 |         
 > 1192 |           default_stub  def sum(
 > 1193 |             initial, 
 > 1194 |             
 > 1195 |             & : (T ->)
 > 1196 |           )
 > 1197 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1198 |           end
 > 1199 |         
 > 1200 |           default_stub  def sum(
 > 1201 |             
 > 1202 |             
 > 1203 |             & : (T ->)
 > 1204 |           )
 > 1205 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1206 |           end
 > 1207 |         
 > 1208 |           default_stub private def additive_identity(
 > 1209 |             reflect, 
 > 1210 |             
 > 1211 |             
 > 1212 |           )
 > 1213 |             super
 > 1214 |           end
 > 1215 |         
 > 1216 |           default_stub  def product(
 > 1217 |             initial : Number, 
 > 1218 |             
 > 1219 |             
 > 1220 |           )
 > 1221 |             super
 > 1222 |           end
 > 1223 |         
 > 1224 |           default_stub  def product(
 > 1225 |             
 > 1226 |             
 > 1227 |             
 > 1228 |           )
 > 1229 |             super
 > 1230 |           end
 > 1231 |         
 > 1232 |           default_stub  def product(
 > 1233 |             initial : Number, 
 > 1234 |             
 > 1235 |             & : (T ->)
 > 1236 |           )
 > 1237 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1238 |           end
 > 1239 |         
 > 1240 |           default_stub  def product(
 > 1241 |             
 > 1242 |             
 > 1243 |             & : (T -> _)
 > 1244 |           )
 > 1245 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1246 |           end
 > 1247 |         
 > 1248 |           default_stub  def take_while(
 > 1249 |             
 > 1250 |             
 > 1251 |             & : (T ->)
 > 1252 |           ) : Array(T)
 > 1253 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1254 |           end
 > 1255 |         
 > 1256 |           default_stub  def tally_by(
 > 1257 |             hash, 
 > 1258 |             
 > 1259 |             &
 > 1260 |           )
 > 1261 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1262 |           end
 > 1263 |         
 > 1264 |           default_stub  def tally_by(
 > 1265 |             
 > 1266 |             
 > 1267 |             &block : (T -> U)
 > 1268 |           ) : Hash(U, Int32) forall U
 > 1269 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1270 |           end
 > 1271 |         
 > 1272 |           default_stub  def tally(
 > 1273 |             hash, 
 > 1274 |             
 > 1275 |             
 > 1276 |           )
 > 1277 |             super
 > 1278 |           end
 > 1279 |         
 > 1280 |           default_stub  def tally(
 > 1281 |             
 > 1282 |             
 > 1283 |             
 > 1284 |           ) : Hash(T, Int32)
 > 1285 |             super
 > 1286 |           end
 > 1287 |         
 > 1288 |           default_stub  def to_a(
 > 1289 |             
 > 1290 |             
 > 1291 |             
 > 1292 |           )
 > 1293 |             super
 > 1294 |           end
 > 1295 |         
 > 1296 |           default_stub  def to_h(
 > 1297 |             
 > 1298 |             
 > 1299 |             
 > 1300 |           )
 > 1301 |             super
 > 1302 |           end
 > 1303 |         
 > 1304 |           default_stub  def to_h(
 > 1305 |             
 > 1306 |             
 > 1307 |             & : (T -> Tuple(K, V))
 > 1308 |           ) forall K, V
 > 1309 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1310 |           end
 > 1311 |         
 > 1312 |           default_stub  def zip(
 > 1313 |             *others : Indexable | Iterable | Iterator, 
 > 1314 |             
 > 1315 |             &
 > 1316 |           )
 > 1317 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1318 |           end
 > 1319 |         
 > 1320 |           default_stub  def zip(
 > 1321 |             *others : Indexable | Iterable | Iterator, 
 > 1322 |             
 > 1323 |             
 > 1324 |           )
 > 1325 |             super
 > 1326 |           end
 > 1327 |         
 > 1328 |           default_stub  def zip?(
 > 1329 |             *others : Indexable | Iterable | Iterator, 
 > 1330 |             
 > 1331 |             &
 > 1332 |           )
 > 1333 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1334 |           end
 > 1335 |         
 > 1336 |           default_stub  def zip?(
 > 1337 |             *others : Indexable | Iterable | Iterator, 
 > 1338 |             
 > 1339 |             
 > 1340 |           )
 > 1341 |             super
 > 1342 |           end
 > 1343 |         
 > 1344 |           default_stub  def to_set(
 > 1345 |             
 > 1346 |             
 > 1347 |             
 > 1348 |           ) : Set(T)
 > 1349 |             super
 > 1350 |           end
 > 1351 |         
 > 1352 | 
 > 1353 |         
 > 1354 |           default_stub  def self.zip(
 > 1355 |             main, others : U, 
 > 1356 |             
 > 1357 |             &
 > 1358 |           ) forall U
 > 1359 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1360 |           end
 > 1361 |         
 > 1362 |           default_stub  def self.zip?(
 > 1363 |             main, others : U, 
 > 1364 |             
 > 1365 |             &
 > 1366 |           ) forall U
 > 1367 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1368 |           end
 > 1369 |         
 > 1370 |           default_stub  def self.element_type(
 > 1371 |             x, 
 > 1372 |             
 > 1373 |             
 > 1374 |           )
 > 1375 |             super
 > 1376 |           end
 > 1377 |         
 > 1378 |       
 > 1379 | 
 > 1380 |       
 > 1381 |         default_stub  def byte_set(
 > 1382 |           
 > 1383 |           
 > 1384 |           
 > 1385 |         ) : Set(Int32)
 > 1386 |           
 > 1387 |             super
 > 1388 |           end
 > 1389 |         
 > 1390 |       
 > 1391 |         default_stub  def char_set(
 > 1392 |           
 > 1393 |           
 > 1394 |           
 > 1395 |         ) : Set(Char)
 > 1396 |           
 > 1397 |             super
 > 1398 |           end
 > 1399 |         
 > 1400 |       
 > 1401 |         default_stub  def bytes(
 > 1402 |           
 > 1403 |           
 > 1404 |           
 > 1405 |         ) : Array(Int32)
 > 1406 |           
 > 1407 |             super
 > 1408 |           end
 > 1409 |         
 > 1410 |       
 > 1411 |         default_stub  def chars(
 > 1412 |           
 > 1413 |           
 > 1414 |           
 > 1415 |         ) : Array(Char)
 > 1416 |           
 > 1417 |             super
 > 1418 |           end
 > 1419 |         
 > 1420 |       
 > 1421 |         default_stub  def <<(
 > 1422 |           value : Char, 
 > 1423 |           
 > 1424 |           
 > 1425 |         ) : CharSet
 > 1426 |           
 > 1427 |             super
 > 1428 |           end
 > 1429 |         
 > 1430 |       
 > 1431 |         default_stub  def <<(
 > 1432 |           value : UInt8, 
 > 1433 |           
 > 1434 |           
 > 1435 |         ) : CharSet
 > 1436 |           
 > 1437 |             super
 > 1438 |           end
 > 1439 |         
 > 1440 |       
 > 1441 |         default_stub  def <<(
 > 1442 |           value : Int32, 
 > 1443 |           
 > 1444 |           
 > 1445 |         ) : CharSet
 > 1446 |           
 > 1447 |             super
 > 1448 |           end
 > 1449 |         
 > 1450 |       
 > 1451 |         default_stub  def includes_byte?(
 > 1452 |           byte : UInt8, 
 > 1453 |           
 > 1454 |           
 > 1455 |         ) : Bool
 > 1456 |           
 > 1457 |             super
 > 1458 |           end
 > 1459 |         
 > 1460 |       
 > 1461 |         default_stub  def includes_byte?(
 > 1462 |           byte : Int32, 
 > 1463 |           
 > 1464 |           
 > 1465 |         ) : Bool
 > 1466 |           
 > 1467 |             super
 > 1468 |           end
 > 1469 |         
 > 1470 |       
 > 1471 |         default_stub  def includes_char?(
 > 1472 |           char : Char, 
 > 1473 |           
 > 1474 |           
 > 1475 |         ) : Bool
 > 1476 |           
 > 1477 |             super
 > 1478 |           end
 > 1479 |         
 > 1480 |       
 > 1481 |         default_stub  def includes?(
 > 1482 |           byte : UInt8 | Int32, 
 > 1483 |           
 > 1484 |           
 > 1485 |         ) : Bool
 > 1486 |           
 > 1487 |             super
 > 1488 |           end
 > 1489 |         
 > 1490 |       
 > 1491 |         default_stub  def includes?(
 > 1492 |           char : Char, 
 > 1493 |           
 > 1494 |           
 > 1495 |         ) : Bool
 > 1496 |           
 > 1497 |             super
 > 1498 |           end
 > 1499 |         
 > 1500 |       
 > 1501 |         default_stub  def each_byte(
 > 1502 |           
 > 1503 |           
 > 1504 |           &block : (Int32 ->)
 > 1505 |         )
 > 1506 |           
 > 1507 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1508 |           end
 > 1509 |         
 > 1510 |       
 > 1511 |         default_stub  def each_char(
 > 1512 |           
 > 1513 |           
 > 1514 |           &block : (Char ->)
 > 1515 |         )
 > 1516 |           
 > 1517 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1518 |           end
 > 1519 |         
 > 1520 |       
 > 1521 |         default_stub  def each(
 > 1522 |           *args, 
 > 1523 |           **options, 
 > 1524 |           
 > 1525 |         )
 > 1526 |           
 > 1527 |             super
 > 1528 |           end
 > 1529 |         
 > 1530 |       
 > 1531 |         default_stub  def each(
 > 1532 |           *args, 
 > 1533 |           **options, 
 > 1534 |           &
 > 1535 |         )
 > 1536 |           
 > 1537 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1538 |           end
 > 1539 |         
 > 1540 |       
 > 1541 |         default_stub  def select_bytes(
 > 1542 |           
 > 1543 |           
 > 1544 |           &block : (Int32 -> Bool)
 > 1545 |         ) : Array(Int32)
 > 1546 |           
 > 1547 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1548 |           end
 > 1549 |         
 > 1550 |       
 > 1551 |         default_stub  def select_chars(
 > 1552 |           
 > 1553 |           
 > 1554 |           &block : (Char -> Bool)
 > 1555 |         ) : Array(Char)
 > 1556 |           
 > 1557 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1558 |           end
 > 1559 |         
 > 1560 |       
 > 1561 |         default_stub  def select(
 > 1562 |           *args, 
 > 1563 |           **options, 
 > 1564 |           
 > 1565 |         )
 > 1566 |           
 > 1567 |             super
 > 1568 |           end
 > 1569 |         
 > 1570 |       
 > 1571 |         default_stub  def select(
 > 1572 |           *args, 
 > 1573 |           **options, 
 > 1574 |           &
 > 1575 |         )
 > 1576 |           
 > 1577 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1578 |           end
 > 1579 |         
 > 1580 |       
 > 1581 |         default_stub  def map_bytes(
 > 1582 |           
 > 1583 |           
 > 1584 |           &block : (Int32 -> T)
 > 1585 |         ) : Array(T) forall T
 > 1586 |           
 > 1587 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1588 |           end
 > 1589 |         
 > 1590 |       
 > 1591 |         default_stub  def map_chars(
 > 1592 |           
 > 1593 |           
 > 1594 |           &block : (Char -> T)
 > 1595 |         ) : Array(T) forall T
 > 1596 |           
 > 1597 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1598 |           end
 > 1599 |         
 > 1600 |       
 > 1601 |         default_stub  def map(
 > 1602 |           *args, 
 > 1603 |           **options, 
 > 1604 |           
 > 1605 |         )
 > 1606 |           
 > 1607 |             super
 > 1608 |           end
 > 1609 |         
 > 1610 |       
 > 1611 |         default_stub  def map(
 > 1612 |           *args, 
 > 1613 |           **options, 
 > 1614 |           &
 > 1615 |         )
 > 1616 |           
 > 1617 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1618 |           end
 > 1619 |         
 > 1620 |       
 > 1621 |         default_stub  def random_byte(
 > 1622 |           random = Random::DEFAULT, 
 > 1623 |           
 > 1624 |           
 > 1625 |         ) : Int32
 > 1626 |           
 > 1627 |             super
 > 1628 |           end
 > 1629 |         
 > 1630 |       
 > 1631 |         default_stub  def random_char(
 > 1632 |           random = Random::DEFAULT, 
 > 1633 |           
 > 1634 |           
 > 1635 |         ) : Char
 > 1636 |           
 > 1637 |             super
 > 1638 |           end
 > 1639 |         
 > 1640 |       
 > 1641 |         default_stub  def each_random_byte(
 > 1642 |           n : Int, 
 > 1643 |           
 > 1644 |           &block : (Int32 ->)
 > 1645 |         )
 > 1646 |           
 > 1647 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1648 |           end
 > 1649 |         
 > 1650 |       
 > 1651 |         default_stub  def each_random_char(
 > 1652 |           n : Int, 
 > 1653 |           
 > 1654 |           &block : (Char ->)
 > 1655 |         )
 > 1656 |           
 > 1657 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1658 |           end
 > 1659 |         
 > 1660 |       
 > 1661 |         default_stub  def random_bytes(
 > 1662 |           length : Int, random = Random::DEFAULT, 
 > 1663 |           
 > 1664 |           
 > 1665 |         ) : Array(Int32)
 > 1666 |           
 > 1667 |             super
 > 1668 |           end
 > 1669 |         
 > 1670 |       
 > 1671 |         default_stub  def random_bytes(
 > 1672 |           lengths : Array(Int) | Range(Int, Int), random = Random::DEFAULT, 
 > 1673 |           
 > 1674 |           
 > 1675 |         ) : Array(Int32)
 > 1676 |           
 > 1677 |             super
 > 1678 |           end
 > 1679 |         
 > 1680 |       
 > 1681 |         default_stub  def random_chars(
 > 1682 |           length : Int, random = Random::DEFAULT, 
 > 1683 |           
 > 1684 |           
 > 1685 |         ) : Array(Char)
 > 1686 |           
 > 1687 |             super
 > 1688 |           end
 > 1689 |         
 > 1690 |       
 > 1691 |         default_stub  def random_chars(
 > 1692 |           lengths : Array(Int) | Range(Int, Int), random = Random::DEFAULT, 
 > 1693 |           
 > 1694 |           
 > 1695 |         ) : Array(Char)
 > 1696 |           
 > 1697 |             super
 > 1698 |           end
 > 1699 |         
 > 1700 |       
 > 1701 |         default_stub  def random_string(
 > 1702 |           length : Int | Array(Int) | Range(Int, Int), 
 > 1703 |           
 > 1704 |           
 > 1705 |         ) : String
 > 1706 |           
 > 1707 |             super
 > 1708 |           end
 > 1709 |         
 > 1710 |       
 > 1711 |         default_stub  def random_distinct_bytes(
 > 1712 |           length : Int, 
 > 1713 |           
 > 1714 |           
 > 1715 |         ) : Array(Int32)
 > 1716 |           
 > 1717 |             super
 > 1718 |           end
 > 1719 |         
 > 1720 |       
 > 1721 |         default_stub  def random_distinct_bytes(
 > 1722 |           length : Array(Int), random = Random::DEFAULT, 
 > 1723 |           
 > 1724 |           
 > 1725 |         ) : Array(Int32)
 > 1726 |           
 > 1727 |             super
 > 1728 |           end
 > 1729 |         
 > 1730 |       
 > 1731 |         default_stub  def random_distinct_bytes(
 > 1732 |           length : Range(Int, Int), 
 > 1733 |           
 > 1734 |           
 > 1735 |         ) : Array(Int32)
 > 1736 |           
 > 1737 |             super
 > 1738 |           end
 > 1739 |         
 > 1740 |       
 > 1741 |         default_stub  def random_distinct_chars(
 > 1742 |           length : Int, 
 > 1743 |           
 > 1744 |           
 > 1745 |         ) : Array(Char)
 > 1746 |           
 > 1747 |             super
 > 1748 |           end
 > 1749 |         
 > 1750 |       
 > 1751 |         default_stub  def random_distinct_chars(
 > 1752 |           length : Array(Int), random = Random::DEFAULT, 
 > 1753 |           
 > 1754 |           
 > 1755 |         ) : Array(Char)
 > 1756 |           
 > 1757 |             super
 > 1758 |           end
 > 1759 |         
 > 1760 |       
 > 1761 |         default_stub  def random_distinct_chars(
 > 1762 |           length : Range(Int, Int), 
 > 1763 |           
 > 1764 |           
 > 1765 |         ) : Array(Char)
 > 1766 |           
 > 1767 |             super
 > 1768 |           end
 > 1769 |         
 > 1770 |       
 > 1771 |         default_stub  def random_distinct_string(
 > 1772 |           length : Int | Array(Int) | Range(Int, Int), 
 > 1773 |           
 > 1774 |           
 > 1775 |         ) : String
 > 1776 |           
 > 1777 |             super
 > 1778 |           end
 > 1779 |         
 > 1780 |       
 > 1781 |         default_stub  def each_substring_with_index(
 > 1782 |           data : String, min_length : Int = 4, 
 > 1783 |           
 > 1784 |           &block : (String, Int32 ->)
 > 1785 |         )
 > 1786 |           
 > 1787 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1788 |           end
 > 1789 |         
 > 1790 |       
 > 1791 |         default_stub  def substrings_with_indexes(
 > 1792 |           data : String, min_length : Int = 4, 
 > 1793 |           
 > 1794 |           
 > 1795 |         ) : Array(Tuple(String, Int32))
 > 1796 |           
 > 1797 |             super
 > 1798 |           end
 > 1799 |         
 > 1800 |       
 > 1801 |         default_stub  def each_substring(
 > 1802 |           data : String, min_length : Int = 4, 
 > 1803 |           
 > 1804 |           &block : (String ->)
 > 1805 |         )
 > 1806 |           
 > 1807 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1808 |           end
 > 1809 |         
 > 1810 |       
 > 1811 |         default_stub  def substrings(
 > 1812 |           data : String, min_length : Int = 4, 
 > 1813 |           
 > 1814 |           
 > 1815 |         ) : Array(String)
 > 1816 |           
 > 1817 |             super
 > 1818 |           end
 > 1819 |         
 > 1820 |       
 > 1821 |         default_stub  def |(
 > 1822 |           other : CharSet, 
 > 1823 |           
 > 1824 |           
 > 1825 |         ) : CharSet
 > 1826 |           
 > 1827 |             super
 > 1828 |           end
 > 1829 |         
 > 1830 |       
 > 1831 |         default_stub  def +(
 > 1832 |           other : CharSet, 
 > 1833 |           
 > 1834 |           
 > 1835 |         ) : CharSet
 > 1836 |           
 > 1837 |             super
 > 1838 |           end
 > 1839 |         
 > 1840 |       
 > 1841 |         default_stub  def -(
 > 1842 |           other : CharSet, 
 > 1843 |           
 > 1844 |           
 > 1845 |         ) : CharSet
 > 1846 |           
 > 1847 |             super
 > 1848 |           end
 > 1849 |         
 > 1850 |       
 > 1851 |         default_stub  def &(
 > 1852 |           other : CharSet, 
 > 1853 |           
 > 1854 |           
 > 1855 |         ) : CharSet
 > 1856 |           
 > 1857 |             super
 > 1858 |           end
 > 1859 |         
 > 1860 |       
 > 1861 |         default_stub  def intersects?(
 > 1862 |           other : CharSet, 
 > 1863 |           
 > 1864 |           
 > 1865 |         ) : Bool
 > 1866 |           
 > 1867 |             super
 > 1868 |           end
 > 1869 |         
 > 1870 |       
 > 1871 |         default_stub  def subset_of?(
 > 1872 |           other : CharSet, 
 > 1873 |           
 > 1874 |           
 > 1875 |         ) : Bool
 > 1876 |           
 > 1877 |             super
 > 1878 |           end
 > 1879 |         
 > 1880 |       
 > 1881 |         default_stub  def ==(
 > 1882 |           other : CharSet, 
 > 1883 |           
 > 1884 |           
 > 1885 |         ) : Bool
 > 1886 |           
 > 1887 |             super
 > 1888 |           end
 > 1889 |         
 > 1890 |       
 > 1891 |         default_stub  def ===(
 > 1892 |           other : String, 
 > 1893 |           
 > 1894 |           
 > 1895 |         ) : Bool
 > 1896 |           
 > 1897 |             super
 > 1898 |           end
 > 1899 |         
 > 1900 |       
 > 1901 |         default_stub  def =~(
 > 1902 |           string : String, 
 > 1903 |           
 > 1904 |           
 > 1905 |         )
 > 1906 |           
 > 1907 |             super
 > 1908 |           end
 > 1909 |         
 > 1910 |       
 > 1911 |         default_stub  def to_a(
 > 1912 |           *args, 
 > 1913 |           **options, 
 > 1914 |           
 > 1915 |         )
 > 1916 |           
 > 1917 |             super
 > 1918 |           end
 > 1919 |         
 > 1920 |       
 > 1921 |         default_stub  def to_a(
 > 1922 |           *args, 
 > 1923 |           **options, 
 > 1924 |           &
 > 1925 |         )
 > 1926 |           
 > 1927 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1928 |           end
 > 1929 |         
 > 1930 |       
 > 1931 |         default_stub  def to_set(
 > 1932 |           *args, 
 > 1933 |           **options, 
 > 1934 |           
 > 1935 |         )
 > 1936 |           
 > 1937 |             super
 > 1938 |           end
 > 1939 |         
 > 1940 |       
 > 1941 |         default_stub  def to_set(
 > 1942 |           *args, 
 > 1943 |           **options, 
 > 1944 |           &
 > 1945 |         )
 > 1946 |           
 > 1947 |             super { |*__temp_1063| yield *__temp_1063 }
 > 1948 |           end
 > 1949 |         
 > 1950 |       
 > 1951 | 
 > 1952 |       
 > 1953 |         default_stub  def self.new(
 > 1954 |           values : Enumerable(UInt8 | Int32 | Char), 
 > 1955 |           
 > 1956 |           
 > 1957 |         )
 > 1958 |           super
 > 1959 |         end
 > 1960 |       
 > 1961 |         default_stub  def self.new(
 > 1962 |           values : Indexable(UInt8 | Int32 | Char), 
 > 1963 |           
 > 1964 |           
 > 1965 |         )
 > 1966 |           super
 > 1967 |         end
 > 1968 |       
 > 1969 |         default_stub  def self.new(
 > 1970 |           
 > 1971 |           
 > 1972 |           
 > 1973 |         )
 > 1974 |           super
 > 1975 |         end
 > 1976 |       
 > 1977 |         default_stub  def self.[](
 > 1978 |           *values : UInt8 | Int32 | Char | Range(UInt8, UInt8) | Range(Int32, Int32) | Range(Char, Char), 
 > 1979 |           
 > 1980 |           
 > 1981 |         ) : CharSet
 > 1982 |           super
 > 1983 |         end
 > 1984 |       
 > 1985 |     
Error: expanding macro


In lib/spectator/src/spectator/mocks/stubbable.cr:161:58

 161 | {{ if method.return_type && method.return_type.resolve == NoReturn
                                                      ^------
Error: undefined constant U


In /var/lib/snapd/snap/crystal/1384/share/crystal/src/enumerable.cr:466:48

 466 | def each_with_object(obj : U, & : T, U ->) : U forall U
                                                    ^
Error: undefined constant U
@icy-arctic-fox icy-arctic-fox added the bug Something isn't working label Dec 13, 2022
@icy-arctic-fox
Copy link
Owner

It appears that the mock code doesn't account for free variables in return types.

@icy-arctic-fox icy-arctic-fox self-assigned this Dec 14, 2022
@icy-arctic-fox
Copy link
Owner

A fix for this issue and various related ones has been pushed to master. Can you confirm this fixes the issue with free variables in type annotations? I suspect there may be other issues porting chars.cr to the latest Spectator mocks. Please open an issue if you encounter any.

@icy-arctic-fox icy-arctic-fox changed the title Strange error when testing a old project with spectator 0.11.4 and crystal 1.6.2 Mocks fail to compile for methods with free variables Dec 18, 2022
@postmodern
Copy link
Author

postmodern commented Dec 18, 2022

@icy-arctic-fox awesome, that got me further. I now think I'm hitting another spectator bug.

Example code:

    #
    # Returns an Array of random, but unique, bytes from the `CharSet`.
    #
    def random_distinct_bytes(length : Int) : Array(Int32)
      @byte_set.to_a.shuffle[0,length]
    end

    #
    # Returns an Array of random, but unique, bytes from the `CharSet`.
    #
    def random_distinct_bytes(length : Array(Int),
                              random = Random::DEFAULT) : Array(Int32)
      bytes.shuffle[0,length.sample(random)]
    end

    #
    # Returns an Array of random, but unique, bytes from the `CharSet`.
    #
    def random_distinct_bytes(length : Range(Int, Int)) : Array(Int32)
      @byte_set.to_a.shuffle[0,rand(length)]
    end

Example spec code:

  describe "#random_distinct_bytes" do
    it "must return a random Array of unique bytes" do
      bytes = subject.random_distinct_bytes(10)

      expect(bytes.uniq).to be == bytes
      expect(bytes.all? { |b| subject.includes?(b) }).to be(true)
    end

    context "with a range of lengths" do
      it "must return a random Array of unique bytes with a varying length" do
        bytes = subject.random_distinct_bytes(5..10)

        expect(bytes.uniq).to be == bytes
        expect(bytes.size).to be_between(5, 10)
        expect(bytes.all? { |b| subject.includes?(b) }).to be(true)
      end
    end
  end

Error:

...

There was a problem expanding macro 'default_stub'

Called macro defined in lib/spectator/src/spectator/mocks/stubbable.cr:108:13

 108 | private macro default_stub(method)

Which expanded to:

    1 |       
    2 |       
    3 |       
    4 |       
    5 | 
    6 |        def random_distinct_bytes(
    7 |         length : Range(Int, Int), 
    8 |         
    9 |         
   10 |       ) : Array(Int32)
   11 |         super(length)
   12 |       end
   13 | 
   14 |       
   15 | 
   16 |       
   17 |        def random_distinct_bytes(
   18 |         length : Range(Int, Int), 
   19 |         
   20 |         
   21 |       ) : Array(Int32)
   22 | 
   23 |         # Capture information about the call.
 > 24 |         __temp_1575 = ::Spectator::MethodCall.build(
   25 |           :random_distinct_bytes,
   26 |           ::NamedTuple.new(
   27 |             "length": length, 
   28 |           ),
   29 |           
   30 |           ::NamedTuple.new(
   31 |             
   32 |           ).merge()
   33 |         )
   34 |         _spectator_record_call(__temp_1575)
   35 | 
   36 |         # Attempt to find a stub that satisfies the method call and arguments.
   37 |         # Finding a suitable stub is delegated to the type including the `Stubbable` module.
   38 |         if __temp_1576 = _spectator_find_stub(__temp_1575)
   39 |           # Cast the stub or return value to the expected type.
   40 |           # This is necessary to match the expected return type of the original method.
   41 |           _spectator_cast_stub_value(__temp_1576, __temp_1575, typeof(previous_def),
   42 |           :raise)
   43 |         else
   44 |           # Delegate missing stub behavior to concrete type.
   45 |           _spectator_stub_fallback(__temp_1575, typeof(previous_def)) do
   46 |             # Use the default response for the method.
   47 |             previous_def
   48 |           end
   49 |         end
   50 |       end
   51 |     
Error: instantiating 'Spectator::MethodCall.class#build(Symbol, NamedTuple(length: Range(Int32, Int32)), NamedTuple())'


In lib/spectator/src/spectator/mocks/method_call.cr:27:35

 27 | arguments = FormalArguments.build(*args, **kwargs).as(AbstractArguments)
                                  ^----
Error: instantiating 'Spectator::FormalArguments(Args, Splat, DoubleSplat).class#build(Tuple(NamedTuple(length: Range(Int32, Int32)), NamedTuple()), NamedTuple())'


In lib/spectator/src/spectator/mocks/formal_arguments.cr:36:7

 36 | new(args, nil, nil, kwargs)
      ^--
Error: instantiating 'new(NamedTuple(length: Range(Int32, Int32)), Nil, Nil, NamedTuple())'


Error: instantiating 'Spectator::AbstractArguments+#===(Spectator::AbstractArguments+)'


In lib/spectator/src/spectator/mocks/stub.cr:47:18

 47 | constraint === call.arguments
                 ^-
Error: instantiating 'Spectator::AbstractArguments+#===(Spectator::AbstractArguments+)'


In lib/spectator/src/spectator/mocks/formal_arguments.cr:130:7

 130 | compare_named_tuples(args, other.args) && compare_tuples(splat, other.splat) && compare_named_tuples(kwargs, other.kwargs)
       ^-------------------
Error: instantiating 'compare_named_tuples(NamedTuple(length: Range(Int32, Int32)), (NamedTuple() | NamedTuple(byte: Int32 | UInt8) | NamedTuple(char: Char) | NamedTuple(io: String::Builder) | NamedTuple(length: Int32 | Range(Int32, Int32)) | NamedTuple(length: Int32, random: Random::PCG32) | NamedTuple(method: Symbol) | NamedTuple(n: Int32) | NamedTuple(random: Random::PCG32) | NamedTuple(value: Char)))'


In lib/spectator/src/spectator/mocks/abstract_arguments.cr:35:9

 35 | a.each do |k, v1|
        ^---
Error: instantiating 'NamedTuple(length: Range(Int32, Int32))#each()'


In lib/spectator/src/spectator/mocks/abstract_arguments.cr:35:9

 35 | a.each do |k, v1|
        ^---
Error: instantiating 'NamedTuple(length: Range(Int32, Int32))#each()'


In lib/spectator/src/spectator/mocks/abstract_arguments.cr:42:34

 42 | return false unless v1 === v2
                             ^-
Error: instantiating 'Range(Int32, Int32)#===((Char | Int32 | Random::PCG32 | Range(Int32, Int32) | String::Builder | Symbol | UInt8))'


In /var/lib/snapd/snap/crystal/1384/share/crystal/src/range.cr:327:5

 327 | includes?(value)
       ^--------
Error: instantiating 'includes?((Char | Int32 | Random::PCG32 | Range(Int32, Int32) | String::Builder | Symbol | UInt8))'


In /var/lib/snapd/snap/crystal/1384/share/crystal/src/range.cr:298:35

 298 | (begin_value.nil? || value >= begin_value) &&
                                     ^----------
Error: expected argument #1 to 'Char#>=' to be Char, not Int32

Overloads are:
 - Char#>=(other : Char)
 - Comparable(T)#>=(other : T)

errors.log

@icy-arctic-fox
Copy link
Owner

Pushed another change to master that should fix range comparisons.

The underlying issue is that a union of argument types are being compared against each other. Case-equality matching (===) is used. This creates all sorts of combinations like (in your case):

(1..10) === 'a'

Which doesn't make sense, but could be a possible comparison with the union types. What I'm doing for now is using == for when === doesn't make sense. This is case-by-case. The problem with this is that any custom types defining a === method with no type restrictions may also hit this. I'm at least trying to cover the standard library types.

If you (or anyone else) has a better solution, I'd love to hear it!

@postmodern
Copy link
Author

@icy-arctic-fox got a little further.

Crystal code:

    @[AlwaysInline]
    def +(other : CharSet) : CharSet
      self | other
    end

Crystal spec:

  describe "#+" do
    mock Chars::CharSet do
      stub :|, other : Chars::CharSet
    end

    let(other) { described_class.new }
    let(return_value) { described_class.new }

    it "must call #+" do
      expect(subject).to receive(:|).with(other).and_return(return_value)

      expect(subject + other).to be(return_value)
    end
  end

Error:

In spec/char_set_spec.cr:658:1

 658 | it "must call #+" do
      ^
Error: expanding macro


There was a problem expanding macro 'it'

Called macro defined in macro 'define_example'

 17 | macro it(what = nil, *tags, **metadata, &block)

Which expanded to:

 >  1 |         
 >  2 |         
 >  3 | 
 >  4 |         _spectator_metadata(__temp_46, :metadata,  )
 >  5 |         _spectator_metadata(__temp_731, __temp_46,  )
 >  6 | 
 >  7 |         
 >  8 |           
 >  9 | 
 > 10 |           private def __temp_732() : Nil
 > 11 |             (expect(subject)).to(((receive(:|)).with(other)).and_return(return_value))
 > 12 | (expect(subject + other)).to(be(return_value))
 > 13 | 
 > 14 |           end
 > 15 | 
 > 16 |           ::Spectator::DSL::Builder.add_example(
 > 17 |             _spectator_example_name("must call #+"),
 > 18 |             ::Spectator::Location.new("/home/postmodern/code/crystal/chars.cr/spec/char_set_spec.cr", 658, 662),
 > 19 |             -> { new.as(::Spectator::Context) },
 > 20 |             __temp_731
 > 21 |           ) do |example|
 > 22 |             example.with_context(SpectatorTestContext::Group__temp_205::Group__temp_726) do
 > 23 |               
 > 24 |                 __temp_732
 > 25 |               
 > 26 |             end
 > 27 |           end
 > 28 | 
 > 29 |         
 > 30 |       
Error: instantiating 'Spectator::Example#with_context(SpectatorTestContext::Group__temp_205::Group__temp_726.class)'


In spec/char_set_spec.cr:658:1

 658 | it "must call #+" do
      ^
Error: expanding macro


There was a problem expanding macro 'it'

Called macro defined in macro 'define_example'

 17 | macro it(what = nil, *tags, **metadata, &block)

Which expanded to:

 >  1 |         
 >  2 |         
 >  3 | 
 >  4 |         _spectator_metadata(__temp_46, :metadata,  )
 >  5 |         _spectator_metadata(__temp_731, __temp_46,  )
 >  6 | 
 >  7 |         
 >  8 |           
 >  9 | 
 > 10 |           private def __temp_732() : Nil
 > 11 |             (expect(subject)).to(((receive(:|)).with(other)).and_return(return_value))
 > 12 | (expect(subject + other)).to(be(return_value))
 > 13 | 
 > 14 |           end
 > 15 | 
 > 16 |           ::Spectator::DSL::Builder.add_example(
 > 17 |             _spectator_example_name("must call #+"),
 > 18 |             ::Spectator::Location.new("/home/postmodern/code/crystal/chars.cr/spec/char_set_spec.cr", 658, 662),
 > 19 |             -> { new.as(::Spectator::Context) },
 > 20 |             __temp_731
 > 21 |           ) do |example|
 > 22 |             example.with_context(SpectatorTestContext::Group__temp_205::Group__temp_726) do
 > 23 |               
 > 24 |                 __temp_732
 > 25 |               
 > 26 |             end
 > 27 |           end
 > 28 | 
 > 29 |         
 > 30 |       
Error: instantiating '__temp_732()'


In spec/char_set_spec.cr:659:24

 659 | expect(subject).to receive(:|).with(other).and_return(return_value)
                        ^-
Error: instantiating 'Spectator::Expectation::Target(Chars::CharSet)#to(Spectator::ValueStub(Chars::CharSet))'


In lib/spectator/src/spectator/expectation.cr:104:7

 104 | def to(stub : Stub, message = nil) : Nil
       ^-
Error: The syntax `expect(...).to receive(...)` requires the expression passed to `expect` be stubbable (a mock or double)

@icy-arctic-fox
Copy link
Owner

It looks like the old (v0.9) stub syntax is being used. A method definition (def) is required after the stub keyword. That should have raised a compiler error, so I'll look into that...

    mock Chars::CharSet do
      stub :|, other : Chars::CharSet
    end

# can be just:

mock Chars::CharSet

The v0.11 syntax doesn't require a stub entry for each stubbed method. The mocked type also has to be instantiated with mock(Type).

I think this code should work:

Spectator.describe Chars::CharSet do
  mock Chars::CharSet

  describe "#|" do
    let(other) { mock(Chars::CharSet) }
    let(return_value) { mock(Chars::CharSet) }

    it "must call #+" do
      expect(subject).to receive(:|).with(other).and_return(return_value)

      expect(subject | other).to be(return_value)
    end
  end
end

More info about the new syntax and mock system can be found on the wiki.

@postmodern
Copy link
Author

Success! After adding the double mock statements it worked. I'm curious why are two mock statements required, in the specs and another within a let/subject?

@icy-arctic-fox
Copy link
Owner

I was attempting to copy the code you had before. This bit from the original:

    let(other) { described_class.new }
    let(return_value) { described_class.new }

The mock outside of the it block is a macro that defines a sub-type which mocks the original. The mock inside of a test block (or any other function like let) instantiates the previously defined mock. These can be replaced with def_mock and new_mock respectively if it makes more sense.

Spectator.describe Chars::CharSet do
  def_mock Chars::CharSet

  let(other) { new_mock(Chars::CharSet) }
  let(return_value) { new_mock(Chars::CharSet) }
end

Hope that makes sense. 😕

I'm glad it works now! Real world usages of Spectator are invaluable for testing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants