/ lib / truffle / src / AssertString.sol
AssertString.sol
  1  //SPDX-License-Identifier: MIT
  2  pragma solidity >= 0.4.15 < 0.9.0;
  3  
  4  library AssertString {
  5  
  6      // Constant: STRING_NULL
  7      // The null string: ""
  8      string constant STRING_NULL = "";
  9      
 10      /*
 11          Event: TestEvent
 12  
 13          Fired when an assertion is made.
 14  
 15          Params:
 16              result (bool) - Whether or not the assertion holds.
 17              message (string) - A message to display if the assertion does not hold.
 18      */
 19      event TestEvent(bool indexed result, string message);
 20  
 21      // ************************************** strings **************************************
 22  
 23      /*
 24          Function: equal(string)
 25  
 26          Assert that two strings are equal.
 27  
 28          : _stringsEqual(A, B) == true
 29  
 30          Params:
 31              A (string) - The first string.
 32              B (string) - The second string.
 33              message (string) - A message that is sent if the assertion fails.
 34  
 35          Returns:
 36              result (bool) - The result.
 37      */
 38      function equal(string memory a, string memory b, string memory message) public returns (bool result) {
 39          result = _stringsEqual(a, b);
 40          if (result)
 41              _report(result, message);
 42          else
 43              _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
 44      }
 45  
 46      /*
 47          Function: notEqual(string)
 48  
 49          Assert that two strings are not equal.
 50  
 51          : _stringsEqual(A, B) == false
 52  
 53          Params:
 54              A (string) - The first string.
 55              B (string) - The second string.
 56              message (string) - A message that is sent if the assertion fails.
 57  
 58          Returns:
 59              result (bool) - The result.
 60      */
 61      function notEqual(string memory a, string memory b, string memory message) public returns (bool result) {
 62          result = !_stringsEqual(a, b);
 63          if (result)
 64              _report(result, message);
 65          else
 66              _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
 67      }
 68  
 69      /*
 70          Function: isEmpty(string)
 71  
 72          Assert that a string is empty.
 73  
 74          : _stringsEqual(str, STRING_NULL) == true
 75  
 76          Params:
 77              str (string) - The string.
 78              message (string) - A message that is sent if the assertion fails.
 79  
 80          Returns:
 81              result (bool) - The result.
 82      */
 83      function isEmpty(string memory str, string memory message) public returns (bool result) {
 84          result = _stringsEqual(str, STRING_NULL);
 85          if (result)
 86              _report(result, message);
 87          else
 88              _report(result, _appendTagged(_tag(str, "Tested"), message));
 89      }
 90  
 91      /*
 92          Function: isNotEmpty(string)
 93  
 94          Assert that a string is not empty.
 95  
 96          : _stringsEqual(str, STRING_NULL) == false
 97  
 98          Params:
 99              str (string) - The string.
100              message (string) - A message that is sent if the assertion fails.
101  
102          Returns:
103              result (bool) - The result.
104      */
105      function isNotEmpty(string memory str, string memory message) public returns (bool result) {
106          result = !_stringsEqual(str, STRING_NULL);
107          if (result)
108              _report(result, message);
109          else
110              _report(result, _appendTagged(_tag(str, "Tested"), message));
111      }
112  
113      /******************************** internal ********************************/
114  
115          /*
116              Function: _report
117  
118              Internal function for triggering <TestEvent>.
119  
120              Params:
121                  result (bool) - The test result (true or false).
122                  message (string) - The message that is sent if the assertion fails.
123          */
124      function _report(bool result, string memory message) internal {
125          if(result)
126              emit TestEvent(true, "");
127          else
128              emit TestEvent(false, message);
129      }
130  
131      /*
132          Function: _stringsEqual
133  
134          Compares two strings. Taken from the StringUtils contract in the Ethereum Dapp-bin
135          (https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol).
136  
137          Params:
138              a (string) - The first string.
139              b (string) - The second string.
140  
141          Returns:
142               result (bool) - 'true' if the strings are equal, otherwise 'false'.
143      */
144      function _stringsEqual(string memory a, string memory b) internal pure returns (bool result) {
145          bytes memory ba = bytes(a);
146          bytes memory bb = bytes(b);
147  
148          if (ba.length != bb.length)
149              return false;
150          for (uint i = 0; i < ba.length; i ++) {
151              if (ba[i] != bb[i])
152                  return false;
153          }
154          return true;
155      }
156  
157      /*
158          Function: _tag(string)
159  
160          Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".
161  
162          Params:
163              value (string) - The value.
164              tag (string) - The tag.
165  
166          Returns:
167              result (string) - "tag: value"
168      */
169      function _tag(string memory value, string memory tag) internal pure returns (string memory) {
170  
171          bytes memory valueB = bytes(value);
172          bytes memory tagB = bytes(tag);
173  
174          uint vl = valueB.length;
175          uint tl = tagB.length;
176  
177          bytes memory newB = new bytes(vl + tl + 2);
178  
179          uint i;
180          uint j;
181  
182          for (i = 0; i < tl; i++)
183              newB[j++] = tagB[i];
184          newB[j++] = ':';
185          newB[j++] = ' ';
186          for (i = 0; i < vl; i++)
187              newB[j++] = valueB[i];
188  
189          return string(newB);
190      }
191  
192      /*
193          Function: _appendTagged(string)
194  
195          Append a tagged value to a string.
196  
197          Params:
198              tagged (string) - The tagged value.
199              str (string) - The string.
200  
201          Returns:
202              result (string) - "str (tagged)"
203      */
204      function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) {
205  
206          bytes memory taggedB = bytes(tagged);
207          bytes memory strB = bytes(str);
208  
209          uint sl = strB.length;
210          uint tl = taggedB.length;
211  
212          bytes memory newB = new bytes(sl + tl + 3);
213  
214          uint i;
215          uint j;
216  
217          for (i = 0; i < sl; i++)
218              newB[j++] = strB[i];
219          newB[j++] = ' ';
220          newB[j++] = '(';
221          for (i = 0; i < tl; i++)
222              newB[j++] = taggedB[i];
223          newB[j++] = ')';
224  
225          return string(newB);
226      }
227  
228      /*
229          Function: _appendTagged(string, string)
230  
231          Append two tagged values to a string.
232  
233          Params:
234              tagged0 (string) - The first tagged value.
235              tagged1 (string) - The second tagged value.
236              str (string) - The string.
237  
238          Returns:
239              result (string) - "str (tagged0, tagged1)"
240      */
241      function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {
242  
243          bytes memory tagged0B = bytes(tagged0);
244          bytes memory tagged1B = bytes(tagged1);
245          bytes memory strB = bytes(str);
246  
247          uint sl = strB.length;
248          uint t0l = tagged0B.length;
249          uint t1l = tagged1B.length;
250  
251          bytes memory newB = new bytes(sl + t0l + t1l + 5);
252  
253          uint i;
254          uint j;
255  
256          for (i = 0; i < sl; i++)
257              newB[j++] = strB[i];
258          newB[j++] = ' ';
259          newB[j++] = '(';
260          for (i = 0; i < t0l; i++)
261              newB[j++] = tagged0B[i];
262          newB[j++] = ',';
263          newB[j++] = ' ';
264          for (i = 0; i < t1l; i++)
265              newB[j++] = tagged1B[i];
266          newB[j++] = ')';
267  
268          return string(newB);
269      }
270  
271  }