<commit_before>describe 'when', ->
  Given -> @testDouble = td.function()

  describe 'no-arg stubbing', ->
    context 'foo', ->
      Given -> td.when(@testDouble()).thenReturn("foo")
      Then -> @testDouble() == "foo"
    context 'bar', ->
      Given -> td.when(@testDouble()).thenReturn("bar")
      Then -> @testDouble() == "bar"

  describe 'last-in-wins overwriting', ->
    Given -> td.when(@testDouble("something")).thenReturn("gold")
    Given -> td.when(@testDouble("something")).thenReturn("iron")
    Then -> @testDouble("something") == "iron"

  describe 'conditional stubbing', ->
    Given -> td.when(@testDouble(1)).thenReturn("foo")
    Given -> td.when(@testDouble(2)).thenReturn("bar")
    Given -> td.when(@testDouble(lol: 'cheese')).thenReturn('nom')
    Given -> td.when(@testDouble(lol: 'fungus')).thenReturn('eww')
    Given -> td.when(@testDouble({lol: 'fungus'}, 2)).thenReturn('eww2')
    Then -> @testDouble() == undefined
    And -> @testDouble(1) == "foo"
    And -> @testDouble(2) == "bar"
    And -> @testDouble(lol: 'cheese') == "nom"
    And -> @testDouble(lol: 'fungus') == "eww"
    And -> @testDouble({lol: 'fungus'}, 2) == "eww2"

  describe 'multiple test doubles', ->
    Given -> @td1 = td.when(td.function()()).thenReturn("lol1")
    Given -> @td2 = td.when(td.function()()).thenReturn("lol2")
    Then -> @td1() == "lol1"
    Then -> @td2() == "lol2"

  describe 'using matchers', ->
    Given -> td.when(@testDouble(88, td.matchers.isA(Number))).thenReturn("yay")
    Then -> @testDouble(88, 5) == "yay"
    Then -> @testDouble(44, 5) == undefined
    Then -> @testDouble(88, "five") == undefined

  describe 'using deep matcher', ->
    context 'single level', ->
      Given -> td.when(@testDouble(key: td.matchers.isA(String))).thenReturn("yay")
      Then -> @testDouble(key: "testytest") == "yay"
      Then -> @testDouble(key: 42) == undefined
      Then -> @testDouble({}) == undefined
      Then -> @testDouble("i am a string") == undefined

    context 'deeply nested', ->
      Given -> td.when(@testDouble(a: {b: td.matchers.isA(String)})).thenReturn("yay")
      Then -> @testDouble(a: {b: "testytest"}) == "yay"
      Then -> @testDouble(a: {b: 42}) == undefined
      Then -> @testDouble(a: "testytest") == undefined

    context 'array values', ->
      Given -> td.when(@testDouble([5, td.matchers.isA(String)])).thenReturn("yay")
      Then -> @testDouble([5, "testytest"]) == "yay"
      Then -> @testDouble([5, 6]) == undefined
      Then -> @testDouble([5]) == undefined
      Then -> @testDouble([]) == undefined

  describe 'stubbing sequential returns', ->
    context 'a single stubbing', ->
      Given -> td.when(@testDouble()).thenReturn(10,9)
      When -> [@first, @second, @third] = [@testDouble(), @testDouble(), @testDouble()]
      Then -> @first == 10
      Then -> @second == 9
      Then -> @third == 9 #<-- last one repeats

    context 'two overlapping stubbings', ->
      Given -> td.when(@testDouble()).thenReturn('A')
      Given -> @testDouble() #<-- returns A, td's callCount will be 1
      Given -> td.when(@testDouble()).thenReturn('B', 'C')
      Then -> @testDouble() == 'B'

  describe 'stubbing actions with `thenDo` instead of `thenReturn`', ->
    Given -> @someAction = td.when(td.function()(55)).thenReturn('yatta')
    Given -> td.when(@testDouble(55)).thenDo(@someAction)
    When -> @result = @testDouble(55)
    And -> @result == 'yatta'

  describe 'stubbing actions with `thenThrow` instead of `thenReturn`', ->
    Given -> @error = new Error('lol')
    Given -> td.when(@testDouble(42)).thenThrow(@error)
    When -> try @testDouble(42) catch e then @result = e
    Then -> @error == @result
<commit_msg>Test to expose circular structure bug in impl<commit_after>describe 'when', ->
  Given -> @testDouble = td.function()

  describe 'no-arg stubbing', ->
    context 'foo', ->
      Given -> td.when(@testDouble()).thenReturn("foo")
      Then -> @testDouble() == "foo"
    context 'bar', ->
      Given -> td.when(@testDouble()).thenReturn("bar")
      Then -> @testDouble() == "bar"

  describe 'last-in-wins overwriting', ->
    Given -> td.when(@testDouble("something")).thenReturn("gold")
    Given -> td.when(@testDouble("something")).thenReturn("iron")
    Then -> @testDouble("something") == "iron"

  describe 'conditional stubbing', ->
    Given -> td.when(@testDouble(1)).thenReturn("foo")
    Given -> td.when(@testDouble(2)).thenReturn("bar")
    Given -> td.when(@testDouble(lol: 'cheese')).thenReturn('nom')
    Given -> td.when(@testDouble(lol: 'fungus')).thenReturn('eww')
    Given -> td.when(@testDouble({lol: 'fungus'}, 2)).thenReturn('eww2')
    Then -> @testDouble() == undefined
    And -> @testDouble(1) == "foo"
    And -> @testDouble(2) == "bar"
    And -> @testDouble(lol: 'cheese') == "nom"
    And -> @testDouble(lol: 'fungus') == "eww"
    And -> @testDouble({lol: 'fungus'}, 2) == "eww2"

  describe 'multiple test doubles', ->
    Given -> @td1 = td.when(td.function()()).thenReturn("lol1")
    Given -> @td2 = td.when(td.function()()).thenReturn("lol2")
    Then -> @td1() == "lol1"
    Then -> @td2() == "lol2"

  describe 'using matchers', ->
    Given -> td.when(@testDouble(88, td.matchers.isA(Number))).thenReturn("yay")
    Then -> @testDouble(88, 5) == "yay"
    Then -> @testDouble(44, 5) == undefined
    Then -> @testDouble(88, "five") == undefined

  describe 'using deep matchers', ->
    context 'single level', ->
      Given -> td.when(@testDouble(key: td.matchers.isA(String))).thenReturn("yay")
      Then -> @testDouble(key: "testytest") == "yay"
      Then -> @testDouble(key: 42) == undefined
      Then -> @testDouble({}) == undefined
      Then -> @testDouble("i am a string") == undefined

    context 'deeply nested', ->
      Given -> td.when(@testDouble(a: {b: td.matchers.isA(String)})).thenReturn("yay")
      Then -> @testDouble(a: {b: "testytest"}) == "yay"
      Then -> @testDouble(a: {b: 42}) == undefined
      Then -> @testDouble(a: "testytest") == undefined

    context 'array values', ->
      Given -> td.when(@testDouble([5, td.matchers.isA(String)])).thenReturn("yay")
      Then -> @testDouble([5, "testytest"]) == "yay"
      Then -> @testDouble([5, 6]) == undefined
      Then -> @testDouble([5]) == undefined
      Then -> @testDouble([]) == undefined

    context 'arguments with circular structures', ->
      Given -> @arg =
        foo: 'bar'
      Given -> @arg.baz = @arg
      Given -> td.when(@testDouble(@arg)).thenReturn("yay")
      Then -> @testDouble(@arg) == "yay"
      Then -> @testDouble('no') == undefined



  describe 'stubbing sequential returns', ->
    context 'a single stubbing', ->
      Given -> td.when(@testDouble()).thenReturn(10,9)
      When -> [@first, @second, @third] = [@testDouble(), @testDouble(), @testDouble()]
      Then -> @first == 10
      Then -> @second == 9
      Then -> @third == 9 #<-- last one repeats

    context 'two overlapping stubbings', ->
      Given -> td.when(@testDouble()).thenReturn('A')
      Given -> @testDouble() #<-- returns A, td's callCount will be 1
      Given -> td.when(@testDouble()).thenReturn('B', 'C')
      Then -> @testDouble() == 'B'

  describe 'stubbing actions with `thenDo` instead of `thenReturn`', ->
    Given -> @someAction = td.when(td.function()(55)).thenReturn('yatta')
    Given -> td.when(@testDouble(55)).thenDo(@someAction)
    When -> @result = @testDouble(55)
    And -> @result == 'yatta'

  describe 'stubbing actions with `thenThrow` instead of `thenReturn`', ->
    Given -> @error = new Error('lol')
    Given -> td.when(@testDouble(42)).thenThrow(@error)
    When -> try @testDouble(42) catch e then @result = e
    Then -> @error == @result

{'fraction_non_alphanumeric': 0.20925423290681142, 'fraction_numerical': 0.013700400672095128, 'mean_word_length': 3.2657111356119075, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 159, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '632139', 'n_tokens_mistral': 2603, 'n_tokens_neox': 2512, 'n_words': 561}