string.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344
  1. package httpexpect
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "regexp"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "unicode"
  11. )
  12. // String provides methods to inspect attached string value
  13. // (Go representation of JSON string).
  14. type String struct {
  15. noCopy noCopy
  16. chain *chain
  17. value string
  18. }
  19. // NewString returns a new String instance.
  20. //
  21. // If reporter is nil, the function panics.
  22. //
  23. // Example:
  24. //
  25. // str := NewString(t, "Hello")
  26. func NewString(reporter Reporter, value string) *String {
  27. return newString(newChainWithDefaults("String()", reporter), value)
  28. }
  29. // NewStringC returns a new String instance with config.
  30. //
  31. // Requirements for config are same as for WithConfig function.
  32. //
  33. // Example:
  34. //
  35. // str := NewStringC(config, "Hello")
  36. func NewStringC(config Config, value string) *String {
  37. return newString(newChainWithConfig("String()", config.withDefaults()), value)
  38. }
  39. func newString(parent *chain, val string) *String {
  40. return &String{chain: parent.clone(), value: val}
  41. }
  42. // Raw returns underlying value attached to String.
  43. // This is the value originally passed to NewString.
  44. //
  45. // Example:
  46. //
  47. // str := NewString(t, "Hello")
  48. // assert.Equal(t, "Hello", str.Raw())
  49. func (s *String) Raw() string {
  50. return s.value
  51. }
  52. // Decode unmarshals the underlying value attached to the String to a target variable.
  53. // target should be one of these:
  54. //
  55. // - pointer to an empty interface
  56. // - pointer to a string
  57. //
  58. // Example:
  59. //
  60. // value := NewString(t, "foo")
  61. //
  62. // var target string
  63. // value.Decode(&target)
  64. //
  65. // assert.Equal(t, "foo", target)
  66. func (s *String) Decode(target interface{}) *String {
  67. opChain := s.chain.enter("Decode()")
  68. defer opChain.leave()
  69. if opChain.failed() {
  70. return s
  71. }
  72. canonDecode(opChain, s.value, target)
  73. return s
  74. }
  75. // Alias is similar to Value.Alias.
  76. func (s *String) Alias(name string) *String {
  77. opChain := s.chain.enter("Alias(%q)", name)
  78. defer opChain.leave()
  79. s.chain.setAlias(name)
  80. return s
  81. }
  82. // Path is similar to Value.Path.
  83. func (s *String) Path(path string) *Value {
  84. opChain := s.chain.enter("Path(%q)", path)
  85. defer opChain.leave()
  86. return jsonPath(opChain, s.value, path)
  87. }
  88. // Schema is similar to Value.Schema.
  89. func (s *String) Schema(schema interface{}) *String {
  90. opChain := s.chain.enter("Schema()")
  91. defer opChain.leave()
  92. jsonSchema(opChain, s.value, schema)
  93. return s
  94. }
  95. // Length returns a new Number instance with string length.
  96. //
  97. // Example:
  98. //
  99. // str := NewString(t, "Hello")
  100. // str.Length().IsEqual(5)
  101. func (s *String) Length() *Number {
  102. opChain := s.chain.enter("Length()")
  103. defer opChain.leave()
  104. if opChain.failed() {
  105. return newNumber(opChain, 0)
  106. }
  107. return newNumber(opChain, float64(len(s.value)))
  108. }
  109. // IsEmpty succeeds if string is empty.
  110. //
  111. // Example:
  112. //
  113. // str := NewString(t, "")
  114. // str.IsEmpty()
  115. func (s *String) IsEmpty() *String {
  116. opChain := s.chain.enter("IsEmpty()")
  117. defer opChain.leave()
  118. if opChain.failed() {
  119. return s
  120. }
  121. if !(s.value == "") {
  122. opChain.fail(AssertionFailure{
  123. Type: AssertEmpty,
  124. Actual: &AssertionValue{s.value},
  125. Errors: []error{
  126. errors.New("expected: string is empty"),
  127. },
  128. })
  129. }
  130. return s
  131. }
  132. // NotEmpty succeeds if string is non-empty.
  133. //
  134. // Example:
  135. //
  136. // str := NewString(t, "Hello")
  137. // str.NotEmpty()
  138. func (s *String) NotEmpty() *String {
  139. opChain := s.chain.enter("NotEmpty()")
  140. defer opChain.leave()
  141. if opChain.failed() {
  142. return s
  143. }
  144. if s.value == "" {
  145. opChain.fail(AssertionFailure{
  146. Type: AssertNotEmpty,
  147. Actual: &AssertionValue{s.value},
  148. Errors: []error{
  149. errors.New("expected: string is non-empty"),
  150. },
  151. })
  152. }
  153. return s
  154. }
  155. // Deprecated: use IsEmpty instead.
  156. func (s *String) Empty() *String {
  157. return s.IsEmpty()
  158. }
  159. // IsEqual succeeds if string is equal to given Go string.
  160. //
  161. // Example:
  162. //
  163. // str := NewString(t, "Hello")
  164. // str.IsEqual("Hello")
  165. func (s *String) IsEqual(value string) *String {
  166. opChain := s.chain.enter("IsEqual()")
  167. defer opChain.leave()
  168. if opChain.failed() {
  169. return s
  170. }
  171. if !(s.value == value) {
  172. opChain.fail(AssertionFailure{
  173. Type: AssertEqual,
  174. Actual: &AssertionValue{s.value},
  175. Expected: &AssertionValue{value},
  176. Errors: []error{
  177. errors.New("expected: strings are equal"),
  178. },
  179. })
  180. }
  181. return s
  182. }
  183. // NotEqual succeeds if string is not equal to given Go string.
  184. //
  185. // Example:
  186. //
  187. // str := NewString(t, "Hello")
  188. // str.NotEqual("Goodbye")
  189. func (s *String) NotEqual(value string) *String {
  190. opChain := s.chain.enter("NotEqual()")
  191. defer opChain.leave()
  192. if opChain.failed() {
  193. return s
  194. }
  195. if s.value == value {
  196. opChain.fail(AssertionFailure{
  197. Type: AssertNotEqual,
  198. Actual: &AssertionValue{s.value},
  199. Expected: &AssertionValue{value},
  200. Errors: []error{
  201. errors.New("expected: strings are non-equal"),
  202. },
  203. })
  204. }
  205. return s
  206. }
  207. // Deprecated: use IsEqual instead.
  208. func (s *String) Equal(value string) *String {
  209. return s.IsEqual(value)
  210. }
  211. // IsEqualFold succeeds if string is equal to given Go string after applying Unicode
  212. // case-folding (so it's a case-insensitive match).
  213. //
  214. // Example:
  215. //
  216. // str := NewString(t, "Hello")
  217. // str.IsEqualFold("hELLo")
  218. func (s *String) IsEqualFold(value string) *String {
  219. opChain := s.chain.enter("IsEqualFold()")
  220. defer opChain.leave()
  221. if opChain.failed() {
  222. return s
  223. }
  224. if !strings.EqualFold(s.value, value) {
  225. opChain.fail(AssertionFailure{
  226. Type: AssertEqual,
  227. Actual: &AssertionValue{s.value},
  228. Expected: &AssertionValue{value},
  229. Errors: []error{
  230. errors.New("expected: strings are equal (if folded)"),
  231. },
  232. })
  233. }
  234. return s
  235. }
  236. // NotEqualFold succeeds if string is not equal to given Go string after applying
  237. // Unicode case-folding (so it's a case-insensitive match).
  238. //
  239. // Example:
  240. //
  241. // str := NewString(t, "Hello")
  242. // str.NotEqualFold("gOODBYe")
  243. func (s *String) NotEqualFold(value string) *String {
  244. opChain := s.chain.enter("NotEqualFold()")
  245. defer opChain.leave()
  246. if opChain.failed() {
  247. return s
  248. }
  249. if strings.EqualFold(s.value, value) {
  250. opChain.fail(AssertionFailure{
  251. Type: AssertNotEqual,
  252. Actual: &AssertionValue{s.value},
  253. Expected: &AssertionValue{value},
  254. Errors: []error{
  255. errors.New("expected: strings are non-equal (if folded)"),
  256. },
  257. })
  258. }
  259. return s
  260. }
  261. // Deprecated: use IsEqualFold instead.
  262. func (s *String) EqualFold(value string) *String {
  263. return s.IsEqualFold(value)
  264. }
  265. // InList succeeds if the string is equal to one of the values from given
  266. // list of strings.
  267. //
  268. // Example:
  269. //
  270. // str := NewString(t, "Hello")
  271. // str.InList("Hello", "Goodbye")
  272. func (s *String) InList(values ...string) *String {
  273. opChain := s.chain.enter("InList()")
  274. defer opChain.leave()
  275. if opChain.failed() {
  276. return s
  277. }
  278. if len(values) == 0 {
  279. opChain.fail(AssertionFailure{
  280. Type: AssertUsage,
  281. Errors: []error{
  282. errors.New("unexpected empty list argument"),
  283. },
  284. })
  285. return s
  286. }
  287. var isListed bool
  288. for _, v := range values {
  289. if s.value == v {
  290. isListed = true
  291. break
  292. }
  293. }
  294. if !isListed {
  295. valueList := make([]interface{}, 0, len(values))
  296. for _, v := range values {
  297. valueList = append(valueList, v)
  298. }
  299. opChain.fail(AssertionFailure{
  300. Type: AssertBelongs,
  301. Actual: &AssertionValue{s.value},
  302. Expected: &AssertionValue{AssertionList(valueList)},
  303. Errors: []error{
  304. errors.New("expected: string is equal to one of the values"),
  305. },
  306. })
  307. }
  308. return s
  309. }
  310. // NotInList succeeds if the string is not equal to any of the values from
  311. // given list of strings.
  312. //
  313. // Example:
  314. //
  315. // str := NewString(t, "Hello")
  316. // str.NotInList("Sayonara", "Goodbye")
  317. func (s *String) NotInList(values ...string) *String {
  318. opChain := s.chain.enter("NotInList()")
  319. defer opChain.leave()
  320. if opChain.failed() {
  321. return s
  322. }
  323. if len(values) == 0 {
  324. opChain.fail(AssertionFailure{
  325. Type: AssertUsage,
  326. Errors: []error{
  327. errors.New("unexpected empty list argument"),
  328. },
  329. })
  330. return s
  331. }
  332. for _, v := range values {
  333. if s.value == v {
  334. valueList := make([]interface{}, 0, len(values))
  335. for _, v := range values {
  336. valueList = append(valueList, v)
  337. }
  338. opChain.fail(AssertionFailure{
  339. Type: AssertNotBelongs,
  340. Actual: &AssertionValue{s.value},
  341. Expected: &AssertionValue{AssertionList(valueList)},
  342. Errors: []error{
  343. errors.New("expected: string is not equal to any of the values"),
  344. },
  345. })
  346. return s
  347. }
  348. }
  349. return s
  350. }
  351. // InListFold succeeds if the string is equal to one of the values from given
  352. // list of strings after applying Unicode case-folding (so it's a case-insensitive match).
  353. //
  354. // Example:
  355. //
  356. // str := NewString(t, "Hello")
  357. // str.InListFold("hEllo", "Goodbye")
  358. func (s *String) InListFold(values ...string) *String {
  359. opChain := s.chain.enter("InListFold()")
  360. defer opChain.leave()
  361. if opChain.failed() {
  362. return s
  363. }
  364. if len(values) == 0 {
  365. opChain.fail(AssertionFailure{
  366. Type: AssertUsage,
  367. Errors: []error{
  368. errors.New("unexpected empty list argument"),
  369. },
  370. })
  371. return s
  372. }
  373. var isListed bool
  374. for _, v := range values {
  375. if strings.EqualFold(s.value, v) {
  376. isListed = true
  377. break
  378. }
  379. }
  380. if !isListed {
  381. valueList := make([]interface{}, 0, len(values))
  382. for _, v := range values {
  383. valueList = append(valueList, v)
  384. }
  385. opChain.fail(AssertionFailure{
  386. Type: AssertBelongs,
  387. Actual: &AssertionValue{s.value},
  388. Expected: &AssertionValue{AssertionList(valueList)},
  389. Errors: []error{
  390. errors.New("expected: string is equal to one of the values (if folded)"),
  391. },
  392. })
  393. }
  394. return s
  395. }
  396. // NotInListFold succeeds if the string is not equal to any of the values from given
  397. // list of strings after applying Unicode case-folding (so it's a case-insensitive match).
  398. //
  399. // Example:
  400. //
  401. // str := NewString(t, "Hello")
  402. // str.NotInListFold("Bye", "Goodbye")
  403. func (s *String) NotInListFold(values ...string) *String {
  404. opChain := s.chain.enter("NotInListFold()")
  405. defer opChain.leave()
  406. if opChain.failed() {
  407. return s
  408. }
  409. if len(values) == 0 {
  410. opChain.fail(AssertionFailure{
  411. Type: AssertUsage,
  412. Errors: []error{
  413. errors.New("unexpected empty list argument"),
  414. },
  415. })
  416. return s
  417. }
  418. for _, v := range values {
  419. if strings.EqualFold(s.value, v) {
  420. valueList := make([]interface{}, 0, len(values))
  421. for _, v := range values {
  422. valueList = append(valueList, v)
  423. }
  424. opChain.fail(AssertionFailure{
  425. Type: AssertNotBelongs,
  426. Actual: &AssertionValue{s.value},
  427. Expected: &AssertionValue{AssertionList(valueList)},
  428. Errors: []error{
  429. errors.New("expected: string is not equal to any of the values (if folded)"),
  430. },
  431. })
  432. return s
  433. }
  434. }
  435. return s
  436. }
  437. // Contains succeeds if string contains given Go string as a substring.
  438. //
  439. // Example:
  440. //
  441. // str := NewString(t, "Hello")
  442. // str.Contains("ell")
  443. func (s *String) Contains(value string) *String {
  444. opChain := s.chain.enter("Contains()")
  445. defer opChain.leave()
  446. if opChain.failed() {
  447. return s
  448. }
  449. if !strings.Contains(s.value, value) {
  450. opChain.fail(AssertionFailure{
  451. Type: AssertContainsSubset,
  452. Actual: &AssertionValue{s.value},
  453. Expected: &AssertionValue{value},
  454. Errors: []error{
  455. errors.New("expected: string contains sub-string"),
  456. },
  457. })
  458. }
  459. return s
  460. }
  461. // NotContains succeeds if string doesn't contain Go string as a substring.
  462. //
  463. // Example:
  464. //
  465. // str := NewString(t, "Hello")
  466. // str.NotContains("bye")
  467. func (s *String) NotContains(value string) *String {
  468. opChain := s.chain.enter("NotContains()")
  469. defer opChain.leave()
  470. if opChain.failed() {
  471. return s
  472. }
  473. if strings.Contains(s.value, value) {
  474. opChain.fail(AssertionFailure{
  475. Type: AssertNotContainsSubset,
  476. Actual: &AssertionValue{s.value},
  477. Expected: &AssertionValue{value},
  478. Errors: []error{
  479. errors.New("expected: string does not contain sub-string"),
  480. },
  481. })
  482. }
  483. return s
  484. }
  485. // ContainsFold succeeds if string contains given Go string as a substring after
  486. // applying Unicode case-folding (so it's a case-insensitive match).
  487. //
  488. // Example:
  489. //
  490. // str := NewString(t, "Hello")
  491. // str.ContainsFold("ELL")
  492. func (s *String) ContainsFold(value string) *String {
  493. opChain := s.chain.enter("ContainsFold()")
  494. defer opChain.leave()
  495. if opChain.failed() {
  496. return s
  497. }
  498. if !strings.Contains(strings.ToLower(s.value), strings.ToLower(value)) {
  499. opChain.fail(AssertionFailure{
  500. Type: AssertContainsSubset,
  501. Actual: &AssertionValue{s.value},
  502. Expected: &AssertionValue{value},
  503. Errors: []error{
  504. errors.New("expected: string contains sub-string (if folded)"),
  505. },
  506. })
  507. }
  508. return s
  509. }
  510. // NotContainsFold succeeds if string doesn't contain given Go string as a substring
  511. // after applying Unicode case-folding (so it's a case-insensitive match).
  512. //
  513. // Example:
  514. //
  515. // str := NewString(t, "Hello")
  516. // str.NotContainsFold("BYE")
  517. func (s *String) NotContainsFold(value string) *String {
  518. opChain := s.chain.enter("NotContainsFold()")
  519. defer opChain.leave()
  520. if opChain.failed() {
  521. return s
  522. }
  523. if strings.Contains(strings.ToLower(s.value), strings.ToLower(value)) {
  524. opChain.fail(AssertionFailure{
  525. Type: AssertNotContainsSubset,
  526. Actual: &AssertionValue{s.value},
  527. Expected: &AssertionValue{value},
  528. Errors: []error{
  529. errors.New("expected: string does not contain sub-string (if folded)"),
  530. },
  531. })
  532. }
  533. return s
  534. }
  535. // HasPrefix succeeds if string has given Go string as prefix
  536. //
  537. // Example:
  538. //
  539. // str := NewString(t, "Hello World")
  540. // str.HasPrefix("Hello")
  541. func (s *String) HasPrefix(value string) *String {
  542. opChain := s.chain.enter("HasPrefix()")
  543. defer opChain.leave()
  544. if opChain.failed() {
  545. return s
  546. }
  547. if !strings.HasPrefix(s.value, value) {
  548. opChain.fail(AssertionFailure{
  549. Type: AssertContainsSubset,
  550. Actual: &AssertionValue{s.value},
  551. Expected: &AssertionValue{value},
  552. Errors: []error{
  553. errors.New("expected: string has prefix"),
  554. },
  555. })
  556. }
  557. return s
  558. }
  559. // NotHasPrefix succeeds if string doesn't have given Go string as prefix
  560. //
  561. // Example:
  562. //
  563. // str := NewString(t, "Hello World")
  564. // str.NotHasPrefix("Bye")
  565. func (s *String) NotHasPrefix(value string) *String {
  566. opChain := s.chain.enter("NotHasPrefix()")
  567. defer opChain.leave()
  568. if opChain.failed() {
  569. return s
  570. }
  571. if strings.HasPrefix(s.value, value) {
  572. opChain.fail(AssertionFailure{
  573. Type: AssertNotContainsSubset,
  574. Actual: &AssertionValue{s.value},
  575. Expected: &AssertionValue{value},
  576. Errors: []error{
  577. errors.New("expected: string doesn't have prefix"),
  578. },
  579. })
  580. }
  581. return s
  582. }
  583. // HasSuffix succeeds if string has given Go string as suffix
  584. //
  585. // Example:
  586. //
  587. // str := NewString(t, "Hello World")
  588. // str.HasSuffix("World")
  589. func (s *String) HasSuffix(value string) *String {
  590. opChain := s.chain.enter("HasSuffix()")
  591. defer opChain.leave()
  592. if opChain.failed() {
  593. return s
  594. }
  595. if !strings.HasSuffix(s.value, value) {
  596. opChain.fail(AssertionFailure{
  597. Type: AssertContainsSubset,
  598. Actual: &AssertionValue{s.value},
  599. Expected: &AssertionValue{value},
  600. Errors: []error{
  601. errors.New("expected: string has suffix"),
  602. },
  603. })
  604. }
  605. return s
  606. }
  607. // NotHasSuffix succeeds if string doesn't have given Go string as suffix
  608. //
  609. // Example:
  610. //
  611. // str := NewString(t, "Hello World")
  612. // str.NotHasSuffix("Hello")
  613. func (s *String) NotHasSuffix(value string) *String {
  614. opChain := s.chain.enter("NotHasSuffix()")
  615. defer opChain.leave()
  616. if opChain.failed() {
  617. return s
  618. }
  619. if strings.HasSuffix(s.value, value) {
  620. opChain.fail(AssertionFailure{
  621. Type: AssertNotContainsSubset,
  622. Actual: &AssertionValue{s.value},
  623. Expected: &AssertionValue{value},
  624. Errors: []error{
  625. errors.New("expected: string doesn't have suffix"),
  626. },
  627. })
  628. }
  629. return s
  630. }
  631. // HasPrefixFold succeeds if string has given Go string as prefix
  632. // after applying Unicode case-folding (so it's a case-insensitive match).
  633. //
  634. // Example:
  635. //
  636. // str := NewString(t, "Hello World")
  637. // str.HasPrefixFold("hello")
  638. func (s *String) HasPrefixFold(value string) *String {
  639. opChain := s.chain.enter("HasPrefixFold()")
  640. defer opChain.leave()
  641. if opChain.failed() {
  642. return s
  643. }
  644. if !strings.HasPrefix(strings.ToLower(s.value), strings.ToLower(value)) {
  645. opChain.fail(AssertionFailure{
  646. Type: AssertContainsSubset,
  647. Actual: &AssertionValue{s.value},
  648. Expected: &AssertionValue{value},
  649. Errors: []error{
  650. errors.New("expected: string has prefix (if folded)"),
  651. },
  652. })
  653. }
  654. return s
  655. }
  656. // NotHasPrefixFold succeeds if string doesn't have given Go string as prefix
  657. // after applying Unicode case-folding (so it's a case-insensitive match).
  658. //
  659. // Example:
  660. //
  661. // str := NewString(t, "Hello World")
  662. // str.NotHasPrefixFold("Bye")
  663. func (s *String) NotHasPrefixFold(value string) *String {
  664. opChain := s.chain.enter("NotHasPrefixFold()")
  665. defer opChain.leave()
  666. if opChain.failed() {
  667. return s
  668. }
  669. if strings.HasPrefix(strings.ToLower(s.value), strings.ToLower(value)) {
  670. opChain.fail(AssertionFailure{
  671. Type: AssertNotContainsSubset,
  672. Actual: &AssertionValue{s.value},
  673. Expected: &AssertionValue{value},
  674. Errors: []error{
  675. errors.New("expected: string doesn't have prefix (if folded)"),
  676. },
  677. })
  678. }
  679. return s
  680. }
  681. // HasSuffixFold succeeds if string has given Go string as suffix
  682. // after applying Unicode case-folding (so it's a case-insensitive match).
  683. //
  684. // Example:
  685. //
  686. // str := NewString(t, "Hello World")
  687. // str.HasSuffixFold("world")
  688. func (s *String) HasSuffixFold(value string) *String {
  689. opChain := s.chain.enter("HasSuffixFold()")
  690. defer opChain.leave()
  691. if opChain.failed() {
  692. return s
  693. }
  694. if !strings.HasSuffix(strings.ToLower(s.value), strings.ToLower(value)) {
  695. opChain.fail(AssertionFailure{
  696. Type: AssertContainsSubset,
  697. Actual: &AssertionValue{s.value},
  698. Expected: &AssertionValue{value},
  699. Errors: []error{
  700. errors.New("expected: string has suffix (if folded)"),
  701. },
  702. })
  703. }
  704. return s
  705. }
  706. // NotHasSuffixFold succeeds if string doesn't have given Go string as suffix
  707. // after applying Unicode case-folding (so it's a case-insensitive match).
  708. //
  709. // Example:
  710. //
  711. // str := NewString(t, "Hello World")
  712. // str.NotHasSuffixFold("Bye")
  713. func (s *String) NotHasSuffixFold(value string) *String {
  714. opChain := s.chain.enter("NotHasSuffix()")
  715. defer opChain.leave()
  716. if opChain.failed() {
  717. return s
  718. }
  719. if strings.HasSuffix(strings.ToLower(s.value), strings.ToLower(value)) {
  720. opChain.fail(AssertionFailure{
  721. Type: AssertNotContainsSubset,
  722. Actual: &AssertionValue{s.value},
  723. Expected: &AssertionValue{value},
  724. Errors: []error{
  725. errors.New("expected: string doesn't have suffix (if folded)"),
  726. },
  727. })
  728. }
  729. return s
  730. }
  731. // Match matches the string with given regexp and returns a new Match instance
  732. // with found submatches.
  733. //
  734. // If regexp is invalid or string doesn't match regexp, Match fails and returns
  735. // empty (but non-nil) instance. regexp.Compile is used to construct regexp, and
  736. // Regexp.FindStringSubmatch is used to construct matches.
  737. //
  738. // Example:
  739. //
  740. // s := NewString(t, "http://example.com/users/john")
  741. // m := s.Match(`http://(?P<host>.+)/users/(?P<user>.+)`)
  742. //
  743. // m.NotEmpty()
  744. // m.Length().IsEqual(3)
  745. //
  746. // m.Index(0).IsEqual("http://example.com/users/john")
  747. // m.Index(1).IsEqual("example.com")
  748. // m.Index(2).IsEqual("john")
  749. //
  750. // m.Name("host").IsEqual("example.com")
  751. // m.Name("user").IsEqual("john")
  752. func (s *String) Match(re string) *Match {
  753. opChain := s.chain.enter("Match()")
  754. defer opChain.leave()
  755. if opChain.failed() {
  756. return newMatch(opChain, nil, nil)
  757. }
  758. rx, err := regexp.Compile(re)
  759. if err != nil {
  760. opChain.fail(AssertionFailure{
  761. Type: AssertValid,
  762. Actual: &AssertionValue{re},
  763. Errors: []error{
  764. errors.New("expected: valid regexp"),
  765. err,
  766. },
  767. })
  768. return newMatch(opChain, nil, nil)
  769. }
  770. match := rx.FindStringSubmatch(s.value)
  771. if match == nil {
  772. opChain.fail(AssertionFailure{
  773. Type: AssertMatchRegexp,
  774. Actual: &AssertionValue{s.value},
  775. Expected: &AssertionValue{re},
  776. Errors: []error{
  777. errors.New("expected: string matches regexp"),
  778. },
  779. })
  780. return newMatch(opChain, nil, nil)
  781. }
  782. return newMatch(opChain, match, rx.SubexpNames())
  783. }
  784. // NotMatch succeeds if the string doesn't match to given regexp.
  785. //
  786. // regexp.Compile is used to construct regexp, and Regexp.MatchString
  787. // is used to perform match.
  788. //
  789. // Example:
  790. //
  791. // s := NewString(t, "a")
  792. // s.NotMatch(`[^a]`)
  793. func (s *String) NotMatch(re string) *String {
  794. opChain := s.chain.enter("NotMatch()")
  795. defer opChain.leave()
  796. rx, err := regexp.Compile(re)
  797. if err != nil {
  798. opChain.fail(AssertionFailure{
  799. Type: AssertValid,
  800. Actual: &AssertionValue{re},
  801. Errors: []error{
  802. errors.New("expected: valid regexp"),
  803. err,
  804. },
  805. })
  806. return s
  807. }
  808. if rx.MatchString(s.value) {
  809. opChain.fail(AssertionFailure{
  810. Type: AssertNotMatchRegexp,
  811. Actual: &AssertionValue{s.value},
  812. Expected: &AssertionValue{re},
  813. Errors: []error{
  814. errors.New("expected: string does not match regexp"),
  815. },
  816. })
  817. return s
  818. }
  819. return s
  820. }
  821. // MatchAll find all matches in string for given regexp and returns a list
  822. // of found matches.
  823. //
  824. // If regexp is invalid or string doesn't match regexp, MatchAll fails and
  825. // returns empty (but non-nil) slice. regexp.Compile is used to construct
  826. // regexp, and Regexp.FindAllStringSubmatch is used to find matches.
  827. //
  828. // Example:
  829. //
  830. // s := NewString(t,
  831. // "http://example.com/users/john http://example.com/users/bob")
  832. //
  833. // m := s.MatchAll(`http://(?P<host>\S+)/users/(?P<user>\S+)`)
  834. //
  835. // m[0].Name("user").IsEqual("john")
  836. // m[1].Name("user").IsEqual("bob")
  837. func (s *String) MatchAll(re string) []Match {
  838. opChain := s.chain.enter("MatchAll()")
  839. defer opChain.leave()
  840. if opChain.failed() {
  841. return []Match{}
  842. }
  843. rx, err := regexp.Compile(re)
  844. if err != nil {
  845. opChain.fail(AssertionFailure{
  846. Type: AssertValid,
  847. Actual: &AssertionValue{re},
  848. Errors: []error{
  849. errors.New("expected: valid regexp"),
  850. err,
  851. },
  852. })
  853. return []Match{}
  854. }
  855. matches := rx.FindAllStringSubmatch(s.value, -1)
  856. if matches == nil {
  857. opChain.fail(AssertionFailure{
  858. Type: AssertMatchRegexp,
  859. Actual: &AssertionValue{s.value},
  860. Expected: &AssertionValue{re},
  861. Errors: []error{
  862. errors.New("expected: string matches regexp"),
  863. },
  864. })
  865. return []Match{}
  866. }
  867. ret := []Match{}
  868. for _, match := range matches {
  869. ret = append(ret, *newMatch(
  870. opChain,
  871. match,
  872. rx.SubexpNames()))
  873. }
  874. return ret
  875. }
  876. // IsASCII succeeds if all string characters belongs to ASCII.
  877. //
  878. // Example:
  879. //
  880. // str := NewString(t, "Hello")
  881. // str.IsASCII()
  882. func (s *String) IsASCII() *String {
  883. opChain := s.chain.enter("IsASCII()")
  884. defer opChain.leave()
  885. if opChain.failed() {
  886. return s
  887. }
  888. isASCII := true
  889. for _, c := range s.value {
  890. if c > unicode.MaxASCII {
  891. isASCII = false
  892. break
  893. }
  894. }
  895. if !isASCII {
  896. opChain.fail(AssertionFailure{
  897. Type: AssertValid,
  898. Actual: &AssertionValue{s.value},
  899. Errors: []error{
  900. errors.New("expected: all string characters are ascii"),
  901. },
  902. })
  903. }
  904. return s
  905. }
  906. // NotASCII succeeds if at least one string character does not belong to ASCII.
  907. //
  908. // Example:
  909. //
  910. // str := NewString(t, "こんにちは")
  911. // str.NotASCII()
  912. func (s *String) NotASCII() *String {
  913. opChain := s.chain.enter("NotASCII()")
  914. defer opChain.leave()
  915. if opChain.failed() {
  916. return s
  917. }
  918. isASCII := true
  919. for _, c := range s.value {
  920. if c > unicode.MaxASCII {
  921. isASCII = false
  922. break
  923. }
  924. }
  925. if isASCII {
  926. opChain.fail(AssertionFailure{
  927. Type: AssertValid,
  928. Actual: &AssertionValue{s.value},
  929. Errors: []error{
  930. errors.New("expected: at least one string character is not ascii"),
  931. },
  932. })
  933. }
  934. return s
  935. }
  936. // Deprecated: use NotASCII instead.
  937. func (s *String) NotIsASCII() *String {
  938. return s.NotASCII()
  939. }
  940. // AsNumber parses float from string and returns a new Number instance
  941. // with result.
  942. //
  943. // If base is 10 or omitted, uses strconv.ParseFloat.
  944. // Otherwise, uses strconv.ParseInt or strconv.ParseUint with given base.
  945. //
  946. // Example:
  947. //
  948. // str := NewString(t, "100")
  949. // str.AsNumber().IsEqual(100)
  950. //
  951. // Specifying base:
  952. //
  953. // str.AsNumber(10).IsEqual(100)
  954. // str.AsNumber(16).IsEqual(256)
  955. func (s *String) AsNumber(base ...int) *Number {
  956. opChain := s.chain.enter("AsNumber()")
  957. defer opChain.leave()
  958. if opChain.failed() {
  959. return newNumber(opChain, 0)
  960. }
  961. if len(base) > 1 {
  962. opChain.fail(AssertionFailure{
  963. Type: AssertUsage,
  964. Errors: []error{
  965. errors.New("unexpected multiple base arguments"),
  966. },
  967. })
  968. return newNumber(opChain, 0)
  969. }
  970. b := 10
  971. if len(base) != 0 {
  972. b = base[0]
  973. }
  974. var fnum float64
  975. var inum int64
  976. var unum uint64
  977. var err error
  978. inum, err = strconv.ParseInt(s.value, b, 64)
  979. fnum = float64(inum)
  980. if err == nil && int64(fnum) != inum {
  981. opChain.fail(AssertionFailure{
  982. Type: AssertValid,
  983. Actual: &AssertionValue{s.value},
  984. Errors: []error{
  985. errors.New("expected:" +
  986. " number can be represented as float64 without precision loss"),
  987. },
  988. })
  989. return newNumber(opChain, 0)
  990. }
  991. if err != nil && errors.Is(err, strconv.ErrRange) {
  992. unum, err = strconv.ParseUint(s.value, b, 64)
  993. fnum = float64(unum)
  994. if err == nil && uint64(fnum) != unum {
  995. opChain.fail(AssertionFailure{
  996. Type: AssertValid,
  997. Actual: &AssertionValue{s.value},
  998. Errors: []error{
  999. errors.New("expected:" +
  1000. " number can be represented as float64 without precision loss"),
  1001. },
  1002. })
  1003. return newNumber(opChain, 0)
  1004. }
  1005. }
  1006. if err != nil && b == 10 {
  1007. fnum, err = strconv.ParseFloat(s.value, 64)
  1008. }
  1009. if err != nil {
  1010. if b == 10 {
  1011. opChain.fail(AssertionFailure{
  1012. Type: AssertValid,
  1013. Actual: &AssertionValue{s.value},
  1014. Errors: []error{
  1015. errors.New("expected: string can be parsed to integer or float"),
  1016. err,
  1017. },
  1018. })
  1019. } else {
  1020. opChain.fail(AssertionFailure{
  1021. Type: AssertValid,
  1022. Actual: &AssertionValue{s.value},
  1023. Errors: []error{
  1024. fmt.Errorf(
  1025. "expected: string can be parsed to integer with base %d",
  1026. base[0]),
  1027. err,
  1028. },
  1029. })
  1030. }
  1031. return newNumber(opChain, 0)
  1032. }
  1033. return newNumber(opChain, fnum)
  1034. }
  1035. // AsBoolean parses true/false value string and returns a new Boolean instance
  1036. // with result.
  1037. //
  1038. // Accepts string values "true", "True", "false", "False".
  1039. //
  1040. // Example:
  1041. //
  1042. // str := NewString(t, "true")
  1043. // str.AsBoolean().IsTrue()
  1044. func (s *String) AsBoolean() *Boolean {
  1045. opChain := s.chain.enter("AsBoolean()")
  1046. defer opChain.leave()
  1047. if opChain.failed() {
  1048. return newBoolean(opChain, false)
  1049. }
  1050. switch s.value {
  1051. case "true", "True":
  1052. return newBoolean(opChain, true)
  1053. case "false", "False":
  1054. return newBoolean(opChain, false)
  1055. }
  1056. opChain.fail(AssertionFailure{
  1057. Type: AssertValid,
  1058. Actual: &AssertionValue{s.value},
  1059. Errors: []error{
  1060. errors.New("expected: string can be parsed to boolean"),
  1061. },
  1062. })
  1063. return newBoolean(opChain, false)
  1064. }
  1065. // AsDateTime parses date/time from string and returns a new DateTime instance
  1066. // with result.
  1067. //
  1068. // If format is given, AsDateTime() uses time.Parse() with every given format.
  1069. // Otherwise, it uses the list of predefined common formats.
  1070. //
  1071. // If the string can't be parsed with any format, AsDateTime reports failure
  1072. // and returns empty (but non-nil) instance.
  1073. //
  1074. // Example:
  1075. //
  1076. // str := NewString(t, "Tue, 15 Nov 1994 08:12:31 GMT")
  1077. // str.AsDateTime().Lt(time.Now())
  1078. //
  1079. // str := NewString(t, "15 Nov 94 08:12 GMT")
  1080. // str.AsDateTime(time.RFC822).Lt(time.Now())
  1081. func (s *String) AsDateTime(format ...string) *DateTime {
  1082. opChain := s.chain.enter("AsDateTime()")
  1083. defer opChain.leave()
  1084. if opChain.failed() {
  1085. return newDateTime(opChain, time.Unix(0, 0))
  1086. }
  1087. var formatList []datetimeFormat
  1088. if len(format) != 0 {
  1089. for _, f := range format {
  1090. formatList = append(formatList, datetimeFormat{layout: f})
  1091. }
  1092. } else {
  1093. formatList = []datetimeFormat{
  1094. {http.TimeFormat, "RFC1123+GMT"},
  1095. {time.RFC850, "RFC850"},
  1096. {time.ANSIC, "ANSIC"},
  1097. {time.UnixDate, "Unix"},
  1098. {time.RubyDate, "Ruby"},
  1099. {time.RFC1123, "RFC1123"},
  1100. {time.RFC1123Z, "RFC1123Z"},
  1101. {time.RFC822, "RFC822"},
  1102. {time.RFC822Z, "RFC822Z"},
  1103. {time.RFC3339, "RFC3339"},
  1104. {time.RFC3339Nano, "RFC3339+nano"},
  1105. }
  1106. }
  1107. var (
  1108. tm time.Time
  1109. err error
  1110. )
  1111. for _, f := range formatList {
  1112. tm, err = time.Parse(f.layout, s.value)
  1113. if err == nil {
  1114. break
  1115. }
  1116. }
  1117. if err != nil {
  1118. if len(formatList) == 1 {
  1119. opChain.fail(AssertionFailure{
  1120. Type: AssertMatchFormat,
  1121. Actual: &AssertionValue{s.value},
  1122. Expected: &AssertionValue{formatList[0]},
  1123. Errors: []error{
  1124. errors.New("expected: string can be parsed to datetime" +
  1125. " with given format"),
  1126. },
  1127. })
  1128. } else {
  1129. var expectedFormats []interface{}
  1130. for _, f := range formatList {
  1131. expectedFormats = append(expectedFormats, f)
  1132. }
  1133. opChain.fail(AssertionFailure{
  1134. Type: AssertMatchFormat,
  1135. Actual: &AssertionValue{s.value},
  1136. Expected: &AssertionValue{AssertionList(expectedFormats)},
  1137. Errors: []error{
  1138. errors.New("expected: string can be parsed to datetime" +
  1139. " with one of the formats from list"),
  1140. },
  1141. })
  1142. }
  1143. return newDateTime(opChain, time.Unix(0, 0))
  1144. }
  1145. return newDateTime(opChain, tm)
  1146. }
  1147. type datetimeFormat struct {
  1148. layout string
  1149. name string
  1150. }
  1151. func (f datetimeFormat) String() string {
  1152. if f.name != "" {
  1153. return fmt.Sprintf("%q (%s)", f.layout, f.name)
  1154. } else {
  1155. return fmt.Sprintf("%q", f.layout)
  1156. }
  1157. }
  1158. // Deprecated: use AsNumber instead.
  1159. func (s *String) Number() *Number {
  1160. return s.AsNumber()
  1161. }
  1162. // Deprecated: use AsDateTime instead.
  1163. func (s *String) DateTime(layout ...string) *DateTime {
  1164. return s.AsDateTime(layout...)
  1165. }