!! Version 2 # Force the test runner to ensure the extension is loaded !! functionhooks invoke !! endfunctionhooks !! article Module:Test !! text local p = {} local isoTestData = '' local bit = require('bit') function p.tooFewArgs() require() end function p.getAllArgs( frame ) local buf = {} local names = {} local values = {} for name, value in pairs( frame.args ) do table.insert(names, name) values[name] = value end table.sort(names, function (a, b) return tostring(a) < tostring(b) end) for index, name in ipairs(names) do if #buf ~= 0 then table.insert( buf, ', ' ) end table.insert( buf, name .. '=' .. values[name] ) end return table.concat( buf ) end function p.getAllArgs2( frame ) local buf = {} local names = {} local values = {} for name, value in frame:argumentPairs() do table.insert(names, name) values[name] = value end table.sort(names, function (a, b) return tostring(a) < tostring(b) end) for index, name in ipairs(names) do if #buf ~= 0 then table.insert( buf, ', ' ) end table.insert( buf, name .. '=' .. values[name] ) end return table.concat( buf ) end function p.getNumericArgs( frame ) local buf = {} for index, value in ipairs(frame.args) do if #buf ~= 0 then table.insert( buf, ', ' ) end table.insert( buf, index .. '=' .. value ) end return table.concat( buf ) end function p.getArg( frame ) local name = frame.args[1] return frame:getArgument( name ):expand() end function p.getArgLength( frame ) local name = frame.args[1] return #(frame.args[name]) end function p.getArgType( frame ) local name = frame.args[1] return type( frame.args[name] ) end function p.hello() return 'hello' end function p.emptyTable() return {} end function p.import() return require('Module:Test2').countBeans() end function p.bitop() return bit.bor(1, bit.bor(2, bit.bor(4, 8))) end function p.isolationTestUpvalue( frame ) isoTestData = isoTestData .. frame.args[1] return isoTestData end function p.isolationTestGlobal( frame ) if isoTestDataGlobal == nil then isoTestDataGlobal = '' end isoTestDataGlobal = isoTestDataGlobal .. frame.args[1] return isoTestDataGlobal end function p.getParentArgs( frame ) return p.getAllArgs( frame:getParent() ) end function p.testExpandTemplate( frame ) return frame:expandTemplate{ title = 'Scribunto_all_args', args = { x = 1, y = 2, z = '|||' } } end function p.testExpandTemplateWithHeaders( frame ) return frame:expandTemplate{ title = 'Scribunto_template_with_headers' } end function p.testNewTemplateParserValue( frame ) return frame:newTemplateParserValue{ title = 'Scribunto_all_args', args = { x = 1, y = 2, z = 'blah' } } : expand() end function p.testPreprocess( frame ) return frame:preprocess( '{{Scribunto_all_args|{{{1}}}}}|x=y' ) end function p.testNewParserValue( frame ) return frame:newParserValue( '{{Scribunto_all_args|{{{1}}}}}|x=y' ):expand() end function p.null( frame ) return '\0' end function p.isSubsting( frame ) return tostring( mw.isSubsting() ) end function p.getFrameTitle( frame ) return frame:getTitle() end p['test=InFunctionName'] = function( frame ) return frame.args[1] end function p.testStrippedCss( frame ) return mw.html.create( 'div' ):css( 'color', frame.args[1] ) end function p.testFrameCaching( frame ) return string.format( 'Parent frame is the root: %s. Child frame is the root: %s.', frame:getParent():preprocess('noyes'), frame:preprocess('noyes') ) end return p !! endarticle !! article Module:Test2 !! text return { countBeans = function () return 3 end } !! endarticle !! article Module:Metatables !! text local p, mt1, mt2 = {}, {}, {} mt1.__index = {} function p.zero(frame) return 'You called the zero method from p' end function mt1.__index.one(frame) return 'You called the one method from mt1' end function mt2.__index(t, k) return function(frame) return 'You called the ' .. k .. ' method from mt2' end end setmetatable(mt1.__index, mt2) setmetatable(p, mt1) return p !! endarticle !! article Template:Scribunto_all_args !! text {{#invoke:test|getParentArgs}} !! endarticle !! article Template:Scribunto_template_with_headers !! text == bar == !! endarticle !! article Template:Scribunto_frame_caching !! text {{#invoke:test|testFrameCaching}} !! endarticle !! test Scribunto: no such module !! wikitext {{#invoke:foo|bar}} !! html

Script error: No such module "foo".

!! end !! test Scribunto: no such function !! wikitext {{#invoke:test|blah}} !! html

Script error: The function "blah" does not exist.

!! end !! test Scribunto: hello world !! wikitext {{#invoke:test|hello}} !! html

hello

!! end !! test Scribunto: getAllArgs !! wikitext {{#invoke:test|getAllArgs|x|y|z|a=1|b=2|c=3|7=?}} !! html

1=x, 2=y, 3=z, 7=?, a=1, b=2, c=3

!! end !! test Scribunto: getAllArgs, deprecated style !! wikitext {{#invoke:test|getAllArgs2|x|y|z|a=1|b=2|c=3|7=?}} !! html

1=x, 2=y, 3=z, 7=?, a=1, b=2, c=3

!! end !! test Scribunto: getNumericArgs !! wikitext {{#invoke:test|getNumericArgs|x|y|z|a=1|b=2|c=3|7=?}} !! html

1=x, 2=y, 3=z

!! end !! test Scribunto: named numeric parameters !! wikitext {{#invoke:test|getArg|2|a|2=b}} {{#invoke:test|getArg|2|2=a|b}} !! html

b b

!! end !! test Scribunto: template-style argument trimming !! wikitext {{#invoke:test|getArgLength|2| x }} {{#invoke:test|getArgLength|2|2= x }} !! html

3 1

!! end !! test Scribunto: missing argument !! wikitext {{#invoke:test|getArgType|2}} {{#invoke:test|getArgType|blah}} !! html

nil nil

!! end !! test Scribunto: parent frame access !! wikitext {{Scribunto_all_args|x|y|z|a = 1|b = 2|c = 3}} !! html

1=x, 2=y, 3=z, a=1, b=2, c=3

!! end !! test Scribunto: expandTemplate !! wikitext {{#invoke:test|testExpandTemplate}} !! html

x=1, y=2, z=|||

!! end !! test Scribunto: expandTemplate with headers !! wikitext ==foo== {{#invoke:test|testExpandTemplateWithHeaders}} !! html

foo[edit]

bar[edit]

!! end !! test Scribunto: newTemplateParserValue !! wikitext {{#invoke:test|testNewTemplateParserValue}} !! html

x=1, y=2, z=blah

!! end !! test Scribunto: preprocess !! wikitext {{#invoke:test|testPreprocess|foo}} !! html

1=foo|x=y

!! end !! test Scribunto: newParserValue !! wikitext {{#invoke:test|testNewParserValue|foo}} !! html

1=foo|x=y

!! end !! test Scribunto: table return !! wikitext {{#invoke:test|emptyTable}} !! html

table

!! end !! test Scribunto: require !! wikitext {{#invoke:test|import}} !! html

3

!! end !! test Scribunto: access to a module imported at the chunk level !! wikitext {{#invoke:test|bitop}} !! html

15

!! end !! test Scribunto: invoke instance upvalue isolation !! wikitext {{#invoke:test|isolationTestUpvalue|1}} {{#invoke:test|isolationTestUpvalue|2}} {{#invoke:test|isolationTestUpvalue|3}} !! html

1 2 3

!! end !! test Scribunto: invoke instance global isolation !! wikitext {{#invoke:test|isolationTestGlobal|1}} {{#invoke:test|isolationTestGlobal|2}} {{#invoke:test|isolationTestGlobal|3}} !! html

1 2 3

!! end !! test Scribunto: ASCII null !! wikitext {{#invoke:test|null}} !! html

!! end !! test Scribunto: isSubsting during PST !! options pst !! wikitext {{safesubst:#invoke:test|isSubsting}} !! html true !! end !! test Scribunto: isSubsting during normal parse !! wikitext {{safesubst:#invoke:test|isSubsting}} !! html

false

!! end !! test Scribunto: frame:getTitle !! wikitext {{#invoke:test|getFrameTitle}} !! html

Module:Test

!! end !! test Scribunto: Metatable on export table !! wikitext {{#invoke:Metatables|zero}} {{#invoke:Metatables|one}} {{#invoke:Metatables|two}} !! html

You called the zero method from p You called the one method from mt1 You called the two method from mt2

!! end !! test Scribunto: Correct argument numbering with equals sign in function name !! wikitext {{#invoke:test|test=InFunctionName|good|bad}} !! html

good

!! end !! test Scribunto: Strip markers in CSS !! wikitext {{#invoke:test|testStrippedCss|#ff0000}} !! html
!! end !! test Scribunto: Parser output isn't incorrectly cached across frames !! wikitext Root: {{#invoke:test|testFrameCaching}} Template: {{Scribunto frame caching}} !! html

Root: Parent frame is the root: yes. Child frame is the root: no. Template: Parent frame is the root: no. Child frame is the root: no.

!! end