jenkins-bot has submitted this change and it was merged.

Change subject: Improve error messages in mw.html
......................................................................


Improve error messages in mw.html

Add more information to error messages in mw.html. This includes the
error level, the function name, and the position of the argument in the
argument list. Where possible, use the functions in libraryUtil.lua to
do this.

Some functions in mw.html accept multiple types, so add a checkTypeMulti
function to libraryUtil.lua to make these kinds of functions easy to check.
And while we're at it, add test cases for libraryUtil.lua as well.

Change-Id: If9cf9a52bd4b1bb42cc7f9f1f1096828710cbc52
---
M common/Hooks.php
M engines/LuaCommon/lualib/libraryUtil.lua
M engines/LuaCommon/lualib/mw.html.lua
M tests/engines/LuaCommon/HtmlLibraryTests.lua
A tests/engines/LuaCommon/LibraryUtilTest.php
A tests/engines/LuaCommon/LibraryUtilTests.lua
6 files changed, 373 insertions(+), 83 deletions(-)

Approvals:
  Jackmcbarn: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/common/Hooks.php b/common/Hooks.php
index cd5fb26..2553984 100644
--- a/common/Hooks.php
+++ b/common/Hooks.php
@@ -345,6 +345,7 @@
                        'engines/LuaCommon/HtmlLibraryTest.php',
                        'engines/LuaCommon/LanguageLibraryTest.php',
                        'engines/LuaCommon/UstringLibraryPureLuaTest.php',
+                       'engines/LuaCommon/LibraryUtilTest.php',
                );
                foreach ( $tests as $test ) {
                        $files[] = __DIR__ . '/../tests/' . $test;
diff --git a/engines/LuaCommon/lualib/libraryUtil.lua 
b/engines/LuaCommon/lualib/libraryUtil.lua
index 5dd35ff..f14a795 100644
--- a/engines/LuaCommon/lualib/libraryUtil.lua
+++ b/engines/LuaCommon/lualib/libraryUtil.lua
@@ -12,6 +12,29 @@
        end
 end
 
+function libraryUtil.checkTypeMulti( name, argIdx, arg, expectTypes )
+       local argType = type( arg )
+       for _, expectType in ipairs( expectTypes ) do
+               if argType == expectType then
+                       return
+               end
+       end
+       local n = #expectTypes
+       local typeList
+       if n > 1 then
+               typeList = table.concat( expectTypes, ', ', 1, n - 1 ) .. ' or 
' .. expectTypes[n]
+       else
+               typeList = expectTypes[1]
+       end
+       local msg = string.format( "bad argument #%d to '%s' (%s expected, got 
%s)",
+               argIdx,
+               name,
+               typeList,
+               type( arg )
+       )
+       error( msg, 3 )
+end
+
 function libraryUtil.checkTypeForIndex( index, value, expectType )
        if type( value ) ~= expectType then
                local msg = string.format( "value for index '%s' must be %s, %s 
given",
diff --git a/engines/LuaCommon/lualib/mw.html.lua 
b/engines/LuaCommon/lualib/mw.html.lua
index 26b8034..c143266 100644
--- a/engines/LuaCommon/lualib/mw.html.lua
+++ b/engines/LuaCommon/lualib/mw.html.lua
@@ -15,6 +15,10 @@
 
 local HtmlBuilder = {}
 
+local util = require 'libraryUtil'
+local checkType = util.checkType
+local checkTypeMulti = util.checkTypeMulti
+
 local metatable = {}
 local methodtable = {}
 
@@ -86,12 +90,54 @@
        return ( string.gsub( s, '[<>&"]', htmlencodeMap ) )
 end
 
- local function cssEncode( s )
+local function cssEncode( s )
        -- XXX: I'm not sure this character set is complete.
        -- bug #68011: allow delete character (\127)
        return mw.ustring.gsub( s, '[^\32-\57\60-\127]', function ( m )
                return string.format( '\\%X ', mw.ustring.codepoint( m ) )
        end )
+end
+
+-- Create a builder object. This is a separate function so that we can show the
+-- correct error levels in both HtmlBuilder.create and metatable.tag.
+--
+-- @param tagName
+-- @param args
+local function createBuilder( tagName, args )
+       if tagName ~= nil and tagName ~= '' and not isValidTag( tagName ) then
+               error( string.format( "invalid tag name '%s'", tagName ), 3 )
+       end
+
+       args = args or {}
+       local builder = {}
+       setmetatable( builder, metatable )
+       builder.nodes = {}
+       builder.attributes = {}
+       builder.styles = {}
+
+       if tagName ~= '' then
+               builder.tagName = tagName
+       end
+
+       builder.parent = args.parent
+       builder.selfClosing = selfClosingTags[tagName] or args.selfClosing or 
false
+       return builder
+end
+
+-- Append a builder to the current node. This is separate from methodtable.node
+-- so that we can show the correct error level in both methodtable.node and
+-- methodtable.wikitext.
+--
+-- @param builder
+local function appendBuilder( t, builder )
+       if t.selfClosing then
+               error( "self-closing tags can't have child nodes", 3 )
+       end
+
+       if builder then
+               table.insert( t.nodes, builder )
+       end
+       return t
 end
 
 methodtable._build = function( t, ret )
@@ -144,25 +190,15 @@
 --
 -- @param builder
 methodtable.node = function( t, builder )
-       if t.selfClosing then
-               error( "Self-closing tags can't have child nodes" )
-       end
-
-       if builder then
-               table.insert( t.nodes, builder )
-       end
-       return t
+       return appendBuilder( t, builder )
 end
 
 -- Appends some markup to the node. This will be treated as wikitext.
 methodtable.wikitext = function( t, ... )
        local vals = {...}
        for i = 1, #vals do
-               if type( vals[i] ) ~= 'string' and type( vals[i] ) ~= 'number' 
then
-                       error( 'Invalid wikitext given: Must be either a string 
or a number' )
-               end
-
-               t:node( vals[i] )
+               checkTypeMulti( 'wikitext', i, vals[i], { 'string', 'number' } )
+               appendBuilder( t, vals[i] )
        end
        return t
 end
@@ -179,9 +215,12 @@
 -- @param tagName
 -- @param args
 methodtable.tag = function( t, tagName, args )
+       checkType( 'tag', 1, tagName, 'string' )
+       checkType( 'tag', 2, args, 'table', true )
        args = args or {}
+
        args.parent = t
-       local builder = HtmlBuilder.create( tagName, args )
+       local builder = createBuilder( tagName, args )
        t:node( builder )
        return builder
 end
@@ -190,6 +229,8 @@
 --
 -- @param name
 methodtable.getAttr = function( t, name )
+       checkType( 'getAttr', 1, name, 'string' )
+
        local attr = getAttr( t, name )
        if attr then
                return attr.val
@@ -204,7 +245,11 @@
 methodtable.attr = function( t, name, val )
        if type( name ) == 'table' then
                if val ~= nil then
-                       error( 'If a key->value table is given as first 
parameter, value must be left empty' )
+                       error(
+                               "bad argument #2 to 'attr' " ..
+                               '(if argument #1 is a table, argument #2 must 
be left empty)',
+                               2
+                       )
                end
 
                local callForTable = function()
@@ -214,18 +259,18 @@
                end
 
                if not pcall( callForTable ) then
-                       error( 'Invalid table given: Must be name (string) 
value (string|number) pairs' )
+                       error(
+                               "bad argument #1 to 'attr' " ..
+                               '(table keys must be strings, and values must 
be strings or numbers)',
+                               2
+                       )
                end
 
                return t
        end
 
-       if type( name ) ~= 'string' then
-               error( 'Invalid name given: The name must be a string' )
-       end
-       if val ~= nil and type( val ) ~= 'string' and type( val ) ~= 'number' 
then
-               error( 'Invalid value given: The value must be either a string 
or a number' )
-       end
+       checkType( 'attr', 1, name, 'string' )
+       checkTypeMulti( 'attr', 2, val, { 'string', 'number', 'nil' } )
 
        -- if caller sets the style attribute explicitly, then replace all 
styles
        -- previously added with css() and cssText()
@@ -235,7 +280,10 @@
        end
 
        if not isValidAttributeName( name ) then
-               error( "Invalid attribute name: " .. name )
+               error( string.format(
+                       "bad argument #1 to 'attr' (invalid attribute name 
'%s')",
+                       name
+               ), 2 )
        end
 
        local attr, i = getAttr( t, name )
@@ -257,12 +305,10 @@
 --
 -- @param class
 methodtable.addClass = function( t, class )
+       checkTypeMulti( 'addClass', 1, class, { 'string', 'number', 'nil' } )
+
        if class == nil then
                return t
-       end
-
-       if type( class ) ~= 'string' and type( class ) ~= 'number' then
-               error( 'Invalid class given: The name must be either a string 
or a number' )
        end
 
        local attr = getAttr( t, 'class' )
@@ -282,7 +328,11 @@
 methodtable.css = function( t, name, val )
        if type( name ) == 'table' then
                if val ~= nil then
-                       error( 'If a key->value table is given as first 
parameter, value must be left empty' )
+                       error(
+                               "bad argument #2 to 'css' " ..
+                               '(if argument #1 is a table, argument #2 must 
be left empty)',
+                               2
+                       )
                end
 
                local callForTable = function()
@@ -292,18 +342,18 @@
                end
 
                if not pcall( callForTable ) then
-                       error( 'Invalid table given: Must be name 
(string|number) value (string|number) pairs' )
+                       error(
+                               "bad argument #1 to 'css' " ..
+                               '(table keys and values must be strings or 
numbers)',
+                               2
+                       )
                end
 
                return t
        end
 
-       if type( name ) ~= 'string' and type( name ) ~= 'number' then
-               error( 'Invalid CSS given: The name must be either a string or 
a number' )
-       end
-       if val ~= nil and type( val ) ~= 'string' and type( val ) ~= 'number' 
then
-               error( 'Invalid CSS given: The value must be either a string or 
a number' )
-       end
+       checkTypeMulti( 'css', 1, name, { 'string', 'number' } )
+       checkTypeMulti( 'css', 2, val, { 'string', 'number', 'nil' } )
 
        for i, prop in ipairs( t.styles ) do
                if prop.name == name then
@@ -328,11 +378,8 @@
 --
 -- @param css
 methodtable.cssText = function( t, css )
+       checkTypeMulti( 'cssText', 1, css, { 'string', 'number', 'nil' } )
        if css ~= nil then
-               if type( css ) ~= 'string' and type( css ) ~= 'number' then
-                       error( 'Invalid CSS given: Must be either a string or a 
number' )
-               end
-
                table.insert( t.styles, css )
        end
        return t
@@ -359,30 +406,9 @@
 -- @param tagName
 -- @param args
 function HtmlBuilder.create( tagName, args )
-       if tagName ~= nil then
-               if type( tagName ) ~= 'string' then
-                       error( "Tag name must be a string" )
-               end
-
-               if tagName ~= '' and not isValidTag( tagName ) then
-                       error( "Invalid tag name: " .. tagName )
-               end
-       end
-
-       args = args or {}
-       local builder = {}
-       setmetatable( builder, metatable )
-       builder.nodes = {}
-       builder.attributes = {}
-       builder.styles = {}
-
-       if tagName ~= '' then
-               builder.tagName = tagName
-       end
-
-       builder.parent = args.parent
-       builder.selfClosing = selfClosingTags[tagName] or args.selfClosing or 
false
-       return builder
+       checkType( 'mw.html.create', 1, tagName, 'string', true )
+       checkType( 'mw.html.create', 2, args, 'table', true )
+       return createBuilder( tagName, args )
 end
 
 mw_interface = nil
diff --git a/tests/engines/LuaCommon/HtmlLibraryTests.lua 
b/tests/engines/LuaCommon/HtmlLibraryTests.lua
index b448056..f7ebfaf 100644
--- a/tests/engines/LuaCommon/HtmlLibraryTests.lua
+++ b/tests/engines/LuaCommon/HtmlLibraryTests.lua
@@ -118,11 +118,11 @@
        },
        { name = 'mw.html.create (invalid tag 1)', func = mw.html.create, 
type='ToString',
          args = { '$$$$' },
-         expect = 'Invalid tag name: $$$$'
+         expect = "invalid tag name '$$$$'"
        },
        { name = 'mw.html.create (invalid tag 2)', func = mw.html.create, 
type='ToString',
          args = { {} },
-         expect = 'Tag name must be a string'
+         expect = "bad argument #1 to 'mw.html.create' (string expected, got 
table)"
        },
        { name = 'mw.html.wikitext', func = testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'wikitext', 'Plain text' },
@@ -130,7 +130,7 @@
        },
        { name = 'mw.html.wikitext (invalid input)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'wikitext', 'Plain text', {} },
-         expect = 'Invalid wikitext given: Must be either a string or a number'
+         expect = "bad argument #2 to 'wikitext' (string or number expected, 
got table)"
        },
        { name = 'mw.html.newline', func = testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'newline' },
@@ -159,39 +159,47 @@
        },
        { name = 'mw.html.attr (invalid name 1)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'attr', 123, 'bar' },
-         expect = 'Invalid name given: The name must be a string'
+         expect = "bad argument #1 to 'attr' (string expected, got number)"
        },
        { name = 'mw.html.attr (invalid name 2)', func = testHelper,
          args = { getEmptyTestDiv(), 'attr', '§§§§', 'foo' },
-         expect = 'Invalid attribute name: §§§§'
+         expect = "bad argument #1 to 'attr' (invalid attribute name '§§§§')"
        },
        { name = 'mw.html.attr (table no value)', func = testHelper,
          args = { getEmptyTestDiv(), 'attr', { foo = 'bar' }, 'foo' },
-         expect = 'If a key->value table is given as first parameter, value 
must be left empty'
+         expect = "bad argument #2 to 'attr' (if argument #1 is a table, 
argument #2 must be left empty)"
        },
        { name = 'mw.html.attr (invalid value)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'attr', 'foo', true },
-         expect = 'Invalid value given: The value must be either a string or a 
number'
+         expect = "bad argument #2 to 'attr' (string, number or nil expected, 
got boolean)"
        },
        { name = 'mw.html.attr (invalid table 1)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'attr', { foo = {} } },
-         expect = 'Invalid table given: Must be name (string) value 
(string|number) pairs'
+         expect = "bad argument #1 to 'attr' " ..
+         '(table keys must be strings, and values must be strings or numbers)'
        },
        { name = 'mw.html.attr (invalid table 2)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'attr', { 1, 2 ,3 } },
-         expect = 'Invalid table given: Must be name (string) value 
(string|number) pairs'
+         expect = "bad argument #1 to 'attr' " ..
+         '(table keys must be strings, and values must be strings or numbers)'
        },
        { name = 'mw.html.attr (invalid table 3)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'attr', { foo = 'bar', blah = true } },
-         expect = 'Invalid table given: Must be name (string) value 
(string|number) pairs'
+         expect = "bad argument #1 to 'attr' " ..
+         '(table keys must be strings, and values must be strings or numbers)'
        },
        { name = 'mw.html.attr (invalid table 4)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'attr', { [{}] = 'foo' } },
-         expect = 'Invalid table given: Must be name (string) value 
(string|number) pairs'
+         expect = "bad argument #1 to 'attr' " ..
+         '(table keys must be strings, and values must be strings or numbers)'
        },
        { name = 'mw.html.getAttr (nil)', func = testHelper,
          args = { getEmptyTestDiv(), 'getAttr', 'foo' },
          expect = { nil }
+       },
+       { name = 'mw.html.getAttr (invalid name)', func = testHelper,
+         args = { getEmptyTestDiv(), 'getAttr', 123 },
+         expect = "bad argument #1 to 'getAttr' (string expected, got number)"
        },
        { name = 'mw.html.addClass', func = testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'addClass', 'foo' },
@@ -203,7 +211,7 @@
        },
        { name = 'mw.html.addClass (invalid value)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'addClass', {} },
-         expect = 'Invalid class given: The name must be either a string or a 
number'
+         expect = "bad argument #1 to 'addClass' (string, number or nil 
expected, got table)"
        },
        { name = 'mw.html.css', func = testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'css', 'foo', 'bar' },
@@ -219,15 +227,15 @@
        },
        { name = 'mw.html.css (invalid name 1)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'css', function() end, 'bar' },
-         expect = 'Invalid CSS given: The name must be either a string or a 
number'
+         expect = "bad argument #1 to 'css' (string or number expected, got 
function)"
        },
        { name = 'mw.html.css (table no value)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'css', {}, 'bar' },
-         expect = 'If a key->value table is given as first parameter, value 
must be left empty'
+         expect = "bad argument #2 to 'css' (if argument #1 is a table, 
argument #2 must be left empty)"
        },
        { name = 'mw.html.css (invalid value)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'css', 'foo', {} },
-         expect = 'Invalid CSS given: The value must be either a string or a 
number'
+         expect = "bad argument #2 to 'css' (string, number or nil expected, 
got table)"
        },
        { name = 'mw.html.css (table)', func = testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'css', testAttrs },
@@ -235,7 +243,8 @@
        },
        { name = 'mw.html.css (invalid table)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'css', { foo = 'bar', ab = true } },
-         expect = 'Invalid table given: Must be name (string|number) value 
(string|number) pairs'
+         expect = "bad argument #1 to 'css' " ..
+         '(table keys and values must be strings or numbers)'
        },
        { name = 'mw.html.cssText', func = testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'cssText', 'Unit tests, ftw' },
@@ -247,7 +256,7 @@
        },
        { name = 'mw.html.cssText (invalid value)', func = testHelper, 
type='ToString',
          args = { getEmptyTestDiv(), 'cssText', {} },
-         expect = 'Invalid CSS given: Must be either a string or a number'
+         expect = "bad argument #1 to 'cssText' (string, number or nil 
expected, got table)"
        },
        { name = 'mw.html attribute escaping (value with double quotes)', func 
= testHelper, type='ToString',
          args = { getEmptyTestDiv(), 'attr', 'foo', 'ble"rgh' },
@@ -296,10 +305,10 @@
          expect = { '<div><br /></div>' }
        },
        { name = 'mw.html.node (append to self closing)', func = 
testNodeAppendToSelfClosing, type='ToString',
-         expect = "Self-closing tags can't have child nodes"
+         expect = "self-closing tags can't have child nodes"
        },
        { name = 'mw.html.wikitext (append to self closing)', func = 
testWikitextAppendToSelfClosing, type='ToString',
-         expect = "Self-closing tags can't have child nodes"
+         expect = "self-closing tags can't have child nodes"
        },
        { name = 'mw.html.tag.node (using allDone)', func = testTagNodeAllDone, 
type='ToString',
          expect = { '<div><p><div></div></p></div>' }
diff --git a/tests/engines/LuaCommon/LibraryUtilTest.php 
b/tests/engines/LuaCommon/LibraryUtilTest.php
new file mode 100644
index 0000000..c434944
--- /dev/null
+++ b/tests/engines/LuaCommon/LibraryUtilTest.php
@@ -0,0 +1,11 @@
+<?php
+
+class Scribunto_LuaLibraryUtilTests extends Scribunto_LuaEngineTestBase {
+       protected static $moduleName = 'LibraryUtilTests';
+
+       function getTestModules() {
+               return parent::getTestModules() + array(
+                       'LibraryUtilTests' => __DIR__ . '/LibraryUtilTests.lua',
+               );
+       }
+}
diff --git a/tests/engines/LuaCommon/LibraryUtilTests.lua 
b/tests/engines/LuaCommon/LibraryUtilTests.lua
new file mode 100644
index 0000000..8855742
--- /dev/null
+++ b/tests/engines/LuaCommon/LibraryUtilTests.lua
@@ -0,0 +1,220 @@
+--[[
+       Tests for the libraryUtil module
+
+       @license GNU GPL v2+
+       @author Mr. Stradivarius < misterst...@gmail.com >
+]]
+
+local testframework = require 'Module:TestFramework'
+
+local util = require( 'libraryUtil' )
+local checkType = util.checkType
+local checkTypeMulti = util.checkTypeMulti
+local checkTypeForIndex = util.checkTypeForIndex
+local checkTypeForNamedArg = util.checkTypeForNamedArg
+local makeCheckSelfFunction = util.makeCheckSelfFunction
+
+local function testExpectTypes( arg, expectTypes )
+       pcall( checkTypeMulti, 'myFunc', 1, arg, expectTypes )
+       return unpack( expectTypes )
+end
+
+local function testCheckSelf( self, method, ... )
+       local checkSelf = makeCheckSelfFunction( ... )
+       return checkSelf( self, method )
+end
+
+local testObject = {}
+
+-- Tests
+local tests = {
+       -- checkType
+       { name = 'checkType, valid', func = checkType, type='ToString',
+         args = { 'myFunc', 1, 'foo', 'string' },
+         expect = { nil }
+       },
+       { name = 'checkType, invalid', func = checkType, type='ToString',
+         args = { 'myFunc', 1, 9, 'string' },
+         expect = "bad argument #1 to 'myFunc' (string expected, got number)"
+       },
+       { name = 'checkType, nil valid', func = checkType, type='ToString',
+         args = { 'myFunc', 1, nil, 'string', true },
+         expect = { nil }
+       },
+       { name = 'checkType, nil invalid', func = checkType, type='ToString',
+         args = { 'myFunc', 1, nil, 'string', false },
+         expect = "bad argument #1 to 'myFunc' (string expected, got nil)"
+       },
+       { name = 'checkType, boolean', func = checkType, type='ToString',
+         args = { 'myFunc', 1, true, 'boolean' },
+         expect = { nil }
+       },
+       { name = 'checkType, table', func = checkType, type='ToString',
+         args = { 'myFunc', 1, {}, 'table' },
+         expect = { nil }
+       },
+       { name = 'checkType, function', func = checkType, type='ToString',
+         args = { 'myFunc', 1, function () return end, 'function' },
+         expect = { nil }
+       },
+       { name = 'checkType, argument #2', func = checkType, type='ToString',
+         args = { 'myFunc', 2, 9, 'string' },
+         expect = "bad argument #2 to 'myFunc' (string expected, got number)"
+       },
+       { name = 'checkType, name', func = checkType, type='ToString',
+         args = { 'otherFunc', 1, 9, 'string' },
+         expect = "bad argument #1 to 'otherFunc' (string expected, got 
number)"
+       },
+
+       -- checkTypeMulti
+       { name = 'checkTypeMulti, single valid', func = checkTypeMulti, 
type='ToString',
+         args = { 'myFunc', 1, 'foo', { 'string' } },
+         expect = { nil }
+       },
+       { name = 'checkTypeMulti, single type invalid (1)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, 9, { 'string' } },
+         expect = "bad argument #1 to 'myFunc' (string expected, got number)"
+       },
+       { name = 'checkTypeMulti, single type invalid (2)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, nil, { 'string' } },
+         expect = "bad argument #1 to 'myFunc' (string expected, got nil)"
+       },
+       { name = 'checkTypeMulti, multiple types valid (1)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, 'foo', { 'string', 'number', 'table' } },
+         expect = { nil }
+       },
+       { name = 'checkTypeMulti, multiple types valid (2)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, 9, { 'string', 'number', 'table' } },
+         expect = { nil }
+       },
+       { name = 'checkTypeMulti, multiple types valid (3)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, {}, { 'string', 'number', 'table' } },
+         expect = { nil }
+       },
+       { name = 'checkTypeMulti, multiple types invalid (1)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, true, { 'string', 'number', 'table' } },
+         expect = "bad argument #1 to 'myFunc' (string, number or table 
expected, got boolean)"
+       },
+       { name = 'checkTypeMulti, multiple types invalid (2)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, nil, { 'string', 'number', 'table' } },
+         expect = "bad argument #1 to 'myFunc' (string, number or table 
expected, got nil)"
+       },
+       { name = 'checkTypeMulti, multiple types invalid (3)', func = 
checkTypeMulti, type='ToString',
+         args = { 'myFunc', 1, function () return end, { 'string', 'number', 
'table' } },
+         expect = "bad argument #1 to 'myFunc' (string, number or table 
expected, got function)"
+       },
+       { name = 'checkTypeMulti, two types invalid', func = checkTypeMulti, 
type='ToString',
+         args = { 'myFunc', 1, {}, { 'string', 'number' } },
+         expect = "bad argument #1 to 'myFunc' (string or number expected, got 
table)"
+       },
+       { name = 'checkTypeMulti, type order', func = checkTypeMulti, 
type='ToString',
+         args = { 'myFunc', 1, true, { 'table', 'number', 'string' } },
+         expect = "bad argument #1 to 'myFunc' (table, number or string 
expected, got boolean)"
+       },
+       { name = 'checkTypeMulti, argument #2', func = checkTypeMulti, 
type='ToString',
+         args = { 'myFunc', 2, 9, { 'string' } },
+         expect = "bad argument #2 to 'myFunc' (string expected, got number)"
+       },
+       { name = 'checkTypeMulti, other name', func = checkTypeMulti, 
type='ToString',
+         args = { 'otherFunc', 1, 9, { 'string' } },
+         expect = "bad argument #1 to 'otherFunc' (string expected, got 
number)"
+       },
+       { name = 'checkTypeMulti, expectTypes not altered (1)', func = 
testExpectTypes, type='ToString',
+         args = { 'foo', { 'string', 'number', 'table' } },
+         expect = { 'string', 'number', 'table' }
+       },
+       { name = 'checkTypeMulti, expectTypes not altered (2)', func = 
testExpectTypes, type='ToString',
+         args = { true, { 'string', 'number', 'table' } },
+         expect = { 'string', 'number', 'table' }
+       },
+       { name = 'checkTypeMulti, expectTypes not altered (3)', func = 
testExpectTypes, type='ToString',
+         args = { 'foo', { 'string' } },
+         expect = { 'string' }
+       },
+       { name = 'checkTypeMulti, expectTypes not altered (4)', func = 
testExpectTypes, type='ToString',
+         args = { true, { 'string' } },
+         expect = { 'string' }
+       },
+
+       -- checkTypeForIndex
+       { name = 'checkTypeForIndex, valid', func = checkTypeForIndex, 
type='ToString',
+         args = { 'foo', 'bar', 'string' },
+         expect = { nil }
+       },
+       { name = 'checkTypeForIndex, invalid (1)', func = checkTypeForIndex, 
type='ToString',
+         args = { 'foo', 9, 'string' },
+         expect = "value for index 'foo' must be string, number given"
+       },
+       { name = 'checkTypeForIndex, invalid (2)', func = checkTypeForIndex, 
type='ToString',
+         args = { 'foo', 9, 'string' },
+         expect = "value for index 'foo' must be string, number given"
+       },
+       { name = 'checkTypeForIndex, other index', func = checkTypeForIndex, 
type='ToString',
+         args = { 'bar', 9, 'string' },
+         expect = "value for index 'bar' must be string, number given"
+       },
+
+       -- checkTypeForNamedArg
+       { name = 'checkTypeForNamedArg, valid', func = checkTypeForNamedArg, 
type='ToString',
+         args = { 'myFunc', 'myArg', 'foo', 'string' },
+         expect = { nil }
+       },
+       { name = 'checkTypeForNamedArg, invalid', func = checkTypeForNamedArg, 
type='ToString',
+         args = { 'myFunc', 'myArg', 9, 'string' },
+         expect = "bad named argument myArg to 'myFunc' (string expected, got 
number)"
+       },
+       { name = 'checkTypeForNamedArg, nil valid', func = 
checkTypeForNamedArg, type='ToString',
+         args = { 'myFunc', 'myArg', nil, 'string', true },
+         expect = { nil }
+       },
+       { name = 'checkTypeForNamedArg, nil invalid', func = 
checkTypeForNamedArg, type='ToString',
+         args = { 'myFunc', 'myArg', nil, 'string', false },
+         expect = "bad named argument myArg to 'myFunc' (string expected, got 
nil)"
+       },
+       { name = 'checkTypeForNamedArg, other function', func = 
checkTypeForNamedArg, type='ToString',
+         args = { 'otherFunc', 'myArg', 9, 'string' },
+         expect = "bad named argument myArg to 'otherFunc' (string expected, 
got number)"
+       },
+       { name = 'checkTypeForNamedArg, other argument', func = 
checkTypeForNamedArg, type='ToString',
+         args = { 'myFunc', 'otherArg', 9, 'string' },
+         expect = "bad named argument otherArg to 'myFunc' (string expected, 
got number)"
+       },
+
+       -- makeCheckSelfFunction
+       { name = 'makeCheckSelfFunction, valid', func = testCheckSelf, 
type='ToString',
+         args = { testObject, 'myMethod', 'myLibrary', 'myObject', testObject, 
'test object' },
+         expect = { nil }
+       },
+       { name = 'makeCheckSelfFunction, invalid (1)', func = testCheckSelf, 
type='ToString',
+         args = { {}, 'myMethod', 'myLibrary', 'myObject', testObject, 'test 
object' },
+         expect = 'myLibrary: invalid test object. Did you call myMethod with 
a dot instead ' ..
+               'of a colon, i.e. myObject.myMethod() instead of 
myObject:myMethod()?'
+       },
+       { name = 'makeCheckSelfFunction, invalid (2)', func = testCheckSelf, 
type='ToString',
+         args = { 'foo', 'myMethod', 'myLibrary', 'myObject', testObject, 
'test object' },
+         expect = 'myLibrary: invalid test object. Did you call myMethod with 
a dot instead ' ..
+               'of a colon, i.e. myObject.myMethod() instead of 
myObject:myMethod()?'
+       },
+       { name = 'makeCheckSelfFunction, other method', func = testCheckSelf, 
type='ToString',
+         args = { {}, 'otherMethod', 'myLibrary', 'myObject', testObject, 
'test object' },
+         expect = 'myLibrary: invalid test object. Did you call otherMethod 
with a dot instead ' ..
+               'of a colon, i.e. myObject.otherMethod() instead of 
myObject:otherMethod()?'
+       },
+       { name = 'makeCheckSelfFunction, other library', func = testCheckSelf, 
type='ToString',
+         args = { {}, 'myMethod', 'otherLibrary', 'myObject', testObject, 
'test object' },
+         expect = 'otherLibrary: invalid test object. Did you call myMethod 
with a dot instead ' ..
+               'of a colon, i.e. myObject.myMethod() instead of 
myObject:myMethod()?'
+       },
+       { name = 'makeCheckSelfFunction, other object', func = testCheckSelf, 
type='ToString',
+         args = { {}, 'myMethod', 'otherLibrary', 'otherObject', testObject, 
'test object' },
+         expect = 'otherLibrary: invalid test object. Did you call myMethod 
with a dot instead ' ..
+               'of a colon, i.e. otherObject.myMethod() instead of 
otherObject:myMethod()?'
+       },
+       { name = 'makeCheckSelfFunction, other description', func = 
testCheckSelf, type='ToString',
+         args = { {}, 'myMethod', 'myLibrary', 'myObject', testObject, 'test 
object' },
+         expect = 'myLibrary: invalid test object. Did you call myMethod with 
a dot instead ' ..
+               'of a colon, i.e. myObject.myMethod() instead of 
myObject:myMethod()?'
+       },
+}
+
+return testframework.getTestProvider( tests )

-- 
To view, visit https://gerrit.wikimedia.org/r/145547
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: If9cf9a52bd4b1bb42cc7f9f1f1096828710cbc52
Gerrit-PatchSet: 8
Gerrit-Project: mediawiki/extensions/Scribunto
Gerrit-Branch: master
Gerrit-Owner: Mr. Stradivarius <misterst...@gmail.com>
Gerrit-Reviewer: Anomie <bjor...@wikimedia.org>
Gerrit-Reviewer: Hoo man <h...@online.de>
Gerrit-Reviewer: Jackmcbarn <jackmcb...@gmail.com>
Gerrit-Reviewer: Mr. Stradivarius <misterst...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to