Jump to content

Module:Citation/CS1/testcases/identifiers

ဝီကီးပီးဒီးယား က

Documentation for this module may be created at Module:Citation/CS1/testcases/identifiers/doc

--[=[

Unit tests for [[Module:Citation/CS1/Identifiers]].

Click talk page to run tests.

]=]

local p = require('Module:UnitTests');
local live_cfg = mw.loadData ('Module:Citation/CS1/Configuration');
local new_cfg = mw.loadData ('Module:Citation/CS1/Configuration/sandbox');

--[[--------------------------< T O D A Y _ P L U S _ O F F S E T _ G E T >------------------------------------

returns date offset from today by <offset> in <format> (#time parser function formatting)
  Y - four digit year
  m - two digit month
  M - abbreviated month name
  F - full month name
  d - zero-padded day
  j - day without zero-padding

<offset> must include units: days, months, years

]]

local function today_plus_offset_get (format, offset)
  return mw.getContentLanguage():formatDate(format, 'today ' .. offset and ('+ ' .. offset) or '');
end


--[[--------------------------< A R X I V _ 9 1 0 7 _ 0 7 0 3 >------------------------------------------------
]]

function p:test_arxiv_9107_0703()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
                                        -- legitimate date range
      {'arxiv=a.a/9007333'},                        -- invalid yymm (fail)
      {'arxiv=a.a/9106333'},                        -- invalid yymm (fail)
      {'arxiv=a.a/9107333'},                        -- valid yymm (pass)
      {'arxiv=a.a/0703333'},                        -- valid yymm (pass)
      {'arxiv=a.a/0704333'},                        -- invalid yymm (fail)
      {'arxiv=a.a/0803333'},                        -- valid yymm (pass)
                                        -- archive & class
      {'arxiv=.a/9107333'},                       -- without archive (fail)
      {'arxiv=aa/9107333'},                       -- without class (pass)
      
                                        -- number
      {'arxiv=aa/910722'},                        -- not enough digits (fail)
      {'arxiv=aa/91074444'},                        -- too many digits (fail)

                                        -- version
      {'arxiv=a.a/9107333v'},                       -- missing version number (fail)
      {'arxiv=a.a/9107333v1'},                      -- with version number (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< A R X I V _ 0 7 0 4 _ 1 4 1 2 >------------------------------------------------
]]

function p:test_arxiv_0704_1412()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
                                        -- date range
      {'arxiv=0612.4444'},                        -- invalid yymm (fail)
      {'arxiv=0703.4444'},                        -- invalid yymm (fail)
      {'arxiv=0704.4444'},                        -- valid yymm (pass)
      {'arxiv=1412.4444'},                        -- valid yymm (pass)
      {'arxiv=1413.4444'},                        -- invalid yymm (fail)
      {'arxiv=1501.4444'},                        -- invalid yymm (fail)

                                        -- number
      {'arxiv=0704.333'},                         -- not enough digits (fail)
      {'arxiv=0704.55555'},                       -- too many digits (fail)

                                        -- version
      {'arxiv=0704.4444v'},                       -- missing version number (fail)
      {'arxiv=0704.4444v1'},                        -- with version number (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< A R X I V _ 1 5 0 1 >----------------------------------------------------------
]]

function p:test_arxiv_1501()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
                                        -- date range
      {'arxiv=1412.55555'},                       -- invalid yymm (fail)
      {'arxiv=1500.55555'},                       -- invalid yymm (fail)
      {'arxiv=1501.55555'},                       -- valid yymm (pass)
      {'arxiv=1513.55555'},                       -- invalid yymm (fail)

                                        -- number
      {'arxiv=1501.4444'},                        -- not enough digits (fail)
      {'arxiv=1501.666666'},                        -- too many digits (fail)

                                        -- version
      {'arxiv=1501.4444v'},                       -- missing version number (fail)
      {'arxiv=1501.4444v1'},                        -- with version number (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< A S I N >----------------------------------------------------------------------
]]

function p:test_asin()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'asin=4-12346789X'},                       -- invalid char: hyphen (fail)
      {'asin=412346789'},                         -- length (9) (fail)
      {'asin=ABCDEFGHIJK'},                       -- length (11) (fail)
      {'asin=ABCDEFGHIJ'},                        -- valid (pass)
      {'asin=412346789X'},                        -- valid (isbn) (pass)
      {'asin=6302732913'},                        -- valid (but not an isbn) (pass)

      {'asin=ABCDEFGHIJ|asin-tld=com'},                 -- invalid tld (fail)
      {'asin=ABCDEFGHIJ|asin-tld=jp'},                  -- valid tld (pass)
      {'asin=ABCDEFGHIJ|asin-tld=uk'},                  -- valid tld (pass)
      {'asin=ABCDEFGHIJ|asin-tld=au'},                  -- valid tld (pass)
      {'asin=ABCDEFGHIJ|asin-tld=br'},                  -- valid tld (pass)
      {'asin=ABCDEFGHIJ|asin-tld=mx'},                  -- valid tld (pass)
      
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< B I B C O D E >----------------------------------------------------------------
]]

function p:test_bibcode()
  local this_year = today_plus_offset_get ('Y', '0 year');          -- get this year
  
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
                                        -- years
      {'bibcode=0999a&1.b2.c3.d4..e'},                  -- invalid yyyy (fail)
      {'bibcode=1000a&1.b2.c3.d4..e'},                  -- valid yyyy (pass)
      {'bibcode=' .. this_year .. 'a&1.b2.c3.d4..e'},           -- valid yyyy (pass)
      {'bibcode=' .. today_plus_offset_get ('Y', '1 year') .. 'a&1.b2.c3.d4..e'}, -- valid yyyy (pass)
      {'bibcode=' .. today_plus_offset_get ('Y', '2 year') .. 'a&1.b2.c3.d4..e'}, -- invalid yyyy (fail)

      {'bibcode=' .. this_year .. '#&1.b2.c3.d4..e'},           -- invalid [5] (fail)
      {'bibcode=' .. this_year .. 'a#1.b2.c3.d4..e'},           -- invalid [6] (fail)
      {'bibcode=' .. this_year .. 'a&#.b2.c3.d4..e'},           -- invalid [7] (fail)
      {'bibcode=' .. this_year .. 'a&1#b2.c3.d4..e'},           -- invalid [8] (fail)
      
      {'bibcode=' .. this_year .. 'a&..b2.c3.d4..e'},           -- ampersand preceeds dot (fail)

      {'bibcode=' .. this_year .. 'a&1.#2.c3.d4..e'},           -- invalid [9] (fail)
      {'bibcode=' .. this_year .. 'a&1.b#.c3.d4..e'},           -- invalid [10] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2#c3.d4..e'},           -- invalid [11] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.#3.d4..e'},           -- invalid [12] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c#.d4..e'},           -- invalid [13] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c3#d4..e'},           -- invalid [14] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c3.#4..e'},           -- invalid [15] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c3.d#..e'},           -- invalid [16] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c3.d4#.e'},           -- invalid [17] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c3.d4.#e'},           -- invalid [18] (fail)
      {'bibcode=' .. this_year .. 'a&1.b2.c3.d4..#'},           -- invalid [19] (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< B I O R X I V >----------------------------------------------------------------
]]

function p:test_biorxiv()
  local today = today_plus_offset_get ('Y.m.d', '0 year');          
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
                                        -- years
      {'biorxiv=10.1100/666666'},                     -- invalid prefix (fail)
      {'biorxiv=10.1101/666666'},                     -- valid prefix (pass)
      {'biorxiv=11.1101/666666'},                     -- invalid prefix (fail)

      {'biorxiv=10.1101/55555'},                      -- invalid identifier (fail)
      {'biorxiv=10.1101/7777777'},                    -- invalid identifier (fail)
----      
      {'biorxiv=10.1100/2019.12.10.666666'},                -- invalid date (fail)
      {'biorxiv=10.1101/2019.12.11.666666'},                -- valid date (pass)
      {'biorxiv=10.1101/2019.00.11.666666'},                -- invalid date (fail)
      {'biorxiv=10.1101/2019.13.11.666666'},                -- invalid date (fail)
      {'biorxiv=10.1101/2019.12.00.666666'},                -- invalid date (fail)
      {'biorxiv=10.1101/2019.12.32.666666'},                -- invalid date (fail)
      
      {'biorxiv=10.1101/' .. today .. '.666666'},             -- valid date (pass)
      {'biorxiv=10.1101/' .. today_plus_offset_get ('Y.m.d', '1 year') .. '.666666'}, -- valid date (pass)

      {'biorxiv=10.1101/' .. today .. '55555'},             -- invalid identifier (fail)
      {'biorxiv=10.1101/' .. today .. '7777777'},             -- invalid identifier (fail)

      {'biorxiv=10.1101/' .. today .. '.666666v'},              -- valid date (pass)
      {'biorxiv=10.1101/' .. today .. '.666666v1'},             -- valid date (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< C I T E S E E R X >------------------------------------------------------------
]]

function p:test_citeseerx()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'citeseerx=11.1.1.1234.1234'},                   -- invalid site id (fail)
      {'citeseerx=10.0.1.1234.1234'},                   -- invalid deployment id (fail)
      {'citeseerx=10.1.0.1234.1234'},                   -- invalid type (fail)
      {'citeseerx=10.1.1.0234.1234'},                   -- invalid bin (fail)
      {'citeseerx=10.1.1.1234.0234'},                   -- invalid record (fail)
      {'citeseerx=10.1.1.1234.1234'},                   -- invalid record (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< D O I >------------------------------------------------------------------------
]]

function p:test_doi()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'doi=10.1000/something'},                      -- valid directory indicator (pass)
      {'doi=11.1000/something'},                      -- invalid directory indicator (fail)
      {'doi=10.10 00/something'},                     -- invalid registrant (fail)
      {'doi=10.5555/something'},                      -- invalid registrant (fail)
      {'doi=10.666666/something'},                    -- invalid registrant (fail)

  -- four digit < registrant w/o subcode
      {'doi=10.1/something'},                       -- invalid registrant (fail)
      {'doi=10.22/something'},                      -- invalid registrant (fail)
      {'doi=10.333/something'},                     -- invalid registrant (fail)

  -- four digit < registrant w/ subcode
      {'doi=10.1.1/something'},                     -- valid registrant (pass)
      {'doi=10.22.1/something'},                      -- valid registrant (pass)
      {'doi=10.333.1/something'},                     -- valid registrant (pass)

  -- four digit registrant w/o subcode
      {'doi=10.0999/something'},                      -- invalid registrant (fail)
      {'doi=10.1000/something'},                      -- valid registrant (pass)
      {'doi=10.9999/something'},                      -- valid registrant (pass)

  -- four digit registrant w/ subcode
      {'doi=10.0999.1/something'},                    -- invalid registrant (fail)
      {'doi=10.1000.1/something'},                    -- valid registrant (pass)
      {'doi=10.9999.1/something'},                    -- valid registrant (pass)

  -- five digit registrant w/o subcode
      {'doi=10.09999/something'},                     -- invalid registrant (fail)
      {'doi=10.10000/something'},                     -- valid registrant (pass)
      {'doi=10.59999/something'},                     -- valid registrant (pass)
      {'doi=10.60000/something'},                     -- invalid registrant (fail)

  -- five digit registrant w/ subcode
      {'doi=10.09999.1/something'},                   -- invalid registrant (fail)
      {'doi=10.10000.1/something'},                   -- valid registrant (pass)
      {'doi=10.39999.1/something'},                   -- valid registrant (pass)
      {'doi=10.40000.1/something'},                   -- invalid registrant (fail)

  -- terminal punctuation
      {'doi=10.1000/something.'},                     -- trailing dot (fail)
      {'doi=10.1000/something,'},                     -- trailing comma (fail)

      {'doi=10.1000/some thing'},                     -- space character in identifier (fail)

  -- doi-broken date
      {'doi=10.1000/something |doi-broken-date=2020'},          -- valid doi-broken date (pass)
      {'doi=10.1000/something |doi-broken-date=January 1900'},      -- valid doi-broken date (pass) TODO: valid but not valid; limit to same-as-access-date?
      {'doi=10.1000/something |doi-broken-date=XXXX'},          -- invalid doi-broken date (fail)
      {'doi=10.1000/something |doi-broken-date=January 3500'},      -- invalid doi-broken date (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< H D L >------------------------------------------------------------------------
]]

function p:test_hdl()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'hdl=abc 123/abc123'},                       -- invalid prefix (fail)
      {'hdl=abc–123/abc123'},                       -- invalid prefix (fail)
      {'hdl=abc123/abc 123'},                       -- invalid suffix (fail)
      {'hdl=abc123/abc–123'},                       -- invalid suffix (fail)
      {'hdl=abc123/abc123.'},                       -- trailing dot (fail)
      {'hdl=abc123/abc123,'},                       -- trailing comma (fail)
      {'hdl=abc123/abc123'},                        -- valid (pass)

    -- query strings
      {'hdl=abc123/abc123?not_a_query=string'},             -- valid (pass)
      {'hdl=abc123/abc123?noredirect=string'},              -- valid (pass) TODO: does this take a value?
      {'hdl=abc123/abc123?ignore_aliases=string'},            -- valid (pass) TODO: does this take a value?
      {'hdl=abc123/abc123?auth=string'},                  -- valid (pass) TODO: does this take a value?
      {'hdl=abc123/abc123?cert=string'},                  -- valid (pass) TODO: does this take a value?
      {'hdl=abc123/abc123?index=string'},                 -- valid (pass)
      {'hdl=abc123/abc123?type=string'},                  -- valid (pass)
      {'hdl=abc123/abc123?urlappend=string'},               -- valid (pass)
      {'hdl=abc123/abc123?locatt=string'},                -- valid (pass)
      {'hdl=abc123/abc123?action=string'},                -- valid (pass)

    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ I S B N >------------------------------------------------------------
]]

function p:test_isbn()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'isbn=3–123467899'},                       -- invalid character (ndash) (fail)
      {'isbn=312346789'},                         -- length (9) (fail)
      {'isbn=31234678999'},                       -- length (11) (fail)
      {'isbn=41234678X9'},                        -- X in the wrong spot (fail)
      {'isbn=3123467896'},                        -- checkdigit (fail)
      {'isbn=3123467899'},                        -- valid (pass)
      {'isbn=412346789X'},                        -- valid (pass)
      {'isbn=3-123467899'},                       -- valid (pass)
      {'isbn=4-12346789X'},                       -- valid (pass)
      {'isbn=3 123467899'},                       -- valid (pass)
      {'isbn=4 12346789X'},                       -- valid (pass)

      {'isbn=978-01234567866'},                     -- length (14) (fail)
      {'isbn=978-012345678'},                       -- length (12) (fail)

      {'isbn=978-012345678X'},                      -- isbn13 is digits only (fail)
      {'isbn=977-0123456786'},                      -- 978 or 979 prefix only (fail)
      {'isbn=979-0123456785'},                      -- 9790 is ismn (fail)
      {'isbn=978-0123456788'},                      -- check digit (fail)
      
      {'isbn=9780123456786'},                       -- valid 978 (pass)
      {'isbn=9791123456782'},                       -- valid 979 (pass)
      {'isbn=978-0123456786'},                      -- valid 978 (pass)
      {'isbn=979-1123456782'},                      -- valid 979 (pass)
      {'isbn=978 0123456786'},                      -- valid 978 (pass)
      {'isbn=979 1123456782'},                      -- valid 979 (pass)

      {'isbn=3123467896 |ignore-isbn-error=yes'},             -- checkdigit (pass)
      {'isbn=3123467899 |ignore-isbn-error=yes'},             -- valid (pass)
      {'isbn=978-0123456788 |ignore-isbn-error=yes'},           -- check digit (pass)
      {'isbn=9780123456786 |ignore-isbn-error=yes'},            -- valid 978 (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ I S M N >------------------------------------------------------------
]]

function p:test_ismn()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'ismn=979-01234567856'},                     -- length (14) (fail)
      {'ismn=979-012345678'},                       -- length (12) (fail)
      {'ismn=979-012345678X'},                      -- digits only (fail)
      {'ismn=979-1123456782'},                      -- group designator must be 0 (fail)
      {'ismn=979-0123456788'},                      -- check digit (fail)

      {'ismn=979–0123456785'},                      -- valid (pass)
      {'ismn=9790123456785'},                       -- valid (pass)
      {'ismn=979-0123456785'},                      -- valid (pass)
      {'ismn=979 0123456785'},                      -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ I S S N >------------------------------------------------------------
]]

function p:test_issn()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'issn=0123-45601'},                        -- length (9) (fail)
      {'issn=0123-456'},                          -- length (7) (fail)
      {'issn=7123-45X6'},                         -- X mispositioned (fail)
      {'issn=0123-4566'},                         -- check digit (fail)

      {'issn=0123–4560'},                         -- valid (pass)
      {'issn=01234560'},                          -- valid (pass)
      {'issn=7123-456X'},                         -- valid (pass)
      {'issn=7123 456X'},                         -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ J F M >--------------------------------------------------------------
]]

function p:test_jfm()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'jfm=1.4444.22'},                          -- missing digit (fail)
      {'jfm=22.333.22'},                          -- missing digit (fail)
      {'jfm=22.4444.1'},                          -- missing digit (fail)

      {'jfm=333.4444.22'},                        -- to many digit (fail)
      {'jfm=22.55555.22'},                        -- to many digit (fail)
      {'jfm=22.4444.333'},                        -- to many digit (fail)

      {'jfm=224444.22'},                          -- missing separator (fail)
      {'jfm=22.444422'},                          -- missing separator (fail)

      {'jfm=jfm22.4444.22'},                        -- jfm prefix (pass)
      {'jfm=22.4444.22'},                         -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ L C C N >------------------------------------------------------------
]]

function p:test_lccn()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
    -- length 8
      {'lccn=7777777'},                         -- missing digit (fail)
      {'lccn=8888888a'},                          -- not all digit (fail)
      {'lccn=888 8888'},                          -- space (fail)
      {'lccn=88888888'},                          -- valid (pass)
    -- length 9
      {'lccn=999999999'},                         -- to many digit (fail)
      {'lccn=A99999999'},                         -- case (fail)
      {'lccn=a99999999'},                         -- valid (pass)
    -- length 10
      {'lccn=a000000000'},                        -- not all digit (fail)
      {'lccn=AA00000000'},                        -- case (fail)
      {'lccn=000 000000'},                        -- space (fail) TODO: fix this: renders as 000000 000 000000
      {'lccn=0000000000'},                        -- valid (pass)
      {'lccn=aa00000000'},                        -- valid (pass)
    -- length 11
      {'lccn=11111111111'},                       -- all digit (fail)
      {'lccn=aa111111111'},                       -- not enough alpha (fail)
      {'lccn=A1111111111'},                       -- case (fail)
      {'lccn=AAA11111111'},                       -- case (fail)
      {'lccn=a1111111111'},                       -- valid (pass)
      {'lccn=aaa11111111'},                       -- valid (pass)
    -- length 12
      {'lccn=222222222222'},                        -- all digit (fail)
      {'lccn=a22222222222'},                        -- not enough alpha (fail)
      {'lccn=AA2222222222'},                        -- case (fail)
      {'lccn=aa2222222222'},                        -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ M R >----------------------------------------------------------------
]]

function p:test_mr()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'mr=88888888'},                          -- to many digit (fail)
      {'mr=a777777'},                           -- non-digit (fail)
      {'mr=7777777'},                           -- valid (pass)

      {'mr=MR7777777'},                         -- valid (pass)
      {'mr=MR7'},                             -- zero fill valid (pass)
      {'mr=7'},                             -- zero fill valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ O C L C >------------------------------------------------------------
]]

function p:test_oclc()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'oclc=ocm8888888'},                        -- not enough digit (fail)
      {'oclc=ocm888888888'},                        -- too many digit (fail)
      {'oclc=OCM88888888'},                       -- case (fail)
      {'oclc=ocm88888888'},                       -- valid (pass)

      {'oclc=ocn99999999'},                       -- not enough digit (fail)
      {'oclc=ocn9999999999'},                       -- too many digit (fail)
      {'oclc=OCN999999999'},                        -- case (fail)
      {'oclc=ocn999999999'},                        -- valid (pass)

      {'oclc=on000000000'},                       -- not enough digit (fail)
      {'oclc=ON0000000000'},                        -- case (fail)
      {'oclc=on0000000000'},                        -- valid (pass)

      {'oclc=(OCoLC)07'},                         -- leading 0 (fail)
      {'oclc=(OCoLC)9999999999'},                     -- too many digit (fail)
      {'oclc=(ocolc)07'},                         -- case (fail)
      {'oclc=OCoLC9'},                          -- missing parentheses (fail)
      {'oclc=(OCoLC)9'},                          -- valid (pass)
      {'oclc=(OCoLC)999999999'},                      -- valid (pass)

      {'oclc=00000000000'},                       -- too many digit (fail)
      {'oclc=000X000000'},                        -- non-digit (fail)
      {'oclc=0000000000'},                        -- valid (pass)
      {'oclc=0'},                             -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ O L >----------------------------------------------------------------
]]

function p:test_ol()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'ol=OLA'},                             -- no digit (fail)

      {'ol=ol22A'},                           -- prefix case (fail)
      {'ol=LO22A'},                           -- invalid prefix (fail)
      {'ol=OL 22A'},                            -- space (fail)

      {'ol=333'},                             -- no suffix (fail)
      {'ol=333a'},                            -- suffix case (fail)
      {'ol=333m'},                            -- suffix case (fail)
      {'ol=333w'},                            -- suffix case (fail)
      {'ol=333R'},                            -- unknown suffix (fail)

      {'ol=OL4444A'},                           -- valid (pass)
      {'ol=4444A'},                           -- valid (pass)
      {'ol=OL55555M'},                          -- valid (pass)
      {'ol=55555M'},                            -- valid (pass)
      {'ol=OL666666W'},                         -- valid (pass)
      {'ol=666666W'},                           -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ P M C >--------------------------------------------------------------
]]

function p:test_pmc()
  local limit = live_cfg.id_handlers['PMC'].id_limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'pmc=PMC'},                            -- no digit (fail)

      {'pmc=0'},                              -- out of bounds (fail)
      {'pmc=1'},                              -- in bounds (pass)
      {'pmc=' .. limit},                          -- in bounds (pass)
      {'pmc=' .. limit+1},                        -- out of bounds (fail)

      {'pmc=PMC1'},                           -- valid (pass)
      {'pmc=PMC1 |doi=10.1000/something |doi-access=free'},       -- title linked from pmc

      {'pmc=22 |pmc-embargo-date=' .. today_plus_offset_get ('Y-m-d', '1 days')}, -- valid still embargoed

      {'pmc=22 |pmc-embargo-date=' .. today_plus_offset_get ('Y-m-d', '0 days')}, -- valid (pass)
      {'pmc=22 |pmc-embargo-date=' .. today_plus_offset_get ('F j, Y', '0 days')},  -- valid (pass)
      {'pmc=22 |pmc-embargo-date=' .. today_plus_offset_get ('j F Y', '0 days')}, -- valid (pass)
      {'pmc=22 |pmc-embargo-date=' .. today_plus_offset_get ('F Y', '0 days')}, -- valid (pass)
      {'pmc=22 |pmc-embargo-date=' .. today_plus_offset_get ('Y', '0 days')},   -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
  
  limit = new_cfg.id_handlers['PMC'].id_limit;                -- get samdbox limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Sandbox limit test |', '}}', '{{cite book |title=Sandbox limit test |', '}}',
    {
      {'pmc=' .. limit},                          -- in bounds (pass)
      {'pmc=' .. limit+1},                        -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ P M I D >------------------------------------------------------------
]]

function p:test_pmid()
  local limit = live_cfg.id_handlers['PMID'].id_limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'pmid=pmid'},                            -- no digit (fail)

      {'pmid=0'},                             -- out of bounds (fail)
      {'pmid=1'},                             -- in bounds (pass)
      {'pmid=' .. limit},                         -- in bounds (pass)
      {'pmid=' .. limit+1},                       -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )

  limit = new_cfg.id_handlers['PMID'].id_limit;               -- get samdbox limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Sandbox limit test |', '}}', '{{cite book |title=Sandbox limit test |', '}}',
    {
      {'pmid=' .. limit},                         -- in bounds (pass)
      {'pmid=' .. limit+1},                       -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ Q I D >--------------------------------------------------------------
]]

function p:test_qid()
  self:preprocess_equals_preprocess_many(
      '{{cite journal/new |title=Title |journal=Journal |', '}}', '{{cite journal |title=Title |journal=Journal |', '}}',
    {
      {'q=Q'},                              -- no digit (fail)
      {'q=q1'},                             -- not uppercase Q (fail)
      {'q=Q1'},                             -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ S 2 C I D >----------------------------------------------------------
]]

function p:test_s2cid()
  local limit = live_cfg.id_handlers['S2CID'].id_limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'s2cid=s2cid'},                          -- no digit (fail)

      {'s2cid=0'},                            -- out of bounds (fail)
      {'s2cid=1'},                            -- in bounds (pass)
      {'s2cid=' .. limit},                        -- in bounds (pass)
      {'s2cid=' .. limit+1},                        -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )

  limit = new_cfg.id_handlers['S2CID'].id_limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Sandbox limit test |', '}}', '{{cite book |title=Sandbox limit test |', '}}',
    {
      {'s2cid=' .. limit},                        -- in bounds (pass)
      {'s2cid=' .. limit+1},                        -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )end


--[[--------------------------< T E S T _ S B N >--------------------------------------------------------------
]]

function p:test_sbn()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'sbn=0–12345679'},                         -- invalid character (ndash) (fail)
      {'sbn=01234567'},                         -- length (8) (fail)
      {'sbn=0123456799'},                         -- length (10) (fail)
      {'sbn=6123456X7'},                          -- X in the wrong spot (fail)
      {'sbn=012345678'},                          -- checkdigit (fail)
      {'sbn=012345679'},                          -- valid (pass)
      {'sbn=61234567X'},                          -- valid (pass)
      {'sbn=0-12345679'},                         -- valid (pass)
      {'sbn=6-1234567X'},                         -- valid (pass)
      {'sbn=0 12345679'},                         -- valid (pass)
      {'sbn=6 1234567X'},                         -- valid (pass)

    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ S S R N >------------------------------------------------------------
]]

function p:test_ssrn()
  local limit = live_cfg.id_handlers['SSRN'].id_limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'ssrn=ssrn'},                            -- no digit (fail)

      {'ssrn=99'},                            -- out of bounds (fail)
      {'ssrn=100'},                           -- in bounds (pass)
      {'ssrn=' .. limit},                         -- in bounds (pass)
      {'ssrn=' .. limit+1},                       -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )
  
  limit = new_cfg.id_handlers['SSRN'].id_limit
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Sandbox limit test |', '}}', '{{cite book |title=Sandbox limit test |', '}}',
    {
      {'ssrn=' .. limit},                         -- in bounds (pass)
      {'ssrn=' .. limit+1},                       -- out of bounds (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ M E S S A G E - I D >------------------------------------------------
]]

function p:test_message_id()
    self:preprocess_equals_preprocess_many(
      '{{cite newsgroup/new |title=Title |', '}}', '{{cite newsgroup |title=Title |', '}}',
    {
      {'message-id=something'},                     -- missing '@' (fail)
      {'message-id=<something@somewhere'},                -- leading '<' (fail)
      {'message-id=something@somewhere>'},                -- trailing '>' (fail)
      {'message-id=something@somewhere'},                 -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ Z B L >--------------------------------------------------------------
]]

function p:test_zbl()
    self:preprocess_equals_preprocess_many(
      '{{cite newsgroup/new |title=Title |', '}}', '{{cite newsgroup |title=Title |', '}}',
    {
      {'zbl=7777777'},                          -- length (temp form) (fail)
      {'zbl=999999999'},                          -- length (temp form) (fail)
      {'zbl=aaaaaaaa'},                         -- must be digits (temp form) (fail)
      {'zbl=88888888'},                         -- valid (temp form) (pass)

      {'zbl=444455555'},                          -- missing dot (fail)
      {'zbl=333.666666'},                         -- dot misplaced (fail)
      {'zbl=4444.55555'},                         -- valid (pass)
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ A U T O _ L I N K  >----------------------------------------=========
]]

function p:test_auto_link()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |doi-access=free |', '}}', '{{cite book |title=Title |doi-access=free |', '}}',
    {
      {'doi=10.1000/something'},              -- title not linked
      {'pmc=1 |doi=10.1000/something'},         -- title not linked
    },
    {nowiki=false, templatestyles=true}
  );

    self:preprocess_equals_preprocess_many(
      '{{cite journal/new |title=Title |journal=Journal |', '}}', '{{cite journal |title=Title |journal=Journal |', '}}',
    {
      {'doi=10.1000/something |doi-access=free |doi-broken-date=2020-09-09'}, -- title linked by doi; TODO: but should it be linked?
      {'doi=10.1000/some thing |doi-access=free'},            -- title linked by doi; TODO: but should it be linked?
      {'doi=10.1000/something |doi-access=free'},             -- title linked by doi

      {'pmc=1 |doi=10.1000/something |doi-access=free |pmc-embargo-date=' .. today_plus_offset_get ('Y-m-d', '1 days')},  -- embargoed pmc; title linked by doi
      {'pmc=1 |doi=10.1000/something |doi-access=free'},          -- title linked by pmc

      {'pmc=1 |pmc-embargo-date=' .. today_plus_offset_get ('Y-m-d', '1 days')},  -- title not linked
      {'pmc=0 |pmc-embargo-date=' .. today_plus_offset_get ('Y-m-d', '1 days')},  -- title not linked

      {'pmc=0 |doi=10.1000/something |doi-access=free'},          -- title linked by pmc; TODO: but shouldn't it be linked by doi?
      {'pmc=0 |doi=10.1000/something |doi-access=free |doi-broken-date=2020-09-09'},  -- title linked by pmc; TODO: should not be linked?
      {'pmc=0 |doi=10.1000/something |doi-access=free |doi-broken-date=2020-09-09 |pmc-embargo-date=' .. today_plus_offset_get ('Y-m-d', '1 days')},  -- title linked by pmc; TODO: should not be linked?
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ A C C E S S _ I C O N S >--------------------------------------------
]]

function p:test_access_icons()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'bibcode=1000a&1.b2.c3.d4..e |bibcode-access=free'},
      {'doi=10.1000/something |doi-access=free'},
      {'hdl=abc123/abc123 |hdl-access=free'},
      {'jstor=12345 |jstor-access=free'},
      {'ol=OL4444A |ol-access=free'},
      {'osti=15005772 |osti-access=free'},
      {'s2cid=30337924  |s2cid-access=free'},
    },
    {nowiki=false, templatestyles=true}
  )
end


--[[--------------------------< T E S T _ A C C E P T _ A S _ W R I T T E N >----------------------------------
]]

function p:test_accept_as_written()
    self:preprocess_equals_preprocess_many(
      '{{cite book/new |title=Title |', '}}', '{{cite book |title=Title |', '}}',
    {
      {'doi=((10.1000/something.))'},
      {'eissn=((0123-4566))'},                      -- check digit (fail)
      {'isbn=((3123467896))'},                      -- checkdigit (fail)
      {'isbn=((978-01234567866))'},                   -- length (14) (fail)
      {'isbn=((978-0123456788))'},                    -- check digit (fail)
      {'issn=((0123-4566))'},                       -- check digit (fail)
      {'sbn=((012345678))'},                        -- checkdigit (fail)
    },
    {nowiki=false, templatestyles=true}
  )
end


return p