A module for building complex HTML from Lua using a
fluent interface. The module is originally from enwiki,
but the authors allowed us to reuse it under GPLv2+
(as stated in the file).
The module will be loaded per default and comes with
unit tests.
As discussed on wikitech-l:
http://lists.wikimedia.org/pipermail/wikitech-l/2013-December/073320.html
Change-Id: I7c8d4378091c13d5ace0dd1fcbb4e27163e8c896
This field already exists in PHP with exactly the content requested in
bug 47089, so we may as well expose it on the frame object.
Bug: 47089
Change-Id: I672820589f6ebc7c4daad29b5eb156733a5bc5cc
It's already possible to detect whether the current template is being
substituted via ParserFunctions (see [[en:Template:Ifsubst]]), and a
similar trick works with frame:preprocess. So we may as well provide the
flag directly.
Bug: 47828
Change-Id: Id06d27c6283ee589a8830b78c04e56978e0ac6da
Specifically:
* String conversion in non-URL contexts (e.g. .prefixedText) uses spaces
instead of underscores.
* Setting .fragment now applies the same transformations that are done
(in PHP) by mw.title.new.
Bug: 56217
Change-Id: I12e354636bcde3327864088175fb4de61aecc81a
The PHP call that makes mw.site.namespaces work case-insensitively
doesn't handle non-standard spaces/underscores. So standardize them
before the call.
Bug: 56216
Change-Id: I4758478b126858fb581614f64eb15472f42fef51
A few edge cases were being incorrectly handled:
* mw.ustring.sub( 'abc', 1, 0 ) returned 'a', not ''.
* mw.ustring.codepoint( 'abc', 1, 0 ) returned 97, not no results.
* mw.ustring.codepoint( 'abc', 4, 4 ) returned 99, not no results.
* mw.ustring.gcodepoint had the same issues as mw.ustring.codepoint.
Change-Id: Ib8c0ef5a8073106eb7d90d0aa0513be4525dca08
Negative values for 'i' in mw.ustring.byteoffset are supposed to count
from the end of the string. But in LuaSandbox, it was actually counting
from two bytes before the end of the string due to a typo.
Fix that, and add some tests for it.
Bug: 50176
Change-Id: Iceee1022a55abd7a08df1ea7843e1277eb02798b
The "%f[set]" frontier pattern has been in Lua 5.1 since the beginning,
but was undocumented until Lua 5.2. And the code is even unchanged from
5.1.0 to 5.2.1. So there's no reason not to implement it in ustring too.
Note the changes to UstringLibrary.php are somewhat large, because it
splits the "convert a Lua bracketed charset to PCRE" code into a
separate function and it changes the handling of mw.ustring.find's and
mw.ustring.match's 'init' parameter from "substring, match from 0, then
add back on $init" to "use preg_match's $offset and use \G instead of ^
where this matters". Both of these are necessary to properly support
%f.
This also fixes a bug in the pure-Lua code (not used in Scribunto)
exposed by the unit tests for %f where %z was matching '\1' rather than
'\0' and %Z everything except '\1' instead of everything except '\0'.
Bug: 48331
Change-Id: Ie0b95ef5b734db53d6adc9de5dae4874f8944c08
The following errors are fixed:
* PHP warning and wrong return value with empty pattern and plain
* Incorrect offsets returned when init is larger than the string length
* Incorrect captured offsets returned when init is excessively negative
Bug: 47365
Change-Id: I9741418287dc727747326d6a19678370ce155a2b
Users are reporting disappointment that using pairs on title objects
doesn't let them see the fields available. It's easy enough to add a
__pairs metamethod to allow pairs to work on title objects, so let's do
that.
The same can be done for mw.uri objects.
For mw.message objects, we can easily enough change the implementation
to be like mw.language objects, which doesn't have this problem.
For mw.site.stats, we may as well just remove the load-on-demand feature
since it will be demanded as soon as the environment is cloned for the
first module.
Change-Id: Ie5a3b5684b2bb6c090f9994baa03977687688929
mw.title.new( pageid ) should not throw an error for an nonexisting
pageid, just return nil. Similarly, it should always return nil for 0,
rather than returning the last non-existent title created.
Change-Id: I3cdbb24fc785aef0f8e75fba1feccd26ac5b7370
This exists for some common text-processing functions that aren't
included in string (and therefore also aren't in mw.ustring), as well as
a logical place for the "unstrip" function requested in bug 45085.
Bug: 45085
Change-Id: I47356215fcc8ddeed5f901cd933a30021394bd78
It would be helpful for debugging if a frame object could be gotten in
the console. To that end, add an empty frame when running in the console
and allow it to be returned by mw.getCurrentFrame().
It would also be helpful to be able to create frames with arbitrary
arguments, again for testing. Fortunately support for creating child
frames with arbitrary arguments already exists in core, so we can just
use it.
And for good measure, be sure to restore the $engine->currentFrames
array even if the Lua code throws an exception.
Change-Id: I1dc8602d63af75424f267c42a3743fabbc1827f7
Currently, the time taken to parse the arguments passed to a Lua
function from #invoke will be counted against Lua's 10-second limit.
This is counterintuitive, and can remove incentive for users to convert
templates to Lua since they may have to convert a whole stack at once.
Note this requires change I11881232 to mediawiki/php/luasandbox to
actually have any effect.
Bug: 45684
Change-Id: I773950e4c399b8a1cfa6d1cde781a069d286b3bd
Since the content of a page is being loaded, this should be recorded in
templatelinks so things can be updated properly when that page is
edited.
Change-Id: I3e720fee2705f6c08ac0456c3cab0ed4ede84536
In the unit tests, the engine is given a parser, but the parser is not
being associated back with the engine. So in some cases, that could lead
to *another*, default engine being created for certain operations.
Fix that.
Change-Id: I79995c2635d9e470931b84dc1854dae26772bbe3
Apparently assigning to $wgHooks at the top of the file breaks every
other hook, somehow. So we need to set it in setUp(), but prevent the
interwiki prefix from being queried beforehand when the dataProvider is
run. Fun.
Change-Id: I8535942e3a0e47d9a5b2ea11c1b0b63c5acf2cc5
* mw.ustring.sub( '', 1 ) errors in LuaStandalone
* Default value for ustring.maxStringLength and ustring.maxPatternLength
should be infinity, not nil
* mw.ustring.find() returns one value instead of two in "plain" mode.
Change-Id: I5e65c4ec3a05f0e6930ce7ab7fd4ac72bea95e7f
Clean up the modules in engines/LuaCommon/lualib:
* Fix luabit/bit.lua to return its table instead of trying to set the
global directly.
* Fix luabit/hex.lua to return its table instead of trying to set the
global directly.
* luabit/noki.lua is useless for our purposes
* luabit/utf8.lua is redundant to mw.ustring
* stringtools uses coroutines, which we don't support
Also fix a parser test that has apparently been broken for a long time.
Change-Id: I1284cddb6e9b94327964cb1077d8dbdf7def6d06
Note that fetching any title besides the one for the current page is
considered "expensive". It also records the title fetched in the
ParserOutput so it will be listed in pagelinks, just like #ifexists.
This also moves the ToString test formatter into TestFramework.lua, so
TitleLibraryTests.lua can use it too.
Change-Id: I799f3289a37fe1349b6bca5758829acf82cb718f
In phpunit 3.6.10, assertEquals considered two NaNs to be equivalent.
Somewhere between that and phpunit 3.7.14, this behavior changed so NaNs
are no longer considered equivalent.
Change-Id: I2c664498eb34cf5119a2eaaa96a6be57b821ab94
People sometimes want to load large tables of constant data from a
module. Using require(), this has to be reparsed every time, which can
be slow.
mw.loadData() will load the just data once, and return a table with a
metatable cleverly designed to give read-only access to the loaded data.
Change-Id: Icec192bdbe6cfca7902fd5cb5d0e217bd8399637
Allowing a module to call mw.makeProtectedEnvFuncs() lets it bypass the
allowEnvFuncs setting. It can also be used to manipulate the global
tables that other modules' sandboxes will be copied from.
And for paranoia's sake, let's tighten up what setfenv is allowed to
set. This requires changing a unit test, because it is no longer
sane to do something like
env.setfenv, env.getfenv = mw.makeProtectedEnvFuncs( { [env] = true }, {} )
Nothing real does this, it was only in the unit test.
Change-Id: I8e0d83bb0980ee869af3ac4413afd211717ca92f
The Lua manual says this:
For this function, a '^' at the start of a pattern does not work as an
anchor, as this would prevent the iteration.
I had interpreted that to mean that a pattern starting with '^' would
never match in gmatch. But further testing reveals that the '^' is just
treated as a literal character: string.gmatch( "foo ^bar baz", "^%a+" )
will match "^bar".
Change-Id: Id91d6ee2db753ce1d6a4f6ae27764691d9e9fdc4
It's easy to forget a 'local' somewhere and accidentally leak a global
variable. Add a unit test to catch that.
Change-Id: I3a8dda22f108d88039f9562a1da7a739850bb14b
This is a reimplementation of Lua's string library with support for
UTF-8.
The entire ustring library is implemented in pure Lua. PHP callbacks are
also available for overrides: in LuaSandbox these are used for almost
all functions, while in LuaStandalone they are used only for the pattern
matching. Also, ustring.upper and ustring.lower are overridden using
mw.language's .uc and .lc if available.
It also includes a bunch of unit tests.
Note that if you download the normalization tests, they may fail under
LuaSandbox if you have PHP's intl extension installed and libicu on your
system is too old.
Change-Id: Ie76fdf8d3a85d0a3d2a41b0d3b7afe433f247af0
Rework the LuaEngine tests to be entirely modular, so that every library
need not add itself to one monolithic file. This also allows other
extensions that add Lua modules to make unit tests without having to
somehow inject them into a test class owned by Scribunto.
The approach taken is similar to that used for Selenium for running
tests against multiple browsers.
Change-Id: I294b2a8195759c0e4fa211f879305a8eb66d9c9a
To allow Lua libraries to mark functions as expensive, add an
incrementExpensiveFunctionCount() method to Scribunto_LuaEngine that
will call the corresponding Parser method and throw an error if the
limit is exceeded.
Also allow libraries to do the same thing from Lua by calling
mw.incrementExpensiveFunctionCount().
Change-Id: I56fded32b1077eff3980371e9abc9b3b7581f7b5
The listing of the standard modules in package.loaded seems to have been
removed to avoid leaking information to loaded modules. However, since
the *entire* environment is cloned, *including* package.loaded itself,
this does not seem to actually be a problem. But for good measure, also
add a unit test to verify that the version of the standard module tables
referenced from package.loaded is the same as that in _G.
This change also cleans up some unused local variables and an unused
local function from the package module.
Change-Id: I7ec8227b3273059e8f65ad735c215bfd0c623e64
In Lua, a table entry with a nil value is the same as a table entry that
doesn't exist. So when serializing for transfer to PHP, these keys will
be skipped. For a table as an associative array this isn't much of a
problem, but for a table as a list it means we have missing indexes.
Some of Lua's functions for handling "lists" (i.e. tables with numeric
keys) also have a problem when the list contains nils.
To work around these issues when passing argument lists and return value
lists, pass the number of elements along with the sparse list. On the
PHP end we can use this to fill in the missing nulls, and on the Lua
end we can pass this count to unpack() to avoid the problems on the Lua
side.
Change-Id: I858e3905a06e377693301da2b8bc534808f00e3e
Trivial fix, the parameter order to assertEquals() was backwards so if
the test failed it would indicate the "Actual" results as "Expected" and
vice versa.
Change-Id: Ibfe12591a58b10e0321aafea576c36cfa674f51d