array.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. package httpexpect
  2. import (
  3. "reflect"
  4. )
  5. // Array provides methods to inspect attached []interface{} object
  6. // (Go representation of JSON array).
  7. type Array struct {
  8. chain chain
  9. value []interface{}
  10. }
  11. // NewArray returns a new Array given a reporter used to report failures
  12. // and value to be inspected.
  13. //
  14. // Both reporter and value should not be nil. If value is nil, failure is
  15. // reported.
  16. //
  17. // Example:
  18. // array := NewArray(t, []interface{}{"foo", 123})
  19. func NewArray(reporter Reporter, value []interface{}) *Array {
  20. chain := makeChain(reporter)
  21. if value == nil {
  22. chain.fail("expected non-nil array value")
  23. } else {
  24. value, _ = canonArray(&chain, value)
  25. }
  26. return &Array{chain, value}
  27. }
  28. // Raw returns underlying value attached to Array.
  29. // This is the value originally passed to NewArray, converted to canonical form.
  30. //
  31. // Example:
  32. // array := NewArray(t, []interface{}{"foo", 123})
  33. // assert.Equal(t, []interface{}{"foo", 123.0}, array.Raw())
  34. func (a *Array) Raw() []interface{} {
  35. return a.value
  36. }
  37. // Path is similar to Value.Path.
  38. func (a *Array) Path(path string) *Value {
  39. return getPath(&a.chain, a.value, path)
  40. }
  41. // Schema is similar to Value.Schema.
  42. func (a *Array) Schema(schema interface{}) *Array {
  43. checkSchema(&a.chain, a.value, schema)
  44. return a
  45. }
  46. // Length returns a new Number object that may be used to inspect array length.
  47. //
  48. // Example:
  49. // array := NewArray(t, []interface{}{1, 2, 3})
  50. // array.Length().Equal(3)
  51. func (a *Array) Length() *Number {
  52. return &Number{a.chain, float64(len(a.value))}
  53. }
  54. // Element returns a new Value object that may be used to inspect array element
  55. // for given index.
  56. //
  57. // If index is out of array bounds, Element reports failure and returns empty
  58. // (but non-nil) value.
  59. //
  60. // Example:
  61. // array := NewArray(t, []interface{}{"foo", 123})
  62. // array.Element(0).String().Equal("foo")
  63. // array.Element(1).Number().Equal(123)
  64. func (a *Array) Element(index int) *Value {
  65. if index < 0 || index >= len(a.value) {
  66. a.chain.fail(
  67. "\narray index out of bounds:\n index %d\n\n bounds [%d; %d)",
  68. index,
  69. 0,
  70. len(a.value))
  71. return &Value{a.chain, nil}
  72. }
  73. return &Value{a.chain, a.value[index]}
  74. }
  75. // First returns a new Value object that may be used to inspect first element
  76. // of given array.
  77. //
  78. // If given array is empty, First reports failure and returns empty
  79. // (but non-nil) value.
  80. //
  81. // Example:
  82. // array := NewArray(t, []interface{}{"foo", 123})
  83. // array.First().String().Equal("foo")
  84. func (a *Array) First() *Value {
  85. if len(a.value) < 1 {
  86. a.chain.fail("\narray is empty")
  87. return &Value{a.chain, nil}
  88. }
  89. return &Value{a.chain, a.value[0]}
  90. }
  91. // Last returns a new Value object that may be used to inspect last element
  92. // of given array.
  93. //
  94. // If given array is empty, Last reports failure and returns empty
  95. // (but non-nil) value.
  96. //
  97. // Example:
  98. // array := NewArray(t, []interface{}{"foo", 123})
  99. // array.Last().Number().Equal(123)
  100. func (a *Array) Last() *Value {
  101. if len(a.value) < 1 {
  102. a.chain.fail("\narray is empty")
  103. return &Value{a.chain, nil}
  104. }
  105. return &Value{a.chain, a.value[len(a.value)-1]}
  106. }
  107. // Iter returns a new slice of Values attached to array elements.
  108. //
  109. // Example:
  110. // strings := []interface{}{"foo", "bar"}
  111. // array := NewArray(t, strings)
  112. //
  113. // for n, val := range array.Iter() {
  114. // val.String().Equal(strings[n])
  115. // }
  116. func (a *Array) Iter() []Value {
  117. if a.chain.failed() {
  118. return []Value{}
  119. }
  120. ret := []Value{}
  121. for n := range a.value {
  122. ret = append(ret, Value{a.chain, a.value[n]})
  123. }
  124. return ret
  125. }
  126. // Empty succeeds if array is empty.
  127. //
  128. // Example:
  129. // array := NewArray(t, []interface{}{})
  130. // array.Empty()
  131. func (a *Array) Empty() *Array {
  132. return a.Equal([]interface{}{})
  133. }
  134. // NotEmpty succeeds if array is non-empty.
  135. //
  136. // Example:
  137. // array := NewArray(t, []interface{}{"foo", 123})
  138. // array.NotEmpty()
  139. func (a *Array) NotEmpty() *Array {
  140. return a.NotEqual([]interface{}{})
  141. }
  142. // Equal succeeds if array is equal to another array.
  143. // Before comparison, both arrays are converted to canonical form.
  144. //
  145. // value should be slice of any type.
  146. //
  147. // Example:
  148. // array := NewArray(t, []interface{}{"foo", 123})
  149. // array.Equal([]interface{}{"foo", 123})
  150. //
  151. // array := NewArray(t, []interface{}{"foo", "bar"})
  152. // array.Equal([]string{}{"foo", "bar"})
  153. //
  154. // array := NewArray(t, []interface{}{123, 456})
  155. // array.Equal([]int{}{123, 456})
  156. func (a *Array) Equal(value interface{}) *Array {
  157. expected, ok := canonArray(&a.chain, value)
  158. if !ok {
  159. return a
  160. }
  161. if !reflect.DeepEqual(expected, a.value) {
  162. a.chain.fail("\nexpected array equal to:\n%s\n\nbut got:\n%s\n\ndiff:\n%s",
  163. dumpValue(expected),
  164. dumpValue(a.value),
  165. diffValues(expected, a.value))
  166. }
  167. return a
  168. }
  169. // NotEqual succeeds if array is not equal to another array.
  170. // Before comparison, both arrays are converted to canonical form.
  171. //
  172. // value should be slice of any type.
  173. //
  174. // Example:
  175. // array := NewArray(t, []interface{}{"foo", 123})
  176. // array.NotEqual([]interface{}{123, "foo"})
  177. func (a *Array) NotEqual(value interface{}) *Array {
  178. expected, ok := canonArray(&a.chain, value)
  179. if !ok {
  180. return a
  181. }
  182. if reflect.DeepEqual(expected, a.value) {
  183. a.chain.fail("\nexpected array not equal to:\n%s",
  184. dumpValue(expected))
  185. }
  186. return a
  187. }
  188. // Elements succeeds if array contains all given elements, in given order, and only them.
  189. // Before comparison, array and all elements are converted to canonical form.
  190. //
  191. // For partial or unordered comparison, see Contains and ContainsOnly.
  192. //
  193. // Example:
  194. // array := NewArray(t, []interface{}{"foo", 123})
  195. // array.Elements("foo", 123)
  196. //
  197. // This calls are equivalent:
  198. // array.Elelems("a", "b")
  199. // array.Equal([]interface{}{"a", "b"})
  200. func (a *Array) Elements(values ...interface{}) *Array {
  201. return a.Equal(values)
  202. }
  203. // Contains succeeds if array contains all given elements (in any order).
  204. // Before comparison, array and all elements are converted to canonical form.
  205. //
  206. // Example:
  207. // array := NewArray(t, []interface{}{"foo", 123})
  208. // array.Contains(123, "foo")
  209. func (a *Array) Contains(values ...interface{}) *Array {
  210. elements, ok := canonArray(&a.chain, values)
  211. if !ok {
  212. return a
  213. }
  214. for _, e := range elements {
  215. if !a.containsElement(e) {
  216. a.chain.fail("\nexpected array containing element:\n%s\n\nbut got:\n%s",
  217. dumpValue(e), dumpValue(a.value))
  218. }
  219. }
  220. return a
  221. }
  222. // NotContains succeeds if array contains none of given elements.
  223. // Before comparison, array and all elements are converted to canonical form.
  224. //
  225. // Example:
  226. // array := NewArray(t, []interface{}{"foo", 123})
  227. // array.NotContains("bar") // success
  228. // array.NotContains("bar", "foo") // failure (array contains "foo")
  229. func (a *Array) NotContains(values ...interface{}) *Array {
  230. elements, ok := canonArray(&a.chain, values)
  231. if !ok {
  232. return a
  233. }
  234. for _, e := range elements {
  235. if a.containsElement(e) {
  236. a.chain.fail("\nexpected array not containing element:\n%s\n\nbut got:\n%s",
  237. dumpValue(e), dumpValue(a.value))
  238. }
  239. }
  240. return a
  241. }
  242. // ContainsOnly succeeds if array contains all given elements, in any order, and only
  243. // them. Before comparison, array and all elements are converted to canonical form.
  244. //
  245. // Example:
  246. // array := NewArray(t, []interface{}{"foo", 123})
  247. // array.ContainsOnly(123, "foo")
  248. //
  249. // This calls are equivalent:
  250. // array.ContainsOnly("a", "b")
  251. // array.ContainsOnly("b", "a")
  252. func (a *Array) ContainsOnly(values ...interface{}) *Array {
  253. elements, ok := canonArray(&a.chain, values)
  254. if !ok {
  255. return a
  256. }
  257. if len(elements) != len(a.value) {
  258. a.chain.fail("\nexpected array of length == %d:\n%s\n\n"+
  259. "but got array of length %d:\n%s",
  260. len(elements), dumpValue(elements),
  261. len(a.value), dumpValue(a.value))
  262. return a
  263. }
  264. for _, e := range elements {
  265. if !a.containsElement(e) {
  266. a.chain.fail("\nexpected array containing element:\n%s\n\nbut got:\n%s",
  267. dumpValue(e), dumpValue(a.value))
  268. }
  269. }
  270. return a
  271. }
  272. func (a *Array) containsElement(expected interface{}) bool {
  273. for _, e := range a.value {
  274. if reflect.DeepEqual(expected, e) {
  275. return true
  276. }
  277. }
  278. return false
  279. }