Skip to content
This repository was archived by the owner on Jun 11, 2024. It is now read-only.

Add GitHub Actions testing, JSHint -> ESLint, rewrite tests in ESM #16

Merged
merged 3 commits into from
Apr 7, 2024
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
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org

root = true

[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_style = space
indent_size = 2
39 changes: 39 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Node

on:
pull_request:
push:
branches-ignore: ["dependabot/**"]

permissions:
contents: read # to fetch code (actions/checkout)

env:
NODE_VERSION: 20.x

jobs:
build-and-test:
runs-on: ubuntu-latest
name: test
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: ${{ env.NODE_VERSION }}

- name: Cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-npm-lock-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-${{ env.NODE_VERSION }}-npm-lock-

- name: Install dependencies
run: npm install

- name: Run tests
run: npm test
16 changes: 0 additions & 16 deletions .jshintrc

This file was deleted.

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10
20
46 changes: 46 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import jqueryConfig from "eslint-config-jquery";
import globals from "globals";

export default [
{
ignores: [
"test/fixtures/**"
]
},

{
languageOptions: {
globals: {
...globals.node
}
},
rules: {
...jqueryConfig.rules,
strict: [ "error", "global" ],

// Too many errors
"max-len": "off"
}
},

{
files: [
"test/*.js"
],
languageOptions: {
globals: {
...globals.node,
...globals.mocha
}
},
rules: {
...jqueryConfig.rules,

// Chai `expect` API violates this rule
"no-unused-expressions": "off",

// Too many errors
"max-len": "off"
}
}
];
8 changes: 4 additions & 4 deletions lib/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ caches = [];

cacheCron = function() {
var currentTime = Date.now();
caches.forEach(function( cache ) {
caches.forEach( function( cache ) {
var count = {
cached: 0,
deleted: 0
};

cache.each(function( value, key ) {
cache.each( function( _value, key ) {
count.cached++;
if ( cache.expires[ key ] < currentTime ) {
cache.destroy( key );
count.deleted++;
}
});
});
} );
} );
cacheCronTimeout = setTimeout( cacheCron, cacheExpiresTime );
};

Expand Down
3 changes: 3 additions & 0 deletions lib/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
67 changes: 35 additions & 32 deletions lib/themeroller-image.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var cache, imVersion,
async = require( "async" ),
Cache = require( "./cache" ),
im = require( "gm" ).subClass({ imageMagick: true }),
im = require( "gm" ).subClass( { imageMagick: true } ),
semver = require( "semver" ),
dimensionLimit = 3000,
namedColors = require( "./themeroller-colors" );
Expand All @@ -10,9 +10,9 @@ cache = new Cache( "Image Cache" );

function expandColor( color ) {
if ( color.length === 3 && /^[0-9a-f]+$/i.test( color ) ) {
return [ 0, 0, 1, 1, 2, 2 ].map(function( i ) {
return [ 0, 0, 1, 1, 2, 2 ].map( function( i ) {
return color[ i ];
}).join( "" );
} ).join( "" );
}
return color;
}
Expand All @@ -28,11 +28,11 @@ function hashColor( color ) {
function pick( obj ) {
var copy = {};
var keys = [].concat.apply( [], [].slice.call( arguments, 1 ) );
keys.forEach(function( key ) {
keys.forEach( function( key ) {
if ( key in obj ) {
copy[ key ] = obj[ key ];
}
});
} );
return copy;
}

Expand All @@ -49,56 +49,58 @@ function stream2Buffer( callback ) {
stdin.on( "data", function( chunk ) {
chunks.push( chunk );
dataLen += chunk.length;
});
} );

stderr.on( "data", function( chunk ) {
err += chunk;
});
} );

stdin.on( "end", function() {
var i = 0,
buffer = Buffer.alloc( dataLen );
if ( err.length ) {
return callback( new Error( err ) );
}
chunks.forEach(function ( chunk ) {
chunks.forEach( function( chunk ) {
chunk.copy( buffer, i, 0, chunk.length );
i += chunk.length;
});
} );
callback( null, buffer );
});
} );

stdin.on( "error", function( err ) {
callback( err );
});
} );
};
}

function validateColor( color ) {
color = color.replace( /^#/, "" );
if ( ( color.length === 3 || color.length === 6 ) && /^[0-9a-f]+$/i.test( color ) ) {

// ok
} else if ( namedColors.indexOf( color.toLowerCase() ) !== -1 ) {

// ok
} else {
throw new Error( "invalid color \"" + color + "\"" );
}
}

function validateDimension( params, dimensionParams ) {
var invalidParams = dimensionParams.filter(function( param ) {
var invalidParams = dimensionParams.filter( function( param ) {
return parseInt( params[ param ], 10 ) > dimensionLimit;
});
} );

if ( invalidParams.length ) {
throw new Error( "dimension bigger than allowed limit " + JSON.stringify( pick( params, invalidParams ) ) );
}
}

function validateInteger( params, integerParams ) {
var invalidParams = integerParams.filter(function( param ) {
return isNaN( parseInt( params[ param ], 10 ) ) || (/[^0-9]/).test( params[ param ] );
});
var invalidParams = integerParams.filter( function( param ) {
return isNaN( parseInt( params[ param ], 10 ) ) || ( /[^0-9]/ ).test( params[ param ] );
} );

if ( invalidParams.length ) {
throw new Error( "got a non-integer " + JSON.stringify( pick( params, invalidParams ) ) );
Expand All @@ -113,9 +115,9 @@ function validateOpacity( opacity ) {
}

function validatePresence( params, requiredParams ) {
var missingParams = requiredParams.filter(function( param ) {
var missingParams = requiredParams.filter( function( param ) {
return !params[ param ];
});
} );

if ( missingParams.length ) {
throw new Error( "missing \"" + missingParams.join( "\", \"" ) + "\"" );
Expand Down Expand Up @@ -151,7 +153,7 @@ generateIcon = function( params, callback ) {
// IM > 6.7.9: (see #132 http://git.io/gfSacg)
// $ convert <icons_mask_filename> -set colorspace RGB -background <color> -alpha shape -set colorspace sRGB output.png

imageQueue.push(function( innerCallback ) {
imageQueue.push( function( innerCallback ) {
try {
if ( semver.gt( imVersion, "6.7.9" ) ) {
im( __dirname + "/../assets/icon/mask.png" )
Expand All @@ -166,7 +168,7 @@ generateIcon = function( params, callback ) {
.out( "-alpha", "shape" )
.stream( "png", stream2Buffer( innerCallback ) );
}
} catch( err ) {
} catch ( err ) {
return innerCallback( err );
}
}, callback );
Expand All @@ -183,12 +185,12 @@ generateTexture = function( params, callback ) {
// http://www.imagemagick.org/Usage/compose/#dissolve
// $ convert -size <width>x<height> 'xc:<color>' <texture_filename> -compose dissolve -define compose:args=<opacity>,100 -composite output.png

imageQueue.push(function( innerCallback ) {
imageQueue.push( function( innerCallback ) {
try {
im( params.width, params.height, color )
.out( __dirname + "/../assets/texture/" + filename, "-compose", "dissolve", "-define", "compose:args=" + params.opacity + ",100", "-composite" )
.stream( "png", stream2Buffer( innerCallback ) );
} catch( err ) {
} catch ( err ) {
return innerCallback( err );
}
}, callback );
Expand Down Expand Up @@ -314,19 +316,19 @@ Image.prototype = {
cached.data = data;
delete cached.callbacks;
}
callbacks.forEach(function( callback ) {
callbacks.forEach( function( callback ) {
callback( err, filename, data );
});
} );
delete cached.callbacks;
if ( err ) {
cache.destroy( filename );
}
});
} );
}
};

// Check the ImageMagick installation using node-gm (in a hacky way).
async.series([
async.series( [
function( callback ) {
var wrappedCallback = function( err ) {
if ( err ) {
Expand All @@ -335,15 +337,15 @@ async.series([
callback();
};
try {
im()._spawn([ "convert", "-version" ], true, wrappedCallback );
} catch( err ) {
im()._spawn( [ "convert", "-version" ], true, wrappedCallback );
} catch ( err ) {
return wrappedCallback( err );
}
},
function( callback ) {
im()._spawn([ "convert", "-version" ], false, stream2Buffer(function( err, buffer ) {
im()._spawn( [ "convert", "-version" ], false, stream2Buffer( function( _err, buffer ) {
var output = buffer.toString( "utf8" );
if ( !(/ImageMagick/).test( output ) ) {
if ( !( /ImageMagick/ ).test( output ) ) {
return callback( new Error( "ImageMagick not installed.\n" + output ) );
}
imVersion = output.split( "\n" )[ 0 ].replace( /^Version: ImageMagick ([^ ]*).*/, "$1" );
Expand All @@ -352,13 +354,14 @@ async.series([
}
imageQueue.resume();
callback();
}));
} ) );
}
], function( err ) {
if ( err ) {

// On error, abort
throw new Error( err );
}
});
} );

module.exports = Image;
Loading