Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 1 | package gophercloud |
| 2 | |
| 3 | import ( |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 4 | "fmt" |
| 5 | "net/http" |
| 6 | "reflect" |
| 7 | "testing" |
| 8 | |
| 9 | "github.com/rackspace/gophercloud/testhelper" |
| 10 | ) |
| 11 | |
| 12 | // SinglePage sample and test cases. |
| 13 | |
| 14 | type SinglePageCollection struct { |
| 15 | results []int |
| 16 | } |
| 17 | |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 18 | func (c SinglePageCollection) NextPageURL() string { |
| 19 | panic("NextPageURL should never be called on a single-paged collection.") |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 20 | } |
| 21 | |
Ash Wilson | b110fc9 | 2014-09-08 13:54:59 -0400 | [diff] [blame] | 22 | func (c SinglePageCollection) Concat(other Collection) Collection { |
| 23 | panic("Concat should never be called on a single-paged collection.") |
| 24 | } |
| 25 | |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 26 | func ExtractSingleInts(c Collection) []int { |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 27 | return c.(SinglePageCollection).results |
| 28 | } |
| 29 | |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 30 | func setupSinglePaged() Pager { |
| 31 | return NewSinglePager(func() (Collection, error) { |
| 32 | return SinglePageCollection{results: []int{1, 2, 3}}, nil |
| 33 | }) |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | func TestEnumerateSinglePaged(t *testing.T) { |
| 37 | callCount := 0 |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 38 | err := setupSinglePaged().EachPage(func(page Collection) bool { |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 39 | callCount++ |
| 40 | |
| 41 | expected := []int{1, 2, 3} |
| 42 | actual := AsSingleInts(page) |
| 43 | if !reflect.DeepEqual(expected, actual) { |
| 44 | t.Errorf("Expected %v, but was %v", expected, actual) |
| 45 | } |
| 46 | return true |
| 47 | }) |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 48 | if err != nil { |
| 49 | t.Fatalf("Unexpected error calling EachPage: %v", err) |
| 50 | } |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 51 | |
| 52 | if callCount != 1 { |
| 53 | t.Errorf("Callback was invoked %d times", callCount) |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | func TestAllSinglePaged(t *testing.T) { |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 58 | r, err := setupSinglePaged().AllPages() |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 59 | if err != nil { |
| 60 | t.Fatalf("Unexpected error when iterating pages: %v", err) |
| 61 | } |
| 62 | |
| 63 | expected := []int{1, 2, 3} |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 64 | actual := ExtractSingleInts(r) |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 65 | if !reflect.DeepEqual(expected, actual) { |
| 66 | t.Errorf("Expected %v, but was %v", expected, actual) |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | // LinkedPager sample and test cases. |
| 71 | |
| 72 | type LinkedCollection struct { |
| 73 | PaginationLinks |
| 74 | |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 75 | results []int |
| 76 | } |
| 77 | |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 78 | func (page LinkedCollection) NextPageURL() string { |
| 79 | n := page.PaginationLinks.Next |
| 80 | if n == nil { |
| 81 | return "" |
| 82 | } |
| 83 | return *n |
Ash Wilson | b110fc9 | 2014-09-08 13:54:59 -0400 | [diff] [blame] | 84 | } |
| 85 | |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 86 | func (page LinkedCollection) Concat(other Collection) Collection { |
Ash Wilson | b110fc9 | 2014-09-08 13:54:59 -0400 | [diff] [blame] | 87 | return LinkedCollection{ |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 88 | service: page.service, |
Ash Wilson | b110fc9 | 2014-09-08 13:54:59 -0400 | [diff] [blame] | 89 | results: append(c.results, AsLinkedInts(other)...), |
| 90 | } |
| 91 | } |
| 92 | |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 93 | func AsLinkedInts(results Collection) []int { |
| 94 | return results.(LinkedCollection).results |
| 95 | } |
| 96 | |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 97 | func createLinked() Pager { |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 98 | nextURL := testhelper.Server.URL + "/foo?page=2&perPage=3" |
Ash Wilson | e30b76b | 2014-09-12 08:36:17 -0400 | [diff] [blame^] | 99 | return CreatePager(func(url) Collection { |
| 100 | LinkedCollection{ |
| 101 | PaginationLinks: PaginationLinks{Next: &nextURL}, |
| 102 | results: []int{1, 2, 3}, |
| 103 | } |
| 104 | }) |
Ash Wilson | 64d67b2 | 2014-09-05 13:04:12 -0400 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | func setupLinkedResponses(t *testing.T) { |
| 108 | testhelper.Mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) { |
| 109 | testhelper.TestMethod(t, r, "GET") |
| 110 | testhelper.TestHeader(t, r, "X-Auth-Token", "1234") |
| 111 | w.Header().Add("Content-Type", "application/json") |
| 112 | |
| 113 | r.ParseForm() |
| 114 | |
| 115 | pages := r.Form["page"] |
| 116 | if len(pages) != 1 { |
| 117 | t.Errorf("Endpoint called with unexpected page: %#v", r.Form) |
| 118 | } |
| 119 | |
| 120 | switch pages[0] { |
| 121 | case "2": |
| 122 | fmt.Fprintf(w, `[4, 5, 6]`) |
| 123 | case "3": |
| 124 | fmt.Fprintf(w, `[7, 8, 9]`) |
| 125 | default: |
| 126 | t.Errorf("Endpoint called with unexpected page: %s", pages[0]) |
| 127 | } |
| 128 | }) |
| 129 | } |
| 130 | |
| 131 | func TestEnumerateLinked(t *testing.T) { |
| 132 | testhelper.SetupHTTP() |
| 133 | defer testhelper.TeardownHTTP() |
| 134 | |
| 135 | setupLinkedResponses(t) |
| 136 | lc := createLinked() |
| 137 | |
| 138 | callCount := 0 |
| 139 | err := EachPage(lc, func(page Collection) bool { |
| 140 | actual := AsLinkedInts(page) |
| 141 | t.Logf("Handler invoked with %v", actual) |
| 142 | |
| 143 | var expected []int |
| 144 | switch callCount { |
| 145 | case 0: |
| 146 | expected = []int{1, 2, 3} |
| 147 | case 1: |
| 148 | expected = []int{4, 5, 6} |
| 149 | case 2: |
| 150 | expected = []int{7, 8, 9} |
| 151 | default: |
| 152 | t.Fatalf("Unexpected call count: %d", callCount) |
| 153 | return false |
| 154 | } |
| 155 | |
| 156 | if !reflect.DeepEqual(expected, actual) { |
| 157 | t.Errorf("Call %d: Expected %#v, but was %#v", callCount, expected, actual) |
| 158 | } |
| 159 | |
| 160 | callCount++ |
| 161 | return true |
| 162 | }) |
| 163 | if err != nil { |
| 164 | t.Errorf("Unexpected error for page iteration: %v", err) |
| 165 | } |
| 166 | |
| 167 | if callCount != 3 { |
| 168 | t.Errorf("Expected 3 calls, but was %d", callCount) |
| 169 | } |
| 170 | } |
Ash Wilson | b110fc9 | 2014-09-08 13:54:59 -0400 | [diff] [blame] | 171 | |
| 172 | func TestAllLinked(t *testing.T) { |
| 173 | testhelper.SetupHTTP() |
| 174 | defer testhelper.TeardownHTTP() |
| 175 | |
| 176 | setupLinkedResponses(t) |
| 177 | lc := createLinked() |
| 178 | |
| 179 | all, err := AllPages(lc) |
| 180 | if err != nil { |
| 181 | t.Fatalf("Unexpected error collection all linked pages: %v", err) |
| 182 | } |
| 183 | |
| 184 | actual := AsLinkedInts(all) |
| 185 | expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} |
| 186 | |
| 187 | if !reflect.DeepEqual(expected, actual) { |
| 188 | t.Errorf("Expected %v, but was %v", expected, actual) |
| 189 | } |
| 190 | |
| 191 | original := []int{1, 2, 3} |
| 192 | if !reflect.DeepEqual(AsLinkedInts(lc), original) { |
| 193 | t.Errorf("AllPages modified the original page, and now it contains: %v", lc) |
| 194 | } |
| 195 | } |