Paginator module in Elixir












0












$begingroup$


I wrote this Paginator module that's part of a small application that displays Elixir Github repos in a table.



I'm new to Elixir and looking for code improvements with as much as possible. Best practices. Commenting. Optimizations. The usage of structs for input output. Etc.



#paginator.ex



defmodule Paginator do

@moduledoc """
A module that implements functions for performing simple pagination functionality

Invoke it using the module's `call` function that takes a struct as parameter.

## Struct key values

- total: The total amount of records (mandatory)
- page: The page currently on (default: 1)
- per_page: The number of records per page (default: 10)
- max_display: The number of pages displayed in the pagination menu (default: 10)
- max_results: Optional argument that limits the total number of records it can paginate

## Examples

iex> Paginator.call %Paginator(total: 1000)

%Paginator.Output{
first: nil,
last: 100,
next: 2,
page: 1,
pages: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
previous: nil
}

"""

# The struct with the pagination info that gets returned
defmodule Output do
defstruct [:page, :first, :last, :previous, :next, :pages]
end

@doc """
# Struct that's passed to the module used to calculate the pagination data
"""
@enforce_keys [:total]
defstruct page: 1, per_page: 10, total: nil, max_display: 10, max_results: nil

@doc """
Invokes the module. Takes a struct with the input and returns a struct with the pagination data
"""
def call(data) do

data = data
|> Map.put(:max_pages, max_pages(data))
|> Map.put(:half, half(data))

%Output{
page: data.page,
first: first(data),
last: last(data),
pages: pages(data),
previous: previous(data),
next: next(data)
}
end

"""
Returns the maximum pages.
@TODO: this must be a bug. add test that has total less than max_results
"""
defp max_pages(data) do
cond do
data.total <= data.per_page ->
0
data.max_results !== nil and data.max_results < data.total ->
Kernel.trunc(data.max_results / data.per_page)
true ->
Kernel.trunc(data.total / data.per_page)
end
end

# Returns the first page
defp first(data) do
if data.total >= data.per_page and data.page !== 1, do: 1, else: nil
end

# Returns the last page
defp last(data) do
if data.page < data.max_pages, do: data.max_pages, else: nil
end

# Returns the half value of `max_display` rounded down
defp half(data) do
Kernel.trunc(data.max_display / 2)
end

# Returns the `pages` list. The number of list items depends on the number specified in `max_display`
defp pages(data) do
if data.total === nil or data.total === 0 or data.max_pages === 0 do

else
Enum.to_list begin_pages(data)..end_pages(data)
end
end

# Returns the page that the `pages` list starts on
defp begin_pages(data) do
cond do
data.page + data.half >= data.max_pages ->
# when reaching the end
data.max_pages - (data.max_display - 1)
data.page > data.half ->
# odd vs even pages
if rem(data.max_display, 2) === 0 do
data.page - (data.half - 1)
else
data.page - data.half
end
true ->
1
end
end

# Returns the page that the `pages` list ends on
defp end_pages(data) do
end_page = data.page + data.half
cond do
end_page >= data.max_pages ->
# when reaching the end
data.max_pages
data.page <= data.half ->
data.max_display
true ->
end_page
end
end

# Returns the page number that is prior than the current page.
# If the current page is 1 it returns nil
defp previous(data) do
if data.page > 1, do: data.page - 1, else: nil
end

# Returns the page number that is latter than the current page.
# If the current page is equal to the last it returns nil
defp next(data) do
if data.page < data.max_pages, do: data.page + 1, else: nil
end
end


#paginator_test.exs



defmodule PaginatorTest do
use ConnCase
alias Paginator

describe "Test Paginator" do

test "page 1 of 15" do
res = Paginator.call %Paginator{total: 150}

assert res.first == nil
assert res.previous == nil
assert res.next == 2
assert res.last == 15
assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
end

test "page 5 of 15" do
res = Paginator.call %Paginator{page: 5, total: 150}

assert res.first == 1
assert res.previous == 4
assert res.next == 6
assert res.last == 15
assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
end

test "page 6 of 15" do
res = Paginator.call %Paginator{page: 6, total: 150}

assert res.first == 1
assert res.previous == 5
assert res.next == 7
assert res.last == 15
assert res.pages == [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
end

test "page 7 of 15" do
res = Paginator.call %Paginator{page: 7, total: 150}

assert res.pages == [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
end

test "page 13 of 15" do
res = Paginator.call %Paginator{page: 13, total: 150}

assert res.pages == [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

end

test "per page 50" do
res = Paginator.call %Paginator{page: 25, per_page: 50, total: 2000}

assert res.first == 1
assert res.previous == 24
assert res.next == 26
assert res.last == 40
assert res.pages == [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

end

test "last page" do
res = Paginator.call %Paginator{page: 50, total: 500}

assert res.first == 1
assert res.previous == 49
assert res.next == nil
assert res.last == nil
end

test "max display" do
res = Paginator.call %Paginator{page: 8, max_display: 5, total: 2000}

assert res.first == 1
assert res.previous == 7
assert res.next == 9
assert res.pages == [6, 7, 8, 9, 10]

res = Paginator.call %Paginator{page: 9, max_display: 5, total: 2000}
assert res.pages == [7, 8, 9, 10, 11]

end

test "max results - total more than max" do
res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

assert res.last == 100
assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

end

test "max results - max more than total" do
res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

assert res.last == 100
assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
end

test "no pages - zero total" do
res = Paginator.call %Paginator{total: 0}

assert res.first == nil
assert res.previous == nil
assert res.next == nil
assert res.pages ==
end

test "no pages - low total" do
res = Paginator.call %Paginator{total: 5}

assert res.first == nil
assert res.previous == nil
assert res.next == nil
assert res.pages ==
end
end
end









share|improve this question









$endgroup$

















    0












    $begingroup$


    I wrote this Paginator module that's part of a small application that displays Elixir Github repos in a table.



    I'm new to Elixir and looking for code improvements with as much as possible. Best practices. Commenting. Optimizations. The usage of structs for input output. Etc.



    #paginator.ex



    defmodule Paginator do

    @moduledoc """
    A module that implements functions for performing simple pagination functionality

    Invoke it using the module's `call` function that takes a struct as parameter.

    ## Struct key values

    - total: The total amount of records (mandatory)
    - page: The page currently on (default: 1)
    - per_page: The number of records per page (default: 10)
    - max_display: The number of pages displayed in the pagination menu (default: 10)
    - max_results: Optional argument that limits the total number of records it can paginate

    ## Examples

    iex> Paginator.call %Paginator(total: 1000)

    %Paginator.Output{
    first: nil,
    last: 100,
    next: 2,
    page: 1,
    pages: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    previous: nil
    }

    """

    # The struct with the pagination info that gets returned
    defmodule Output do
    defstruct [:page, :first, :last, :previous, :next, :pages]
    end

    @doc """
    # Struct that's passed to the module used to calculate the pagination data
    """
    @enforce_keys [:total]
    defstruct page: 1, per_page: 10, total: nil, max_display: 10, max_results: nil

    @doc """
    Invokes the module. Takes a struct with the input and returns a struct with the pagination data
    """
    def call(data) do

    data = data
    |> Map.put(:max_pages, max_pages(data))
    |> Map.put(:half, half(data))

    %Output{
    page: data.page,
    first: first(data),
    last: last(data),
    pages: pages(data),
    previous: previous(data),
    next: next(data)
    }
    end

    """
    Returns the maximum pages.
    @TODO: this must be a bug. add test that has total less than max_results
    """
    defp max_pages(data) do
    cond do
    data.total <= data.per_page ->
    0
    data.max_results !== nil and data.max_results < data.total ->
    Kernel.trunc(data.max_results / data.per_page)
    true ->
    Kernel.trunc(data.total / data.per_page)
    end
    end

    # Returns the first page
    defp first(data) do
    if data.total >= data.per_page and data.page !== 1, do: 1, else: nil
    end

    # Returns the last page
    defp last(data) do
    if data.page < data.max_pages, do: data.max_pages, else: nil
    end

    # Returns the half value of `max_display` rounded down
    defp half(data) do
    Kernel.trunc(data.max_display / 2)
    end

    # Returns the `pages` list. The number of list items depends on the number specified in `max_display`
    defp pages(data) do
    if data.total === nil or data.total === 0 or data.max_pages === 0 do

    else
    Enum.to_list begin_pages(data)..end_pages(data)
    end
    end

    # Returns the page that the `pages` list starts on
    defp begin_pages(data) do
    cond do
    data.page + data.half >= data.max_pages ->
    # when reaching the end
    data.max_pages - (data.max_display - 1)
    data.page > data.half ->
    # odd vs even pages
    if rem(data.max_display, 2) === 0 do
    data.page - (data.half - 1)
    else
    data.page - data.half
    end
    true ->
    1
    end
    end

    # Returns the page that the `pages` list ends on
    defp end_pages(data) do
    end_page = data.page + data.half
    cond do
    end_page >= data.max_pages ->
    # when reaching the end
    data.max_pages
    data.page <= data.half ->
    data.max_display
    true ->
    end_page
    end
    end

    # Returns the page number that is prior than the current page.
    # If the current page is 1 it returns nil
    defp previous(data) do
    if data.page > 1, do: data.page - 1, else: nil
    end

    # Returns the page number that is latter than the current page.
    # If the current page is equal to the last it returns nil
    defp next(data) do
    if data.page < data.max_pages, do: data.page + 1, else: nil
    end
    end


    #paginator_test.exs



    defmodule PaginatorTest do
    use ConnCase
    alias Paginator

    describe "Test Paginator" do

    test "page 1 of 15" do
    res = Paginator.call %Paginator{total: 150}

    assert res.first == nil
    assert res.previous == nil
    assert res.next == 2
    assert res.last == 15
    assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    end

    test "page 5 of 15" do
    res = Paginator.call %Paginator{page: 5, total: 150}

    assert res.first == 1
    assert res.previous == 4
    assert res.next == 6
    assert res.last == 15
    assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    end

    test "page 6 of 15" do
    res = Paginator.call %Paginator{page: 6, total: 150}

    assert res.first == 1
    assert res.previous == 5
    assert res.next == 7
    assert res.last == 15
    assert res.pages == [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    end

    test "page 7 of 15" do
    res = Paginator.call %Paginator{page: 7, total: 150}

    assert res.pages == [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    end

    test "page 13 of 15" do
    res = Paginator.call %Paginator{page: 13, total: 150}

    assert res.pages == [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

    end

    test "per page 50" do
    res = Paginator.call %Paginator{page: 25, per_page: 50, total: 2000}

    assert res.first == 1
    assert res.previous == 24
    assert res.next == 26
    assert res.last == 40
    assert res.pages == [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

    end

    test "last page" do
    res = Paginator.call %Paginator{page: 50, total: 500}

    assert res.first == 1
    assert res.previous == 49
    assert res.next == nil
    assert res.last == nil
    end

    test "max display" do
    res = Paginator.call %Paginator{page: 8, max_display: 5, total: 2000}

    assert res.first == 1
    assert res.previous == 7
    assert res.next == 9
    assert res.pages == [6, 7, 8, 9, 10]

    res = Paginator.call %Paginator{page: 9, max_display: 5, total: 2000}
    assert res.pages == [7, 8, 9, 10, 11]

    end

    test "max results - total more than max" do
    res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

    assert res.last == 100
    assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

    end

    test "max results - max more than total" do
    res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

    assert res.last == 100
    assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
    end

    test "no pages - zero total" do
    res = Paginator.call %Paginator{total: 0}

    assert res.first == nil
    assert res.previous == nil
    assert res.next == nil
    assert res.pages ==
    end

    test "no pages - low total" do
    res = Paginator.call %Paginator{total: 5}

    assert res.first == nil
    assert res.previous == nil
    assert res.next == nil
    assert res.pages ==
    end
    end
    end









    share|improve this question









    $endgroup$















      0












      0








      0





      $begingroup$


      I wrote this Paginator module that's part of a small application that displays Elixir Github repos in a table.



      I'm new to Elixir and looking for code improvements with as much as possible. Best practices. Commenting. Optimizations. The usage of structs for input output. Etc.



      #paginator.ex



      defmodule Paginator do

      @moduledoc """
      A module that implements functions for performing simple pagination functionality

      Invoke it using the module's `call` function that takes a struct as parameter.

      ## Struct key values

      - total: The total amount of records (mandatory)
      - page: The page currently on (default: 1)
      - per_page: The number of records per page (default: 10)
      - max_display: The number of pages displayed in the pagination menu (default: 10)
      - max_results: Optional argument that limits the total number of records it can paginate

      ## Examples

      iex> Paginator.call %Paginator(total: 1000)

      %Paginator.Output{
      first: nil,
      last: 100,
      next: 2,
      page: 1,
      pages: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
      previous: nil
      }

      """

      # The struct with the pagination info that gets returned
      defmodule Output do
      defstruct [:page, :first, :last, :previous, :next, :pages]
      end

      @doc """
      # Struct that's passed to the module used to calculate the pagination data
      """
      @enforce_keys [:total]
      defstruct page: 1, per_page: 10, total: nil, max_display: 10, max_results: nil

      @doc """
      Invokes the module. Takes a struct with the input and returns a struct with the pagination data
      """
      def call(data) do

      data = data
      |> Map.put(:max_pages, max_pages(data))
      |> Map.put(:half, half(data))

      %Output{
      page: data.page,
      first: first(data),
      last: last(data),
      pages: pages(data),
      previous: previous(data),
      next: next(data)
      }
      end

      """
      Returns the maximum pages.
      @TODO: this must be a bug. add test that has total less than max_results
      """
      defp max_pages(data) do
      cond do
      data.total <= data.per_page ->
      0
      data.max_results !== nil and data.max_results < data.total ->
      Kernel.trunc(data.max_results / data.per_page)
      true ->
      Kernel.trunc(data.total / data.per_page)
      end
      end

      # Returns the first page
      defp first(data) do
      if data.total >= data.per_page and data.page !== 1, do: 1, else: nil
      end

      # Returns the last page
      defp last(data) do
      if data.page < data.max_pages, do: data.max_pages, else: nil
      end

      # Returns the half value of `max_display` rounded down
      defp half(data) do
      Kernel.trunc(data.max_display / 2)
      end

      # Returns the `pages` list. The number of list items depends on the number specified in `max_display`
      defp pages(data) do
      if data.total === nil or data.total === 0 or data.max_pages === 0 do

      else
      Enum.to_list begin_pages(data)..end_pages(data)
      end
      end

      # Returns the page that the `pages` list starts on
      defp begin_pages(data) do
      cond do
      data.page + data.half >= data.max_pages ->
      # when reaching the end
      data.max_pages - (data.max_display - 1)
      data.page > data.half ->
      # odd vs even pages
      if rem(data.max_display, 2) === 0 do
      data.page - (data.half - 1)
      else
      data.page - data.half
      end
      true ->
      1
      end
      end

      # Returns the page that the `pages` list ends on
      defp end_pages(data) do
      end_page = data.page + data.half
      cond do
      end_page >= data.max_pages ->
      # when reaching the end
      data.max_pages
      data.page <= data.half ->
      data.max_display
      true ->
      end_page
      end
      end

      # Returns the page number that is prior than the current page.
      # If the current page is 1 it returns nil
      defp previous(data) do
      if data.page > 1, do: data.page - 1, else: nil
      end

      # Returns the page number that is latter than the current page.
      # If the current page is equal to the last it returns nil
      defp next(data) do
      if data.page < data.max_pages, do: data.page + 1, else: nil
      end
      end


      #paginator_test.exs



      defmodule PaginatorTest do
      use ConnCase
      alias Paginator

      describe "Test Paginator" do

      test "page 1 of 15" do
      res = Paginator.call %Paginator{total: 150}

      assert res.first == nil
      assert res.previous == nil
      assert res.next == 2
      assert res.last == 15
      assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      end

      test "page 5 of 15" do
      res = Paginator.call %Paginator{page: 5, total: 150}

      assert res.first == 1
      assert res.previous == 4
      assert res.next == 6
      assert res.last == 15
      assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      end

      test "page 6 of 15" do
      res = Paginator.call %Paginator{page: 6, total: 150}

      assert res.first == 1
      assert res.previous == 5
      assert res.next == 7
      assert res.last == 15
      assert res.pages == [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
      end

      test "page 7 of 15" do
      res = Paginator.call %Paginator{page: 7, total: 150}

      assert res.pages == [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
      end

      test "page 13 of 15" do
      res = Paginator.call %Paginator{page: 13, total: 150}

      assert res.pages == [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

      end

      test "per page 50" do
      res = Paginator.call %Paginator{page: 25, per_page: 50, total: 2000}

      assert res.first == 1
      assert res.previous == 24
      assert res.next == 26
      assert res.last == 40
      assert res.pages == [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

      end

      test "last page" do
      res = Paginator.call %Paginator{page: 50, total: 500}

      assert res.first == 1
      assert res.previous == 49
      assert res.next == nil
      assert res.last == nil
      end

      test "max display" do
      res = Paginator.call %Paginator{page: 8, max_display: 5, total: 2000}

      assert res.first == 1
      assert res.previous == 7
      assert res.next == 9
      assert res.pages == [6, 7, 8, 9, 10]

      res = Paginator.call %Paginator{page: 9, max_display: 5, total: 2000}
      assert res.pages == [7, 8, 9, 10, 11]

      end

      test "max results - total more than max" do
      res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

      assert res.last == 100
      assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

      end

      test "max results - max more than total" do
      res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

      assert res.last == 100
      assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
      end

      test "no pages - zero total" do
      res = Paginator.call %Paginator{total: 0}

      assert res.first == nil
      assert res.previous == nil
      assert res.next == nil
      assert res.pages ==
      end

      test "no pages - low total" do
      res = Paginator.call %Paginator{total: 5}

      assert res.first == nil
      assert res.previous == nil
      assert res.next == nil
      assert res.pages ==
      end
      end
      end









      share|improve this question









      $endgroup$




      I wrote this Paginator module that's part of a small application that displays Elixir Github repos in a table.



      I'm new to Elixir and looking for code improvements with as much as possible. Best practices. Commenting. Optimizations. The usage of structs for input output. Etc.



      #paginator.ex



      defmodule Paginator do

      @moduledoc """
      A module that implements functions for performing simple pagination functionality

      Invoke it using the module's `call` function that takes a struct as parameter.

      ## Struct key values

      - total: The total amount of records (mandatory)
      - page: The page currently on (default: 1)
      - per_page: The number of records per page (default: 10)
      - max_display: The number of pages displayed in the pagination menu (default: 10)
      - max_results: Optional argument that limits the total number of records it can paginate

      ## Examples

      iex> Paginator.call %Paginator(total: 1000)

      %Paginator.Output{
      first: nil,
      last: 100,
      next: 2,
      page: 1,
      pages: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
      previous: nil
      }

      """

      # The struct with the pagination info that gets returned
      defmodule Output do
      defstruct [:page, :first, :last, :previous, :next, :pages]
      end

      @doc """
      # Struct that's passed to the module used to calculate the pagination data
      """
      @enforce_keys [:total]
      defstruct page: 1, per_page: 10, total: nil, max_display: 10, max_results: nil

      @doc """
      Invokes the module. Takes a struct with the input and returns a struct with the pagination data
      """
      def call(data) do

      data = data
      |> Map.put(:max_pages, max_pages(data))
      |> Map.put(:half, half(data))

      %Output{
      page: data.page,
      first: first(data),
      last: last(data),
      pages: pages(data),
      previous: previous(data),
      next: next(data)
      }
      end

      """
      Returns the maximum pages.
      @TODO: this must be a bug. add test that has total less than max_results
      """
      defp max_pages(data) do
      cond do
      data.total <= data.per_page ->
      0
      data.max_results !== nil and data.max_results < data.total ->
      Kernel.trunc(data.max_results / data.per_page)
      true ->
      Kernel.trunc(data.total / data.per_page)
      end
      end

      # Returns the first page
      defp first(data) do
      if data.total >= data.per_page and data.page !== 1, do: 1, else: nil
      end

      # Returns the last page
      defp last(data) do
      if data.page < data.max_pages, do: data.max_pages, else: nil
      end

      # Returns the half value of `max_display` rounded down
      defp half(data) do
      Kernel.trunc(data.max_display / 2)
      end

      # Returns the `pages` list. The number of list items depends on the number specified in `max_display`
      defp pages(data) do
      if data.total === nil or data.total === 0 or data.max_pages === 0 do

      else
      Enum.to_list begin_pages(data)..end_pages(data)
      end
      end

      # Returns the page that the `pages` list starts on
      defp begin_pages(data) do
      cond do
      data.page + data.half >= data.max_pages ->
      # when reaching the end
      data.max_pages - (data.max_display - 1)
      data.page > data.half ->
      # odd vs even pages
      if rem(data.max_display, 2) === 0 do
      data.page - (data.half - 1)
      else
      data.page - data.half
      end
      true ->
      1
      end
      end

      # Returns the page that the `pages` list ends on
      defp end_pages(data) do
      end_page = data.page + data.half
      cond do
      end_page >= data.max_pages ->
      # when reaching the end
      data.max_pages
      data.page <= data.half ->
      data.max_display
      true ->
      end_page
      end
      end

      # Returns the page number that is prior than the current page.
      # If the current page is 1 it returns nil
      defp previous(data) do
      if data.page > 1, do: data.page - 1, else: nil
      end

      # Returns the page number that is latter than the current page.
      # If the current page is equal to the last it returns nil
      defp next(data) do
      if data.page < data.max_pages, do: data.page + 1, else: nil
      end
      end


      #paginator_test.exs



      defmodule PaginatorTest do
      use ConnCase
      alias Paginator

      describe "Test Paginator" do

      test "page 1 of 15" do
      res = Paginator.call %Paginator{total: 150}

      assert res.first == nil
      assert res.previous == nil
      assert res.next == 2
      assert res.last == 15
      assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      end

      test "page 5 of 15" do
      res = Paginator.call %Paginator{page: 5, total: 150}

      assert res.first == 1
      assert res.previous == 4
      assert res.next == 6
      assert res.last == 15
      assert res.pages == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      end

      test "page 6 of 15" do
      res = Paginator.call %Paginator{page: 6, total: 150}

      assert res.first == 1
      assert res.previous == 5
      assert res.next == 7
      assert res.last == 15
      assert res.pages == [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
      end

      test "page 7 of 15" do
      res = Paginator.call %Paginator{page: 7, total: 150}

      assert res.pages == [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
      end

      test "page 13 of 15" do
      res = Paginator.call %Paginator{page: 13, total: 150}

      assert res.pages == [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

      end

      test "per page 50" do
      res = Paginator.call %Paginator{page: 25, per_page: 50, total: 2000}

      assert res.first == 1
      assert res.previous == 24
      assert res.next == 26
      assert res.last == 40
      assert res.pages == [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

      end

      test "last page" do
      res = Paginator.call %Paginator{page: 50, total: 500}

      assert res.first == 1
      assert res.previous == 49
      assert res.next == nil
      assert res.last == nil
      end

      test "max display" do
      res = Paginator.call %Paginator{page: 8, max_display: 5, total: 2000}

      assert res.first == 1
      assert res.previous == 7
      assert res.next == 9
      assert res.pages == [6, 7, 8, 9, 10]

      res = Paginator.call %Paginator{page: 9, max_display: 5, total: 2000}
      assert res.pages == [7, 8, 9, 10, 11]

      end

      test "max results - total more than max" do
      res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

      assert res.last == 100
      assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

      end

      test "max results - max more than total" do
      res = Paginator.call %Paginator{page: 96, total: 2000, max_results: 1000}

      assert res.last == 100
      assert res.pages == [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
      end

      test "no pages - zero total" do
      res = Paginator.call %Paginator{total: 0}

      assert res.first == nil
      assert res.previous == nil
      assert res.next == nil
      assert res.pages ==
      end

      test "no pages - low total" do
      res = Paginator.call %Paginator{total: 5}

      assert res.first == nil
      assert res.previous == nil
      assert res.next == nil
      assert res.pages ==
      end
      end
      end






      elixir






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 14 mins ago









      dan-klassondan-klasson

      1725




      1725






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214097%2fpaginator-module-in-elixir%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214097%2fpaginator-module-in-elixir%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Сан-Квентин

          8-я гвардейская общевойсковая армия

          Алькесар