<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
                                        > <span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Replaces SUnit-ct.126 which can be moved into the treated inbox.</span><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">And what about </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 10pt">SUnit-ct.127?</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 10pt"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 10pt">Best,</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 10pt">Marcel</span></div><div class="mb_sig"></div><blockquote class='history_container' type='cite' style='border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;'>
                        <p style='color: #AAAAAA; margin-top: 10px;'>Am 06.03.2021 00:35:43 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style='font-family:Arial,Helvetica,sans-serif'>A new version of SUnit was added to project The Inbox:<br>http://source.squeak.org/inbox/SUnit-ct.132.mcz<br><br>==================== Summary ====================<br><br>Name: SUnit-ct.132<br>Author: ct<br>Time: 6 March 2021, 12:35:33.710439 am<br>UUID: 98d667df-13be-d148-9117-0b214c9adb3f<br>Ancestors: SUnit-nice.124<br><br>Refactors and completes equality assertions<br><br>- Add #deny:equals:description:, #deny:identical:, and #deny:identical:description:<br>- Revise default description message for #deny:equals:, aligning it to #assert:equals: description<br>- Make equality assertions capable of lazy descriptions (aStringOrBlock), aligning them to<br>#assert:description: etc.<br>- Add multilingual support for default description messages<br>- Some internal refactoring<br>- Improve test coverage of these assertions in SUnitTest<br><br>Thanks to Marcel for pointing to the idea!<br><br>Uploaded again to resolve conflicts with SUnit-pre.122 (recategorization). Replaces SUnit-ct.126 which can be moved into the treated inbox. :-)<br><br>=============== Diff against SUnit-nice.124 ===============<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testAssertEquals (in category 'tests') -----<br>+ testAssertEquals<br>+ <br>+       | a b |<br>+      a := 'foo'.<br>+  b := 'bar'.<br>+  <br>+     self shouldnt: [self assert: a equals: a copy] raise: TestFailure.<br>+   <br>+     self should: [self assert: a equals: b] raise: TestFailure.<br>+  <br>+     [self assert: a equals: b]<br>+           on: TestFailure do: [:ex |<br>+                   | error |<br>+                    error := ex messageText.<br>+                     self<br>+                                 assert: (error includesSubstring: a)<br>+                                 description: 'Error message doesn''t include the expected value'.<br>+                    self<br>+                                 assert: (error includesSubstring: b)<br>+                                 description: 'Error message doesn''t include the actual value'].!<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testAssertEqualsDescription (in category 'tests') -----<br>+ testAssertEqualsDescription<br>+ <br>+    | a b called |<br>+       a := 'foo'.<br>+  b := 'bar'.<br>+  <br>+     self shouldnt: [self assert: a equals: a copy description: 'A description42'] raise: TestFailure.<br>+    <br>+     self should: [self assert: a equals: b description: 'A description42'] raise: TestFailure.<br>+   <br>+     [self assert: a equals: b description: 'A description42']<br>+            on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A description42')<br>+                                description: 'Error message doesn''t give you the description'].<br>+     <br>+     called := false.<br>+     self shouldnt: [self assert: a equals: a description: [called := true]] raise: TestFailure.<br>+  self deny: called description: 'Description block was evaluated prematurely'.<br>+        <br>+     [self assert: a equals: b description: ['A generated description' asUppercase]]<br>+              on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A generated description' asUppercase)<br>+                            description: 'Error message doesn''t give you the generated description'].!<br><br>Item was changed:<br>  ----- Method: SUnitTest>>testAssertIdentical (in category 'tests') -----<br>  testAssertIdentical<br>+ <br>         | a b |<br>       a := 'foo'.<br>   b := 'bar'.<br>+  <br>+     self shouldnt: [self assert: a identical: a] raise: TestFailure.<br>+     <br>      self should: [self assert: a identical: b] raise: TestFailure.<br>+       <br>+     [self assert: a identical: b]<br>+                on: TestFailure do: [:ex |<br>+                   | error |<br>+                    error := ex messageText.<br>+                     self<br>+                                 assert: (error includesSubstring: a)<br>+                                 description: 'Error message doesn''t include the expected value'.<br>+                    self<br>+                                 assert: (error includesSubstring: b)<br>+                                 description: 'Error message doesn''t include the actual value'].!<br>-    [self assert: a identical: b] on: TestFailure do: [:e | |error|<br>-              error := e messageText.<br>-              self assert: (error includesSubstring: a) description: 'Error message doesn''t include the expected value'.<br>-          self assert: (error includesSubstring: b) description: 'Error message doesn''t include the expected value'].!<br><br>Item was changed:<br>  ----- Method: SUnitTest>>testAssertIdenticalDescription (in category 'tests') -----<br>  testAssertIdenticalDescription<br>+ <br>+        | a b called |<br>-       | a b |<br>       a := 'foo'.<br>   b := a copy.<br>+         <br>+     self shouldnt: [self assert: a identical: a description: 'A description42'] raise: TestFailure.<br>+      <br>+     self should: [self assert: a identical: b description: 'A description42'] raise: TestFailure.<br>+        <br>+     [self assert: a identical: b description: 'A description42']<br>+                 on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A description42')<br>+                                description: 'Error message doesn''t give you the description'].<br>+     <br>+     called := false.<br>+     self shouldnt: [self assert: a identical: a description: [called := true]] raise: TestFailure.<br>+       self deny: called description: 'Description block was evaluated prematurely'.<br>+        <br>+     [self assert: a identical: b description: ['A generated description' asUppercase]]<br>+           on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A generated description' asUppercase)<br>+                            description: 'Error message doesn''t give you the generated description'].!<br>-  self should: [self assert: a identical: b description: 'A desciption'] raise: TestFailure.<br>-   [self assert: a identical: b description: 'A desciption'] on: TestFailure do: [:e | |error|<br>-          error := e messageText.<br>-              self assert: (error includesSubstring: 'A desciption') description: 'Error message doesn''t give you the description'].!<br><br>Item was changed:<br>  ----- Method: SUnitTest>>testAssertIdenticalWithEqualObjects (in category 'tests') -----<br>  testAssertIdenticalWithEqualObjects<br>+ <br>    | a b |<br>       a := 'foo'.<br>   b := a copy.<br>+         <br>      self should: [self assert: a identical: b] raise: TestFailure.<br>+       <br>+     [self assert: a identical: b]<br>+                on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'not identical')<br>+                          description: 'Error message doesn''t say the two things aren''t identical'].!<br>-        [self assert: a identical: b] on: TestFailure do: [:e | |error|<br>-              error := e messageText.<br>-              self assert: (error includesSubstring: 'not identical') description: 'Error message doesn''t say the two things aren''t identical'].!<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testDenyEquals (in category 'tests') -----<br>+ testDenyEquals<br>+ <br>+  | a b |<br>+      a := 'foo'.<br>+  b := 'bar'.<br>+  <br>+     self shouldnt: [self deny: a equals: b] raise: TestFailure.<br>+  <br>+     self should: [self deny: a equals: a copy] raise: TestFailure.<br>+       <br>+     [self deny: a equals: a]<br>+             on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: a)<br>+                                description: 'Error message doesn''t include the unexpected value'].!<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testDenyEqualsDescription (in category 'tests') -----<br>+ testDenyEqualsDescription<br>+ <br>+    | a b called |<br>+       a := 'foo'.<br>+  b := 'bar'.<br>+  <br>+     self shouldnt: [self deny: a equals: b description: 'A description42'] raise: TestFailure.<br>+   <br>+     self should: [self deny: a equals: a copy description: 'A description42'] raise: TestFailure.<br>+        <br>+     [self deny: a equals: a description: 'A description42']<br>+              on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A description42')<br>+                                description: 'Error message doesn''t give you the description'].<br>+     <br>+     called := false.<br>+     self shouldnt: [self deny: a equals: b description: [called := true]] raise: TestFailure.<br>+    self deny: called description: 'Description block was evaluated prematurely'.<br>+        <br>+     [self deny: a equals: a description: ['A generated description' asUppercase]]<br>+                on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A generated description' asUppercase)<br>+                            description: 'Error message doesn''t give you the generated description'].!<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testDenyIdentical (in category 'tests') -----<br>+ testDenyIdentical<br>+ <br>+      | a b |<br>+      a := 'foo'.<br>+  b := 'bar'.<br>+  self shouldnt: [self deny: a identical: b] raise: TestFailure.<br>+       self should: [self deny: a identical: a] raise: TestFailure.<br>+         [self deny: a identical: a]<br>+          on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: a)<br>+                                description: 'Error message doesn''t include the unexpected value'].!<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testDenyIdenticalDescription (in category 'tests') -----<br>+ testDenyIdenticalDescription<br>+ <br>+      | a b called |<br>+       a := 'foo'.<br>+  b := a copy.<br>+         <br>+     self shouldnt: [self deny: a identical: b description: 'A description42'] raise: TestFailure.<br>+        <br>+     self should: [self deny: a identical: a description: 'A description42'] raise: TestFailure.<br>+  <br>+     [self deny: a identical: a description: 'A description42']<br>+           on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A description42')<br>+                                description: 'Error message doesn''t give you the description'].<br>+     <br>+     called := false.<br>+     self shouldnt: [self deny: a identical: b description: [called := true]] raise: TestFailure.<br>+         self deny: called description: 'Description block was evaluated prematurely'.<br>+        <br>+     [self deny: a identical: a description: ['A generated description' asUppercase]]<br>+             on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'A generated description' asUppercase)<br>+                            description: 'Error message doesn''t give you the description'].!<br><br>Item was added:<br>+ ----- Method: SUnitTest>>testDenyIdenticalWithEqualObjects (in category 'tests') -----<br>+ testDenyIdenticalWithEqualObjects<br>+ <br>+        | a b |<br>+      a := 'foo'.<br>+  b := a copy.<br>+         self should: [self deny: a identical: a] raise: TestFailure.<br>+         [self deny: a identical: a]<br>+          on: TestFailure do: [:ex |<br>+                   self<br>+                                 assert: (ex messageText includesSubstring: 'identical')<br>+                              description: 'Error message doesn''t say the two things are identical'].!<br><br>Item was changed:<br>  ----- Method: TestCase>>assert:equals: (in category 'asserting') -----<br>  assert: expected equals: actual<br>  <br>+        ^ self<br>+               assert: expected<br>+             equals: actual<br>+               description: nil<br>-     ^self<br>-                assert: expected = actual<br>-            description: [ self comparingStringBetween: expected and: actual ]<br>  !<br><br>Item was changed:<br>  ----- Method: TestCase>>assert:equals:description: (in category 'asserting') -----<br>+ assert: expected equals: actual description: aStringOrBlock<br>- assert: expected equals: actual description: aString<br>  <br>+  ^ self<br>-       ^self<br>                 assert: expected = actual<br>+            description: [self<br>+                   description: aStringOrBlock<br>+                  with: (self comparingStringBetween: expected and: actual)]!<br>-          description: [ aString , ': ', (self comparingStringBetween: expected and: actual) ]!<br><br>Item was changed:<br>  ----- Method: TestCase>>assert:identical: (in category 'asserting') -----<br>  assert: expected identical: actual<br>  <br>+      ^ self<br>+               assert: expected<br>+             identical: actual<br>+            description: nil!<br>-    ^self<br>-                assert: expected == actual<br>-           description: [ self comparingStringBetweenIdentical: expected and: actual ]<br>- !<br><br>Item was changed:<br>  ----- Method: TestCase>>assert:identical:description: (in category 'asserting') -----<br>+ assert: expected identical: actual description: aStringOrBlock<br>- assert: expected identical: actual description: aString<br>  <br>+        ^ self<br>-       ^self<br>                 assert: expected == actual<br>+           description: [self<br>+                   description: aStringOrBlock<br>+                  with: (self comparingStringBetween: expected andIdentical: actual)]!<br>-                 description: [ aString , ': ', (self comparingStringBetweenIdentical: expected and: actual) ]!<br><br>Item was changed:<br>  ----- Method: TestCase>>comparingStringBetween:and: (in category 'private') -----<br>  comparingStringBetween: expected and: actual<br>+ <br>+   ^ 'Expected {1} but was {2}.' translated<br>+             format: {<br>+                    expected printStringLimitedTo: 10.<br>+                   actual printStringLimitedTo: 10 }!<br>-   ^ String streamContents: [:stream |<br>-          stream<br>-                       nextPutAll: 'Expected ';<br>-                     nextPutAll: (expected printStringLimitedTo: 10);<br>-                     nextPutAll: ' but was ';<br>-                     nextPutAll: (actual printStringLimitedTo: 10);<br>-                       nextPutAll: '.'<br>-              ]!<br><br>Item was added:<br>+ ----- Method: TestCase>>comparingStringBetween:andIdentical: (in category 'private') -----<br>+ comparingStringBetween: expected andIdentical: actual<br>+ <br>+       ^ 'Expected {1} and actual {2} are not identical.' translated<br>+                format: {<br>+                    expected printStringLimitedTo: 10.<br>+                   actual printStringLimitedTo: 10 }!<br><br>Item was changed:<br>  ----- Method: TestCase>>comparingStringBetweenIdentical:and: (in category 'private') -----<br>  comparingStringBetweenIdentical: expected and: actual<br>+ <br>+     self deprecated.<br>+     ^ self comparingStringBetween: expected andIdentical: actual!<br>-        ^ 'Expected {1} and actual {2} are not identical.' format: {<br>-                 expected printStringLimitedTo: 10.<br>-           actual printStringLimitedTo: 10.<br>-     }!<br><br>Item was added:<br>+ ----- Method: TestCase>>comparingStringBetweenUnexpected:and: (in category 'private') -----<br>+ comparingStringBetweenUnexpected: unexpected and: actual<br>+ <br>+   ^ 'Did not expect {1} but was {2}.' translated<br>+               format: {<br>+                    unexpected printStringLimitedTo: 10.<br>+                         actual printStringLimitedTo: 10 }!<br><br>Item was added:<br>+ ----- Method: TestCase>>comparingStringBetweenUnexpected:andIdentical: (in category 'private') -----<br>+ comparingStringBetweenUnexpected: expected andIdentical: actual<br>+ <br>+   ^ 'Unexpected {1} and actual {2} are identical.' translated<br>+          format: {<br>+                    expected printStringLimitedTo: 10.<br>+                   actual printStringLimitedTo: 10 }!<br><br>Item was changed:<br>  ----- Method: TestCase>>deny:equals: (in category 'asserting') -----<br>  deny: unexpected equals: actual<br>  <br>+         ^ self<br>+               deny: unexpected<br>+             equals: actual<br>+               description: nil!<br>-    ^self<br>-                deny: unexpected = actual<br>-            description: 'Actual equals unexpected'<br>- !<br><br>Item was added:<br>+ ----- Method: TestCase>>deny:equals:description: (in category 'asserting') -----<br>+ deny: unexpected equals: actual description: aStringOrBlock<br>+ <br>+         ^ self<br>+               deny: unexpected = actual<br>+            description: [self<br>+                   description: aStringOrBlock<br>+                  with: (self comparingStringBetweenUnexpected: unexpected and: actual)]!<br><br>Item was added:<br>+ ----- Method: TestCase>>deny:identical: (in category 'asserting') -----<br>+ deny: unexpected identical: actual<br>+ <br>+        ^ self<br>+               deny: unexpected<br>+             identical: actual<br>+            description: nil!<br><br>Item was added:<br>+ ----- Method: TestCase>>deny:identical:description: (in category 'asserting') -----<br>+ deny: unexpected identical: actual description: aStringOrBlock<br>+ <br>+      ^ self<br>+               deny: unexpected == actual<br>+           description: [self<br>+                   description: aStringOrBlock<br>+                  with: (self comparingStringBetweenUnexpected: unexpected andIdentical: actual)]!<br><br>Item was added:<br>+ ----- Method: TestCase>>description:with: (in category 'private') -----<br>+ description: aStringOrBlock with: reason<br>+ <br>+         | description |<br>+      description := aStringOrBlock value.<br>+         ^ description<br>+                ifNil: [reason]<br>+              ifNotNil: ['{1}: {2}' translated format: {description. reason}]!<br><br><br></div></blockquote>
                                        </div></body>