Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docker/images/Dockerfile.perl-testsuite
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
ARG BZDB=""
FROM bugzilla/bugzilla-perl-slim${BZDB}:20250925.1

ENV BZ_REQUIRE_NODE=1

WORKDIR /app

# Install system dependencies
Expand All @@ -19,6 +21,7 @@ RUN apt-get update && apt-get -y dist-upgrade && \
cpanminus \
mariadb-client \
netcat-traditional \
nodejs \
build-essential \
libapache2-mod-perl2 \
libapache2-mod-perl2-dev \
Expand Down
63 changes: 17 additions & 46 deletions js/productform.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,53 +329,24 @@ function fake_diff_array(a, b) {
* @return Merged and sorted array.
*/
function merge_arrays(a, b, b_is_select) {
var pos_a = 0;
var pos_b = 0;
var items = a.slice();
var ret = new Array();
var bitem, aitem;

// Iterate through both arrays and add the larger item to the return
// list. Remove dupes, too. Use toLowerCase to provide
// case-insensitivity.
while ((pos_a < a.length) && (pos_b < b.length)) {
aitem = a[pos_a];
if (b_is_select)
bitem = b[pos_b].value;
else
bitem = b[pos_b];

// Smaller item in list a.
if (aitem.toLowerCase() < bitem.toLowerCase()) {
ret[ret.length] = aitem;
pos_a++;
}
else {
// Smaller item in list b.
if (aitem.toLowerCase() > bitem.toLowerCase()) {
ret[ret.length] = bitem;
pos_b++;
}
else {
// List contents are equal, include both counters.
ret[ret.length] = aitem;
pos_a++;
pos_b++;
}
}
}

// Catch leftovers here. These sections are ugly code-copying.
if (pos_a < a.length)
for (; pos_a < a.length ; pos_a++)
ret[ret.length] = a[pos_a];

if (pos_b < b.length) {
for (; pos_b < b.length; pos_b++) {
if (b_is_select)
bitem = b[pos_b].value;
else
bitem = b[pos_b];
ret[ret.length] = bitem;
var i;

for (i = 0; i < b.length; i++)
items[items.length] = b_is_select ? b[i].value : b[i];

items.sort(function(left, right) {
left = left.toLowerCase();
right = right.toLowerCase();
return left < right ? -1 : left > right ? 1 : 0;
});

for (i = 0; i < items.length; i++) {
if (!ret.length
|| items[i].toLowerCase() != ret[ret.length - 1].toLowerCase())
{
ret[ret.length] = items[i];
}
}

Expand Down
96 changes: 96 additions & 0 deletions t/015productform.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.


##################
#Bugzilla Test 15#
####Productform###

use 5.14.0;
use strict;
use warnings;

use File::Spec;
use Test::More;

my $node;
foreach my $dir (File::Spec->path()) {
foreach my $name (qw(node nodejs node.exe)) {
my $path = File::Spec->catfile($dir, $name);
if (-x $path && !-d $path) {
$node = $path;
last;
}
}
last if $node;
}

if (!$node && $ENV{BZ_REQUIRE_NODE}) {
plan tests => 1;
fail('Node.js is required to test js/productform.js');
exit;
}

plan skip_all => 'Node.js is required to test js/productform.js' if !$node;

my $script = <<'JS';
var fs = require('fs');
var vm = require('vm');

vm.runInThisContext(
fs.readFileSync('js/productform.js', 'utf8'),
{ filename: 'js/productform.js' }
);

console.log(
merge_arrays(
['Trunk', '2.0'],
['unspecified', 'Trunk'],
false
).join('\t')
);
console.log(
merge_arrays(
['Beta', 'alpha'],
[{ value: 'ALPHA' }, { value: 'Release' }],
true
).join('\t')
);
JS

my $pid = open(my $fh, '-|', $node, '-e', $script);
if (!defined $pid) {
plan tests => 1;
fail("could not run $node: $!");
exit;
}

my @results = <$fh>;
close($fh);
my $status = $?;

if ($status || @results != 2) {
plan tests => 1;
fail('js/productform.js did not produce the expected test output');
diag("Node.js exit status: $status");
diag("Node.js output:\n" . join('', @results));
exit;
}

chomp(@results);
plan tests => 2;

is_deeply(
[split(/\t/, $results[0])],
['2.0', 'Trunk', 'unspecified'],
'unsorted product values are sorted and de-duplicated'
);
is_deeply(
[split(/\t/, $results[1])],
['alpha', 'Beta', 'Release'],
'select options are merged, sorted, and de-duplicated'
);
Loading