Tdarr_Plugins/tests/checkPlugins.js
HaveAGitGat 2a0a7e1bfc
Add new tests (#311)
* Add new tests

* Add tdarrSkipTest logic

* Add Tdarr_Plugin_00td_action_add_audio_stream_codec test

* Add Tdarr_Plugin_00td_action_handbrake_basic_options test

* Add Tdarr_Plugin_00td_action_handbrake_ffmpeg_custom test

* Add Tdarr_Plugin_00td_action_keep_one_audio_stream test

* Fix lint

* Fix reorder streams bug

* Add Tdarr_Plugin_00td_action_re_order_all_streams_v2 test

* Add Tdarr_Plugin_00td_action_remux_container test

* Add Tdarr_Plugin_00td_action_standardise_audio_stream_codecs test

* Lint

* Add Tdarr_Plugin_00td_filter_by_bitrate test

* Add Tdarr_Plugin_00td_filter_by_resolution test

* Add Tdarr_Plugin_00td_filter_by_size test

* Log all errors together, use chalk

* Add Tdarr_Plugin_075a_FFMPEG_HEVC_Generic test

* Add Tdarr_Plugin_075a_Transcode_Customisable test

* Add Tdarr_Plugin_075b_FFMPEG_HEVC_Generic_Video_Audio_Only test

* Add Tdarr_Plugin_075c_FFMPEG_HEVC_Generic_Video_Audio_Only_CRF20 test

* Add Tdarr_Plugin_075d_FFMPEG_HEVC_GPU_Generic_Video_Audio_Only_CRF20 test

* Add Tdarr_Plugin_076a_re_order_audio_streams test

* Add chalk

* Add Tdarr_Plugin_076b_re_order_subtitle_streams

* Add Tdarr_Plugin_077b_HandBrake_NVENC_264_Configurable test

* Add Tdarr_Plugin_a8hc_HaveAGitGat_HandBrake_H264_VeryFast1080p30 test

* Add Tdarr_Plugin_a9hc_HaveAGitGat_HandBrake_H264_Fast1080p30 test

* Add Tdarr_Plugin_a9hd_FFMPEG_Transcode_Specific_Audio_Stream_Codecs test

* Update qsv to vaapi (will handle input at later date)

* Add Tdarr_Plugin_a9he_New_file_size_check test

* useCloneDeep

* Add Tdarr_Plugin_a37x_Drawmonster_MP4_No_Title_Meta test

* Add Tdarr_Plugin_A47j_FFMPEG_NVENC_HEVC_Video_Only test

* Add Tdarr_Plugin_b38x_Nosirus_h265_aac_no_meta test

* Add Tdarr_Plugin_b39x_the1poet_surround_sound_to_ac3 test

* Add Tdarr_Plugin_bsh1_Boosh_FFMPEG_QSV_HEVC test

* Add Tdarr_Plugin_c0r1_SetDefaultAudioStream test

* Lint

* Add Tdarr_Plugin_d5d3_iiDrakeii_FFMPEG_NVENC_Tiered_MKV test

* Add Tdarr_Plugin_d5d4_iiDrakeii_Not_A_Video_Mjpeg_Fix test

* Add Tdarr_Plugin_da11_Dallas_FFmpeg_Presets_H264_MP4 test

* Tdarr_Plugin_DOOM_NVENC_Tiered_MKV_CleanAll test

* Remove logging

* Add Tdarr_Plugin_drdd_standardise_all_in_one test

* Add Tdarr_Plugin_e3jc_Tharic_H.264_MKV_480p30_No_Subs_No_Title_Meta test

* Add Tdarr_Plugin_e3jd_Tharic_H.264_MKV_720p30_No_Subs_No_Title_Meta test

* Add Tdarr_Plugin_e3je_Tharic_H.264_MKV_1080p30_No_Subs_No_Title_Meta test

* Add Tdarr_Plugin_e5c3_CnT_Keep_Preferred_Audio test

* Add Tdarr_Plugin_ER01_Transcode audio and video with HW (PC and Mac) test

* Add Tdarr_Plugin_fd5T_Sparticus_4K_AC3_No_Subs test

* Add Tdarr_Plugin_Greg_MP3_FFMPEG_CPU test

* Add Tdarr_Plugin_henk_Add_Specific_Audio_Codec test

* Add Tdarr_Plugin_hk75_Drawmonster_MP4_AAC_No_Subs_No_metaTitle test

* Add Tdarr_Plugin_hk76_GilbN_MP4_AAC_No_metaTitle test

* Add outputModify func

* Base tests on linux for now

* Add Tdarr_Plugin_jeons001_Downmix_to_stereo_and_apply_DRC test

* Add Tdarr_Plugin_lmg1_Reorder_Streams test

* Add Tdarr_Plugin_MC93_Migz1FFMPEG test

* Add Tdarr_Plugin_MC93_Migz1FFMPEG_CPU test

* Add Tdarr_Plugin_MC93_Migz1Remux test

* Add Tdarr_Plugin_MC93_Migz2CleanTitle test

* Add Tdarr_Plugin_MC93_Migz2CleanTitle test

* Add Tdarr_Plugin_MC93_Migz3CleanAudio test

* Add Tdarr_Plugin_MC93_Migz4CleanSubs test

* Add Tdarr_Plugin_MC93_Migz5ConvertAudio test

* Add Tdarr_Plugin_MC93_Migz6OrderStreams test

* Add Tdarr_Plugin_MC93_MigzImageRemoval test

* Add Tdarr_Plugin_MP01_MichPasCleanSubsAndAudioCodecs test

* Add Tdarr_Plugin_Mthr_VaapiHEVCTranscode test

* Add Tdarr_Plugin_nc7x_Drawmonster_No_Title_Meta test

* Add Tdarr_Plugin_r002_rootuser_FFMPEG_HQ_HEVC_MKV_Animation test

* Add Tdarr_Plugin_raf4_Floorpie_FFmpeg_Tiered_HEVC_MKV test

* Add Tdarr_Plugin_s7x8_winsome_h265 test
2022-05-22 18:32:59 +02:00

208 lines
7.7 KiB
JavaScript

/* eslint no-console: 0 */ // --> OFF
/* eslint max-len: 0 */
const fs = require('fs');
const chalk = require('chalk');
const folders = [
'./Community',
'./examples',
];
let errorEncountered = false;
folders.forEach((folder) => {
const files = fs.readdirSync(folder).filter((row) => row.includes('.js'));
const detailsOrder = [
'id',
'Stage',
'Name',
'Type',
'Operation',
'Description',
'Version',
'Tags',
'Inputs',
];
const pluginInputTypes = ['string', 'number', 'boolean'];
for (let i = 0; i < files.length; i += 1) {
let read = fs.readFileSync(`${folder}/${files[i]}`).toString();
const importLib = 'const lib = require(\'../methods/lib\')();';
if (!read.includes(importLib)) {
console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${importLib}`));
read = `${importLib}\n${read}`;
// fs.writeFileSync(`${folder}/${files[i]}`, read)
errorEncountered = true;
}
const detailsText = 'const details = () =>';
if (!read.includes(detailsText)) {
console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${detailsText}`));
errorEncountered = true;
}
const syncText = 'const plugin = (file, librarySettings, inputs, otherArguments) => {';
const asyncText = 'const plugin = async (file, librarySettings, inputs, otherArguments) => {';
if (!read.includes(syncText)
&& !read.includes(asyncText)
) {
console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${syncText} or ${asyncText}`));
errorEncountered = true;
}
const inputsText = 'inputs = lib.loadDefaultValues(inputs, details);';
if (!read.includes(inputsText)
) {
console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${inputsText}`));
errorEncountered = true;
}
const exportText = `module.exports.details = details;
module.exports.plugin = plugin;`;
if (!read.includes(exportText)) {
console.log(chalk.red(`Plugin error: '${folder}/${files[i]}' does not contain ${exportText}`));
read = read.replace('module.exports.details = details;', '');
read = read.replace('module.exports.plugin = plugin;', '');
read += `\n${exportText}`;
// fs.writeFileSync(`${folder}/${files[i]}`, read)
errorEncountered = true;
}
// check deps are within functions
const keyWord = 'require(';
const requires = read.split(keyWord);
if (requires.length >= 2) {
const allBefore = [];
for (let j = 0; j < requires.length - 1; j += 1) {
allBefore.push(requires[j]);
const countOpen = allBefore.join(keyWord).split('{').length - 1;
const countClose = allBefore.join(keyWord).split('}').length - 1;
if (countOpen === countClose) {
console.log(chalk.red(`Plugin has requires outside of function '${folder}/${files[i]}'`));
errorEncountered = true;
}
}
}
let pluginDetails;
try {
// eslint-disable-next-line import/no-dynamic-require,global-require
pluginDetails = require(`.${folder}/${files[i]}`).details();
} catch (err) {
console.log(chalk.red(err.message));
errorEncountered = true;
}
const detailsKeys = Object.keys(pluginDetails);
// eslint-disable-next-line no-loop-func
detailsOrder.forEach((detail) => {
if (detailsKeys.indexOf(detail) === -1) {
console.log(chalk.red(`Plugin details is missing '${folder}/${files[i]}' : ${detail}`));
errorEncountered = true;
}
});
// eslint-disable-next-line no-loop-func
detailsKeys.forEach((detail, index) => {
if (detailsOrder[index] !== detail) {
console.log(chalk.red(`Plugin details keys are not in the correct order: '${folder}/${files[i]}' ${detail}`));
errorEncountered = true;
}
});
if (detailsKeys.length < detailsOrder.length) {
console.log(chalk.red(`Plugin details are too few '${folder}/${files[i]}'`));
errorEncountered = true;
}
if (!['Pre-processing', 'Post-processing'].includes(pluginDetails.Stage)) {
console.log(chalk.red(`Plugin does not have a valid Type'${folder}/${files[i]}'`));
errorEncountered = true;
}
if (!['Video', 'Audio', 'Subtitle', 'Any'].includes(pluginDetails.Type)) {
console.log(chalk.red(`Plugin does not have a valid Type'${folder}/${files[i]}'`));
errorEncountered = true;
}
if (files[i].split('.js').join('') !== pluginDetails.id) {
console.log(chalk.red(`Plugin file name does not match details id'${folder}/${files[i]}'`));
errorEncountered = true;
}
if (!['Transcode', 'Filter'].includes(pluginDetails.Operation)) {
console.log(chalk.red(`Plugin does not have a valid Operation '${folder}/${files[i]}'`));
errorEncountered = true;
} else if (detailsKeys.length > detailsOrder.length) {
console.log(chalk.red(`Plugin details are too many '${folder}/${files[i]}'`));
errorEncountered = true;
} else if (pluginDetails.Inputs && !Array.isArray(pluginDetails.Inputs)) {
// Check default values are set;
console.log(chalk.red(`Plugin Inputs is not an array: ${files[i]}`));
errorEncountered = true;
} else if (pluginDetails.Inputs && Array.isArray(pluginDetails.Inputs)) {
const inputs = pluginDetails.Inputs;
const savedInputs = {};
for (let j = 0; j < inputs.length; j += 1) {
// Prevent duplicate plugin inputs
if (savedInputs[inputs[j].name] === true) {
console.log(chalk.red(`Plugin Input already exists: '${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
} else {
savedInputs[inputs[j].name] = true;
}
const inputKeys = Object.keys(inputs[j]);
if (
inputKeys[0] !== 'name'
|| inputKeys[1] !== 'type'
|| inputKeys[2] !== 'defaultValue'
|| inputKeys[3] !== 'inputUI'
|| inputKeys[4] !== 'tooltip'
) {
console.log(chalk.red(`Plugin Input keys are not in correct order: '${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
} else if (inputs[j].type === undefined || !pluginInputTypes.includes(inputs[j].type)) {
console.log(chalk.red(`Plugin Input does not have a type: '${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
} else if (
(inputs[j].type === 'string' && typeof inputs[j].defaultValue !== 'string')
|| (inputs[j].type === 'number' && typeof inputs[j].defaultValue !== 'number')
|| (inputs[j].type === 'boolean' && typeof inputs[j].defaultValue !== 'boolean')
) {
console.log(chalk.red(`Plugin Input type does not match defaultValue type:
'${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
} else if (!['text', 'dropdown'].includes(inputs[j].inputUI.type)) {
console.log(chalk.red(`Plugin Input inputUI is invalid: '${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
} else if (inputs[j].defaultValue === undefined) {
console.log(chalk.red(`Plugin Input does not have a default value: '${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
}
const count = read.split(inputs[j].name).length - 1;
if (count === 1) {
console.log(chalk.red(`Plugin Input is not used: '${folder}/${files[i]}' : ${inputs[j].name}`));
errorEncountered = true;
}
}
}
console.log(`[✓]${folder}/${files[i]}`);
}
});
console.log('Done!');
if (errorEncountered) {
console.log('Errors encountered');
process.exit(1);
}