object.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. package httpexpect
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. "sort"
  7. )
  8. // Object provides methods to inspect attached map[string]interface{} object
  9. // (Go representation of JSON object).
  10. type Object struct {
  11. noCopy noCopy
  12. chain *chain
  13. value map[string]interface{}
  14. }
  15. // NewObject returns a new Object instance.
  16. //
  17. // If reporter is nil, the function panics.
  18. // If value is nil, failure is reported.
  19. //
  20. // Example:
  21. //
  22. // object := NewObject(t, map[string]interface{}{"foo": 123})
  23. func NewObject(reporter Reporter, value map[string]interface{}) *Object {
  24. return newObject(newChainWithDefaults("Object()", reporter), value)
  25. }
  26. // NewObjectC returns a new Object instance with config.
  27. //
  28. // Requirements for config are same as for WithConfig function.
  29. // If value is nil, failure is reported.
  30. //
  31. // Example:
  32. //
  33. // object := NewObjectC(config, map[string]interface{}{"foo": 123})
  34. func NewObjectC(config Config, value map[string]interface{}) *Object {
  35. return newObject(newChainWithConfig("Object()", config.withDefaults()), value)
  36. }
  37. func newObject(parent *chain, val map[string]interface{}) *Object {
  38. o := &Object{chain: parent.clone(), value: nil}
  39. opChain := o.chain.enter("")
  40. defer opChain.leave()
  41. if val == nil {
  42. opChain.fail(AssertionFailure{
  43. Type: AssertNotNil,
  44. Actual: &AssertionValue{val},
  45. Errors: []error{
  46. errors.New("expected: non-nil map"),
  47. },
  48. })
  49. } else {
  50. o.value, _ = canonMap(opChain, val)
  51. }
  52. return o
  53. }
  54. // Raw returns underlying value attached to Object.
  55. // This is the value originally passed to NewObject, converted to canonical form.
  56. //
  57. // Example:
  58. //
  59. // object := NewObject(t, map[string]interface{}{"foo": 123})
  60. // assert.Equal(t, map[string]interface{}{"foo": 123.0}, object.Raw())
  61. func (o *Object) Raw() map[string]interface{} {
  62. return o.value
  63. }
  64. // Decode unmarshals the underlying value attached to the Object to a target variable
  65. // target should be one of this:
  66. //
  67. // - pointer to an empty interface
  68. // - pointer to a map
  69. // - pointer to a struct
  70. //
  71. // Example:
  72. //
  73. // type S struct{
  74. // Foo int `json:"foo"`
  75. // Bar []interface{} `json:"bar"`
  76. // Baz map[string]interface{} `json:"baz"`
  77. // Bat struct{ A int } `json:"bat"`
  78. // }
  79. //
  80. // m := map[string]interface{}{
  81. // "foo": 123,
  82. // "bar": []interface{}{"123", 234.0},
  83. // "baz": map[string]interface{}{
  84. // "a": "b",
  85. // },
  86. // "bat": struct{ A int }{123},
  87. // }
  88. //
  89. // value := NewObject(t, value)
  90. //
  91. // var target S
  92. // value.Decode(&target)
  93. //
  94. // assert.Equal(t, S{123,[]interface{}{"123", 234.0},
  95. // map[string]interface{}{"a": "b"}, struct{ A int }{123},
  96. // }, target)
  97. func (o *Object) Decode(target interface{}) *Object {
  98. opChain := o.chain.enter("Decode()")
  99. defer opChain.leave()
  100. if opChain.failed() {
  101. return o
  102. }
  103. canonDecode(opChain, o.value, target)
  104. return o
  105. }
  106. // Alias is similar to Value.Alias.
  107. func (o *Object) Alias(name string) *Object {
  108. opChain := o.chain.enter("Alias(%q)", name)
  109. defer opChain.leave()
  110. o.chain.setAlias(name)
  111. return o
  112. }
  113. // Path is similar to Value.Path.
  114. func (o *Object) Path(path string) *Value {
  115. opChain := o.chain.enter("Path(%q)", path)
  116. defer opChain.leave()
  117. return jsonPath(opChain, o.value, path)
  118. }
  119. // Schema is similar to Value.Schema.
  120. func (o *Object) Schema(schema interface{}) *Object {
  121. opChain := o.chain.enter("Schema()")
  122. defer opChain.leave()
  123. jsonSchema(opChain, o.value, schema)
  124. return o
  125. }
  126. // Keys returns a new Array instance with object's keys.
  127. // Keys are sorted in ascending order.
  128. //
  129. // Example:
  130. //
  131. // object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
  132. // object.Keys().ContainsOnly("foo", "bar")
  133. func (o *Object) Keys() *Array {
  134. opChain := o.chain.enter("Keys()")
  135. defer opChain.leave()
  136. if opChain.failed() {
  137. return newArray(opChain, nil)
  138. }
  139. keys := []interface{}{}
  140. for _, kv := range o.sortedKV() {
  141. keys = append(keys, kv.key)
  142. }
  143. return newArray(opChain, keys)
  144. }
  145. // Values returns a new Array instance with object's values.
  146. // Values are sorted by keys ascending order.
  147. //
  148. // Example:
  149. //
  150. // object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
  151. // object.Values().ContainsOnly(123, 456)
  152. func (o *Object) Values() *Array {
  153. opChain := o.chain.enter("Values()")
  154. defer opChain.leave()
  155. if opChain.failed() {
  156. return newArray(opChain, nil)
  157. }
  158. values := []interface{}{}
  159. for _, kv := range o.sortedKV() {
  160. values = append(values, kv.val)
  161. }
  162. return newArray(opChain, values)
  163. }
  164. // Value returns a new Value instance with value for given key.
  165. //
  166. // Example:
  167. //
  168. // object := NewObject(t, map[string]interface{}{"foo": 123})
  169. // object.Value("foo").Number().IsEqual(123)
  170. func (o *Object) Value(key string) *Value {
  171. opChain := o.chain.enter("Value(%q)", key)
  172. defer opChain.leave()
  173. if opChain.failed() {
  174. return newValue(opChain, nil)
  175. }
  176. value, ok := o.value[key]
  177. if !ok {
  178. opChain.fail(AssertionFailure{
  179. Type: AssertContainsKey,
  180. Actual: &AssertionValue{o.value},
  181. Expected: &AssertionValue{key},
  182. Errors: []error{
  183. errors.New("expected: map contains key"),
  184. },
  185. })
  186. return newValue(opChain, nil)
  187. }
  188. return newValue(opChain, value)
  189. }
  190. // HasValue succeeds if object's value for given key is equal to given value.
  191. // Before comparison, both values are converted to canonical form.
  192. //
  193. // value should be map[string]interface{} or struct.
  194. //
  195. // Example:
  196. //
  197. // object := NewObject(t, map[string]interface{}{"foo": 123})
  198. // object.HasValue("foo", 123)
  199. func (o *Object) HasValue(key string, value interface{}) *Object {
  200. opChain := o.chain.enter("HasValue(%q)", key)
  201. defer opChain.leave()
  202. if opChain.failed() {
  203. return o
  204. }
  205. if !containsKey(opChain, o.value, key) {
  206. opChain.fail(AssertionFailure{
  207. Type: AssertContainsKey,
  208. Actual: &AssertionValue{o.value},
  209. Expected: &AssertionValue{key},
  210. Errors: []error{
  211. errors.New("expected: map contains key"),
  212. },
  213. })
  214. return o
  215. }
  216. expected, ok := canonValue(opChain, value)
  217. if !ok {
  218. return o
  219. }
  220. if !reflect.DeepEqual(expected, o.value[key]) {
  221. opChain.fail(AssertionFailure{
  222. Type: AssertEqual,
  223. Actual: &AssertionValue{o.value[key]},
  224. Expected: &AssertionValue{value},
  225. Errors: []error{
  226. fmt.Errorf(
  227. "expected: map value for key %q is equal to given value",
  228. key),
  229. },
  230. })
  231. return o
  232. }
  233. return o
  234. }
  235. // NotHasValue succeeds if object's value for given key is not equal to given
  236. // value. Before comparison, both values are converted to canonical form.
  237. //
  238. // value should be map[string]interface{} or struct.
  239. //
  240. // If object doesn't contain any value for given key, failure is reported.
  241. //
  242. // Example:
  243. //
  244. // object := NewObject(t, map[string]interface{}{"foo": 123})
  245. // object.NotHasValue("foo", "bad value") // success
  246. // object.NotHasValue("bar", "bad value") // failure! (key is missing)
  247. func (o *Object) NotHasValue(key string, value interface{}) *Object {
  248. opChain := o.chain.enter("NotHasValue(%q)", key)
  249. defer opChain.leave()
  250. if opChain.failed() {
  251. return o
  252. }
  253. if !containsKey(opChain, o.value, key) {
  254. opChain.fail(AssertionFailure{
  255. Type: AssertContainsKey,
  256. Actual: &AssertionValue{o.value},
  257. Expected: &AssertionValue{key},
  258. Errors: []error{
  259. errors.New("expected: map contains key"),
  260. },
  261. })
  262. return o
  263. }
  264. expected, ok := canonValue(opChain, value)
  265. if !ok {
  266. return o
  267. }
  268. if reflect.DeepEqual(expected, o.value[key]) {
  269. opChain.fail(AssertionFailure{
  270. Type: AssertNotEqual,
  271. Actual: &AssertionValue{o.value[key]},
  272. Expected: &AssertionValue{value},
  273. Errors: []error{
  274. fmt.Errorf(
  275. "expected: map value for key %q is non-equal to given value",
  276. key),
  277. },
  278. })
  279. return o
  280. }
  281. return o
  282. }
  283. // Deprecated: use HasValue instead.
  284. func (o *Object) ValueEqual(key string, value interface{}) *Object {
  285. return o.HasValue(key, value)
  286. }
  287. // Deprecated: use NotHasValue instead.
  288. func (o *Object) ValueNotEqual(key string, value interface{}) *Object {
  289. return o.NotHasValue(key, value)
  290. }
  291. // Iter returns a new map of Values attached to object elements.
  292. //
  293. // Example:
  294. //
  295. // numbers := map[string]interface{}{"foo": 123, "bar": 456}
  296. // object := NewObject(t, numbers)
  297. //
  298. // for key, value := range object.Iter() {
  299. // value.Number().IsEqual(numbers[key])
  300. // }
  301. func (o *Object) Iter() map[string]Value {
  302. opChain := o.chain.enter("Iter()")
  303. defer opChain.leave()
  304. if opChain.failed() {
  305. return map[string]Value{}
  306. }
  307. ret := map[string]Value{}
  308. for k, v := range o.value {
  309. func() {
  310. valueChain := opChain.replace("Iter[%q]", k)
  311. defer valueChain.leave()
  312. ret[k] = *newValue(valueChain, v)
  313. }()
  314. }
  315. return ret
  316. }
  317. // Every runs the passed function for all the key value pairs in the object.
  318. //
  319. // If assertion inside function fails, the original Object is marked failed.
  320. //
  321. // Every will execute the function for all values in the object irrespective
  322. // of assertion failures for some values in the object.
  323. //
  324. // The function is invoked for key value pairs sorted by keys in ascending order.
  325. //
  326. // Example:
  327. //
  328. // object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
  329. //
  330. // object.Every(func(key string, value *httpexpect.Value) {
  331. // value.String().NotEmpty()
  332. // })
  333. func (o *Object) Every(fn func(key string, value *Value)) *Object {
  334. opChain := o.chain.enter("Every()")
  335. defer opChain.leave()
  336. if opChain.failed() {
  337. return o
  338. }
  339. if fn == nil {
  340. opChain.fail(AssertionFailure{
  341. Type: AssertUsage,
  342. Errors: []error{
  343. errors.New("unexpected nil function argument"),
  344. },
  345. })
  346. return o
  347. }
  348. for _, kv := range o.sortedKV() {
  349. func() {
  350. valueChain := opChain.replace("Every[%q]", kv.key)
  351. defer valueChain.leave()
  352. fn(kv.key, newValue(valueChain, kv.val))
  353. }()
  354. }
  355. return o
  356. }
  357. // Filter accepts a function that returns a boolean. The function is ran
  358. // over the object elements. If the function returns true, the element passes
  359. // the filter and is added to the new object of filtered elements. If false,
  360. // the value is skipped (or in other words filtered out). After iterating
  361. // through all the elements of the original object, the new filtered object
  362. // is returned.
  363. //
  364. // If there are any failed assertions in the filtering function, the
  365. // element is omitted without causing test failure.
  366. //
  367. // The function is invoked for key value pairs sorted by keys in ascending order.
  368. //
  369. // Example:
  370. //
  371. // object := NewObject(t, map[string]interface{}{
  372. // "foo": "bar",
  373. // "baz": 6,
  374. // "qux": "quux",
  375. // })
  376. // filteredObject := object.Filter(func(key string, value *httpexpect.Value) bool {
  377. // value.String().NotEmpty() //fails on 6
  378. // return value.Raw() != "bar" //fails on "bar"
  379. // })
  380. // filteredObject.IsEqual(map[string]interface{}{"qux":"quux"}) //succeeds
  381. func (o *Object) Filter(fn func(key string, value *Value) bool) *Object {
  382. opChain := o.chain.enter("Filter()")
  383. defer opChain.leave()
  384. if opChain.failed() {
  385. return newObject(opChain, nil)
  386. }
  387. if fn == nil {
  388. opChain.fail(AssertionFailure{
  389. Type: AssertUsage,
  390. Errors: []error{
  391. errors.New("unexpected nil function argument"),
  392. },
  393. })
  394. return newObject(opChain, nil)
  395. }
  396. filteredObject := map[string]interface{}{}
  397. for _, kv := range o.sortedKV() {
  398. func() {
  399. valueChain := opChain.replace("Filter[%q]", kv.key)
  400. defer valueChain.leave()
  401. valueChain.setRoot()
  402. valueChain.setSeverity(SeverityLog)
  403. if fn(kv.key, newValue(valueChain, kv.val)) && !valueChain.treeFailed() {
  404. filteredObject[kv.key] = kv.val
  405. }
  406. }()
  407. }
  408. return newObject(opChain, filteredObject)
  409. }
  410. // Transform runs the passed function on all the elements in the Object
  411. // and returns a new object without effecting original object.
  412. //
  413. // The function is invoked for key value pairs sorted by keys in ascending order.
  414. //
  415. // Example:
  416. //
  417. // object := NewObject(t, []interface{}{"x": "foo", "y": "bar"})
  418. // transformedObject := object.Transform(
  419. // func(key string, value interface{}) interface{} {
  420. // return strings.ToUpper(value.(string))
  421. // })
  422. // transformedObject.IsEqual([]interface{}{"x": "FOO", "y": "BAR"})
  423. func (o *Object) Transform(fn func(key string, value interface{}) interface{}) *Object {
  424. opChain := o.chain.enter("Transform()")
  425. defer opChain.leave()
  426. if opChain.failed() {
  427. return newObject(opChain, nil)
  428. }
  429. if fn == nil {
  430. opChain.fail(AssertionFailure{
  431. Type: AssertUsage,
  432. Errors: []error{
  433. errors.New("unexpected nil function argument"),
  434. },
  435. })
  436. return newObject(opChain, nil)
  437. }
  438. transformedObject := map[string]interface{}{}
  439. for _, kv := range o.sortedKV() {
  440. transformedObject[kv.key] = fn(kv.key, kv.val)
  441. }
  442. return newObject(opChain, transformedObject)
  443. }
  444. // Find accepts a function that returns a boolean, runs it over the object
  445. // elements, and returns the first element on which it returned true.
  446. //
  447. // If there are any failed assertions in the predicate function, the
  448. // element is skipped without causing test failure.
  449. //
  450. // If no elements were found, a failure is reported.
  451. //
  452. // The function is invoked for key value pairs sorted by keys in ascending order.
  453. //
  454. // Example:
  455. //
  456. // object := NewObject(t, map[string]interface{}{
  457. // "a": 1,
  458. // "b": "foo",
  459. // "c": 101,
  460. // "d": "bar",
  461. // "e": 201,
  462. // })
  463. // foundValue := object.Find(func(key string, value *httpexpect.Value) bool {
  464. // num := value.Number() // skip if element is not a string
  465. // return num.Raw() > 100 // check element value
  466. // })
  467. // foundValue.IsEqual(101) // succeeds
  468. func (o *Object) Find(fn func(key string, value *Value) bool) *Value {
  469. opChain := o.chain.enter("Find()")
  470. defer opChain.leave()
  471. if opChain.failed() {
  472. return newValue(opChain, nil)
  473. }
  474. if fn == nil {
  475. opChain.fail(AssertionFailure{
  476. Type: AssertUsage,
  477. Errors: []error{
  478. errors.New("unexpected nil function argument"),
  479. },
  480. })
  481. return newValue(opChain, nil)
  482. }
  483. for _, kv := range o.sortedKV() {
  484. found := false
  485. func() {
  486. valueChain := opChain.replace("Find[%q]", kv.key)
  487. defer valueChain.leave()
  488. valueChain.setRoot()
  489. valueChain.setSeverity(SeverityLog)
  490. if fn(kv.key, newValue(valueChain, kv.val)) && !valueChain.treeFailed() {
  491. found = true
  492. }
  493. }()
  494. if found {
  495. return newValue(opChain, kv.val)
  496. }
  497. }
  498. opChain.fail(AssertionFailure{
  499. Type: AssertValid,
  500. Actual: &AssertionValue{o.value},
  501. Errors: []error{
  502. errors.New("expected: at least one object element matches predicate"),
  503. },
  504. })
  505. return newValue(opChain, nil)
  506. }
  507. // FindAll accepts a function that returns a boolean, runs it over the object
  508. // elements, and returns all the elements on which it returned true.
  509. //
  510. // If there are any failed assertions in the predicate function, the
  511. // element is skipped without causing test failure.
  512. //
  513. // If no elements were found, empty slice is returned without reporting error.
  514. //
  515. // The function is invoked for key value pairs sorted by keys in ascending order.
  516. //
  517. // Example:
  518. //
  519. // object := NewObject(t, map[string]interface{}{
  520. // "a": 1,
  521. // "b": "foo",
  522. // "c": 101,
  523. // "d": "bar",
  524. // "e": 201,
  525. // })
  526. // foundValues := object.FindAll(func(key string, value *httpexpect.Value) bool {
  527. // num := value.Number() // skip if element is not a string
  528. // return num.Raw() > 100 // check element value
  529. // })
  530. //
  531. // assert.Equal(t, len(foundValues), 2)
  532. // foundValues[0].IsEqual(101)
  533. // foundValues[1].IsEqual(201)
  534. func (o *Object) FindAll(fn func(key string, value *Value) bool) []*Value {
  535. opChain := o.chain.enter("FindAll()")
  536. defer opChain.leave()
  537. if opChain.failed() {
  538. return []*Value{}
  539. }
  540. if fn == nil {
  541. opChain.fail(AssertionFailure{
  542. Type: AssertUsage,
  543. Errors: []error{
  544. errors.New("unexpected nil function argument"),
  545. },
  546. })
  547. return []*Value{}
  548. }
  549. foundValues := make([]*Value, 0, len(o.value))
  550. for _, kv := range o.sortedKV() {
  551. func() {
  552. valueChain := opChain.replace("FindAll[%q]", kv.key)
  553. defer valueChain.leave()
  554. valueChain.setRoot()
  555. valueChain.setSeverity(SeverityLog)
  556. if fn(kv.key, newValue(valueChain, kv.val)) && !valueChain.treeFailed() {
  557. foundValues = append(foundValues, newValue(opChain, kv.val))
  558. }
  559. }()
  560. }
  561. return foundValues
  562. }
  563. // NotFind accepts a function that returns a boolean, runs it over the object
  564. // elelements, and checks that it does not return true for any of the elements.
  565. //
  566. // If there are any failed assertions in the predicate function, the
  567. // element is skipped without causing test failure.
  568. //
  569. // If the predicate function did not fail and returned true for at least
  570. // one element, a failure is reported.
  571. //
  572. // The function is invoked for key value pairs sorted by keys in ascending order.
  573. //
  574. // Example:
  575. //
  576. // object := NewObject(t, map[string]interface{}{
  577. // "a": 1,
  578. // "b": "foo",
  579. // "c": 2,
  580. // "d": "bar",
  581. // })
  582. // object.NotFind(func(key string, value *httpexpect.Value) bool {
  583. // num := value.Number() // skip if element is not a number
  584. // return num.Raw() > 100 // check element value
  585. // }) // succeeds
  586. func (o *Object) NotFind(fn func(key string, value *Value) bool) *Object {
  587. opChain := o.chain.enter("NotFind()")
  588. defer opChain.leave()
  589. if opChain.failed() {
  590. return o
  591. }
  592. if fn == nil {
  593. opChain.fail(AssertionFailure{
  594. Type: AssertUsage,
  595. Errors: []error{
  596. errors.New("unexpected nil function argument"),
  597. },
  598. })
  599. return o
  600. }
  601. for _, kv := range o.sortedKV() {
  602. found := false
  603. func() {
  604. valueChain := opChain.replace("NotFind[%q]", kv.key)
  605. defer valueChain.leave()
  606. valueChain.setRoot()
  607. valueChain.setSeverity(SeverityLog)
  608. if fn(kv.key, newValue(valueChain, kv.val)) && !valueChain.treeFailed() {
  609. found = true
  610. }
  611. }()
  612. if found {
  613. opChain.fail(AssertionFailure{
  614. Type: AssertNotContainsElement,
  615. Expected: &AssertionValue{kv.val},
  616. Actual: &AssertionValue{o.value},
  617. Errors: []error{
  618. errors.New("expected: none of the object elements match predicate"),
  619. fmt.Errorf("element with key %q matches predicate", kv.key),
  620. },
  621. })
  622. return o
  623. }
  624. }
  625. return o
  626. }
  627. // IsEmpty succeeds if object is empty.
  628. //
  629. // Example:
  630. //
  631. // object := NewObject(t, map[string]interface{}{})
  632. // object.IsEmpty()
  633. func (o *Object) IsEmpty() *Object {
  634. opChain := o.chain.enter("IsEmpty()")
  635. defer opChain.leave()
  636. if opChain.failed() {
  637. return o
  638. }
  639. if !(len(o.value) == 0) {
  640. opChain.fail(AssertionFailure{
  641. Type: AssertEmpty,
  642. Actual: &AssertionValue{o.value},
  643. Errors: []error{
  644. errors.New("expected: map is empty"),
  645. },
  646. })
  647. }
  648. return o
  649. }
  650. // NotEmpty succeeds if object is non-empty.
  651. //
  652. // Example:
  653. //
  654. // object := NewObject(t, map[string]interface{}{"foo": 123})
  655. // object.NotEmpty()
  656. func (o *Object) NotEmpty() *Object {
  657. opChain := o.chain.enter("NotEmpty()")
  658. defer opChain.leave()
  659. if opChain.failed() {
  660. return o
  661. }
  662. if len(o.value) == 0 {
  663. opChain.fail(AssertionFailure{
  664. Type: AssertNotEmpty,
  665. Actual: &AssertionValue{o.value},
  666. Errors: []error{
  667. errors.New("expected: map is non-empty"),
  668. },
  669. })
  670. }
  671. return o
  672. }
  673. // Deprecated: use IsEmpty instead.
  674. func (o *Object) Empty() *Object {
  675. return o.IsEmpty()
  676. }
  677. // IsEqual succeeds if object is equal to given value.
  678. // Before comparison, both object and value are converted to canonical form.
  679. //
  680. // value should be map[string]interface{} or struct.
  681. //
  682. // Example:
  683. //
  684. // object := NewObject(t, map[string]interface{}{"foo": 123})
  685. // object.IsEqual(map[string]interface{}{"foo": 123})
  686. func (o *Object) IsEqual(value interface{}) *Object {
  687. opChain := o.chain.enter("IsEqual()")
  688. defer opChain.leave()
  689. if opChain.failed() {
  690. return o
  691. }
  692. expected, ok := canonMap(opChain, value)
  693. if !ok {
  694. return o
  695. }
  696. if !reflect.DeepEqual(expected, o.value) {
  697. opChain.fail(AssertionFailure{
  698. Type: AssertEqual,
  699. Actual: &AssertionValue{o.value},
  700. Expected: &AssertionValue{expected},
  701. Errors: []error{
  702. errors.New("expected: maps are equal"),
  703. },
  704. })
  705. }
  706. return o
  707. }
  708. // NotEqual succeeds if object is not equal to given value.
  709. // Before comparison, both object and value are converted to canonical form.
  710. //
  711. // value should be map[string]interface{} or struct.
  712. //
  713. // Example:
  714. //
  715. // object := NewObject(t, map[string]interface{}{"foo": 123})
  716. // object.IsEqual(map[string]interface{}{"bar": 123})
  717. func (o *Object) NotEqual(value interface{}) *Object {
  718. opChain := o.chain.enter("NotEqual()")
  719. defer opChain.leave()
  720. if opChain.failed() {
  721. return o
  722. }
  723. expected, ok := canonMap(opChain, value)
  724. if !ok {
  725. return o
  726. }
  727. if reflect.DeepEqual(expected, o.value) {
  728. opChain.fail(AssertionFailure{
  729. Type: AssertNotEqual,
  730. Actual: &AssertionValue{o.value},
  731. Expected: &AssertionValue{expected},
  732. Errors: []error{
  733. errors.New("expected: maps are non-equal"),
  734. },
  735. })
  736. }
  737. return o
  738. }
  739. // Deprecated: use IsEqual instead.
  740. func (o *Object) Equal(value interface{}) *Object {
  741. return o.IsEqual(value)
  742. }
  743. // InList succeeds if whole object is equal to one of the values from given list
  744. // of objects. Before comparison, each value is converted to canonical form.
  745. //
  746. // Each value should be map[string]interface{} or struct. If at least one value
  747. // has wrong type, failure is reported.
  748. //
  749. // Example:
  750. //
  751. // object := NewObject(t, map[string]interface{}{"foo": 123})
  752. // object.InList(
  753. // map[string]interface{}{"foo": 123},
  754. // map[string]interface{}{"bar": 456},
  755. // )
  756. func (o *Object) InList(values ...interface{}) *Object {
  757. opChain := o.chain.enter("InList()")
  758. defer opChain.leave()
  759. if opChain.failed() {
  760. return o
  761. }
  762. if len(values) == 0 {
  763. opChain.fail(AssertionFailure{
  764. Type: AssertUsage,
  765. Errors: []error{
  766. errors.New("unexpected empty list argument"),
  767. },
  768. })
  769. return o
  770. }
  771. var isListed bool
  772. for _, v := range values {
  773. expected, ok := canonMap(opChain, v)
  774. if !ok {
  775. return o
  776. }
  777. if reflect.DeepEqual(expected, o.value) {
  778. isListed = true
  779. // continue loop to check that all values are correct
  780. }
  781. }
  782. if !isListed {
  783. opChain.fail(AssertionFailure{
  784. Type: AssertBelongs,
  785. Actual: &AssertionValue{o.value},
  786. Expected: &AssertionValue{AssertionList(values)},
  787. Errors: []error{
  788. errors.New("expected: map is equal to one of the values"),
  789. },
  790. })
  791. return o
  792. }
  793. return o
  794. }
  795. // NotInList succeeds if the whole object is not equal to any of the values
  796. // from given list of objects. Before comparison, each value is converted to
  797. // canonical form.
  798. //
  799. // Each value should be map[string]interface{} or struct. If at least one value
  800. // has wrong type, failure is reported.
  801. //
  802. // Example:
  803. //
  804. // object := NewObject(t, map[string]interface{}{"foo": 123})
  805. // object.NotInList(
  806. // map[string]interface{}{"bar": 456},
  807. // map[string]interface{}{"baz": 789},
  808. // )
  809. func (o *Object) NotInList(values ...interface{}) *Object {
  810. opChain := o.chain.enter("NotInList()")
  811. defer opChain.leave()
  812. if opChain.failed() {
  813. return o
  814. }
  815. if len(values) == 0 {
  816. opChain.fail(AssertionFailure{
  817. Type: AssertUsage,
  818. Errors: []error{
  819. errors.New("unexpected empty list argument"),
  820. },
  821. })
  822. return o
  823. }
  824. for _, v := range values {
  825. expected, ok := canonMap(opChain, v)
  826. if !ok {
  827. return o
  828. }
  829. if reflect.DeepEqual(expected, o.value) {
  830. opChain.fail(AssertionFailure{
  831. Type: AssertNotBelongs,
  832. Actual: &AssertionValue{o.value},
  833. Expected: &AssertionValue{AssertionList(values)},
  834. Errors: []error{
  835. errors.New("expected: map is not equal to any of the values"),
  836. },
  837. })
  838. return o
  839. }
  840. }
  841. return o
  842. }
  843. // ContainsKey succeeds if object contains given key.
  844. //
  845. // Example:
  846. //
  847. // object := NewObject(t, map[string]interface{}{"foo": 123})
  848. // object.ContainsKey("foo")
  849. func (o *Object) ContainsKey(key string) *Object {
  850. opChain := o.chain.enter("ContainsKey()")
  851. defer opChain.leave()
  852. if opChain.failed() {
  853. return o
  854. }
  855. if !containsKey(opChain, o.value, key) {
  856. opChain.fail(AssertionFailure{
  857. Type: AssertContainsKey,
  858. Actual: &AssertionValue{o.value},
  859. Expected: &AssertionValue{key},
  860. Errors: []error{
  861. errors.New("expected: map contains key"),
  862. },
  863. })
  864. }
  865. return o
  866. }
  867. // NotContainsKey succeeds if object doesn't contain given key.
  868. //
  869. // Example:
  870. //
  871. // object := NewObject(t, map[string]interface{}{"foo": 123})
  872. // object.NotContainsKey("bar")
  873. func (o *Object) NotContainsKey(key string) *Object {
  874. opChain := o.chain.enter("NotContainsKey()")
  875. defer opChain.leave()
  876. if opChain.failed() {
  877. return o
  878. }
  879. if containsKey(opChain, o.value, key) {
  880. opChain.fail(AssertionFailure{
  881. Type: AssertNotContainsKey,
  882. Actual: &AssertionValue{o.value},
  883. Expected: &AssertionValue{key},
  884. Errors: []error{
  885. errors.New("expected: map does not contain key"),
  886. },
  887. })
  888. }
  889. return o
  890. }
  891. // ContainsValue succeeds if object contains given value with any key.
  892. // Before comparison, both object and value are converted to canonical form.
  893. //
  894. // Example:
  895. //
  896. // object := NewObject(t, map[string]interface{}{"foo": 123})
  897. // object.ContainsValue(123)
  898. func (o *Object) ContainsValue(value interface{}) *Object {
  899. opChain := o.chain.enter("ContainsValue()")
  900. defer opChain.leave()
  901. if opChain.failed() {
  902. return o
  903. }
  904. if _, ok := containsValue(opChain, o.value, value); !ok {
  905. opChain.fail(AssertionFailure{
  906. Type: AssertContainsElement,
  907. Actual: &AssertionValue{o.value},
  908. Expected: &AssertionValue{value},
  909. Errors: []error{
  910. errors.New("expected: map contains element (with any key)"),
  911. },
  912. })
  913. }
  914. return o
  915. }
  916. // NotContainsValue succeeds if object does not contain given value with any key.
  917. // Before comparison, both object and value are converted to canonical form.
  918. //
  919. // Example:
  920. //
  921. // object := NewObject(t, map[string]interface{}{"foo": 123})
  922. // object.NotContainsValue(456)
  923. func (o *Object) NotContainsValue(value interface{}) *Object {
  924. opChain := o.chain.enter("NotContainsValue()")
  925. defer opChain.leave()
  926. if opChain.failed() {
  927. return o
  928. }
  929. if key, ok := containsValue(opChain, o.value, value); ok {
  930. opChain.fail(AssertionFailure{
  931. Type: AssertNotContainsElement,
  932. Actual: &AssertionValue{o.value},
  933. Expected: &AssertionValue{value},
  934. Errors: []error{
  935. errors.New("expected: map does not contain element (with any key)"),
  936. fmt.Errorf("found matching element with key %q", key),
  937. },
  938. })
  939. }
  940. return o
  941. }
  942. // ContainsSubset succeeds if given value is a subset of object.
  943. // Before comparison, both object and value are converted to canonical form.
  944. //
  945. // value should be map[string]interface{} or struct.
  946. //
  947. // Example:
  948. //
  949. // object := NewObject(t, map[string]interface{}{
  950. // "foo": 123,
  951. // "bar": []interface{}{"x", "y"},
  952. // "bar": map[string]interface{}{
  953. // "a": true,
  954. // "b": false,
  955. // },
  956. // })
  957. //
  958. // object.ContainsSubset(map[string]interface{}{ // success
  959. // "foo": 123,
  960. // "bar": map[string]interface{}{
  961. // "a": true,
  962. // },
  963. // })
  964. //
  965. // object.ContainsSubset(map[string]interface{}{ // failure
  966. // "foo": 123,
  967. // "qux": 456,
  968. // })
  969. //
  970. // object.ContainsSubset(map[string]interface{}{ // failure, slices should match exactly
  971. // "bar": []interface{}{"x"},
  972. // })
  973. func (o *Object) ContainsSubset(value interface{}) *Object {
  974. opChain := o.chain.enter("ContainsSubset()")
  975. defer opChain.leave()
  976. if opChain.failed() {
  977. return o
  978. }
  979. if !containsSubset(opChain, o.value, value) {
  980. opChain.fail(AssertionFailure{
  981. Type: AssertContainsSubset,
  982. Actual: &AssertionValue{o.value},
  983. Expected: &AssertionValue{value},
  984. Errors: []error{
  985. errors.New("expected: map contains sub-map"),
  986. },
  987. })
  988. }
  989. return o
  990. }
  991. // NotContainsSubset succeeds if given value is not a subset of object.
  992. // Before comparison, both object and value are converted to canonical form.
  993. //
  994. // value should be map[string]interface{} or struct.
  995. //
  996. // Example:
  997. //
  998. // object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
  999. // object.NotContainsSubset(map[string]interface{}{"foo": 123, "bar": "no-no-no"})
  1000. func (o *Object) NotContainsSubset(value interface{}) *Object {
  1001. opChain := o.chain.enter("NotContainsSubset()")
  1002. defer opChain.leave()
  1003. if opChain.failed() {
  1004. return o
  1005. }
  1006. if containsSubset(opChain, o.value, value) {
  1007. opChain.fail(AssertionFailure{
  1008. Type: AssertNotContainsSubset,
  1009. Actual: &AssertionValue{o.value},
  1010. Expected: &AssertionValue{value},
  1011. Errors: []error{
  1012. errors.New("expected: map does not contain sub-map"),
  1013. },
  1014. })
  1015. }
  1016. return o
  1017. }
  1018. // Deprecated: use ContainsSubset instead.
  1019. func (o *Object) ContainsMap(value interface{}) *Object {
  1020. return o.ContainsSubset(value)
  1021. }
  1022. // Deprecated: use NotContainsSubset instead.
  1023. func (o *Object) NotContainsMap(value interface{}) *Object {
  1024. return o.NotContainsSubset(value)
  1025. }
  1026. type kv struct {
  1027. key string
  1028. val interface{}
  1029. }
  1030. func (o *Object) sortedKV() []kv {
  1031. kvs := make([]kv, 0, len(o.value))
  1032. for key, val := range o.value {
  1033. kvs = append(kvs, kv{key: key, val: val})
  1034. }
  1035. sort.Slice(kvs, func(i, j int) bool {
  1036. return kvs[i].key < kvs[j].key
  1037. })
  1038. return kvs
  1039. }
  1040. func containsKey(
  1041. opChain *chain, obj map[string]interface{}, key string,
  1042. ) bool {
  1043. for k := range obj {
  1044. if k == key {
  1045. return true
  1046. }
  1047. }
  1048. return false
  1049. }
  1050. func containsValue(
  1051. opChain *chain, obj map[string]interface{}, val interface{},
  1052. ) (string, bool) {
  1053. canonVal, ok := canonValue(opChain, val)
  1054. if !ok {
  1055. return "", false
  1056. }
  1057. for k, v := range obj {
  1058. if reflect.DeepEqual(canonVal, v) {
  1059. return k, true
  1060. }
  1061. }
  1062. return "", false
  1063. }
  1064. func containsSubset(
  1065. opChain *chain, obj map[string]interface{}, val interface{},
  1066. ) bool {
  1067. canonVal, ok := canonMap(opChain, val)
  1068. if !ok {
  1069. return false
  1070. }
  1071. return isSubset(obj, canonVal)
  1072. }
  1073. func isSubset(outer, inner map[string]interface{}) bool {
  1074. for k, iv := range inner {
  1075. ov, ok := outer[k]
  1076. if !ok {
  1077. return false
  1078. }
  1079. if ovm, ok := ov.(map[string]interface{}); ok {
  1080. if ivm, ok := iv.(map[string]interface{}); ok {
  1081. if !isSubset(ovm, ivm) {
  1082. return false
  1083. }
  1084. continue
  1085. }
  1086. }
  1087. if !reflect.DeepEqual(ov, iv) {
  1088. return false
  1089. }
  1090. }
  1091. return true
  1092. }