Best JavaScript code snippet using karma
watch.js
Source:watch.js
1module.exports = {2 description: "Watch a message textpattern in the server",3 icon: {4 emoji: "ðâð¨",5 url: "https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/240/twitter/236/eye-in-speech-bubble_1f441-fe0f-200d-1f5e8-fe0f.png"6 },7 args: {8 usage: [{9 title: "View all watch patterns",10 parameters: [11 "view"12 ]13 }, {14 title: "Set a watch pattern",15 parameters: [16 "set",17 "[RegExp]",18 "-channels:focus/ignore:[Channel Tag] (multiple channels separated by a comma)",19 "-members:focus/ignore:[Member Tag/ID] (multiple members separated by a comma)",20 "-roles:focus/ignore:[Role ID] (multiple channels separated by a comma)",21 "-action:[Action Name]:[Action Data] (multiple action tags for separate actions)"22 ]23 }, {24 title: "Remove a watch pattern",25 parameters: [26 "remove",27 "[Pattern ID]"28 ]29 }],30 detectors: [31 /^set|view|remove/i,32 /\/[^]+?(?<!\\)\/[ig]*|\d+/,33 /^-channels:(focus|ignore):(?:(?:<#)?\d+>?,?)+/i,34 /^-members:(focus|ignore):(?:(?:<@)?\d+>?,?)+/i,35 /^-roles:(focus|ignore):(?:(?:<@&)?\d+>?,?)+/i,36 /^-actions:(?:\d+,?)+/i37 ]38 },39 run,40 parse41}4243const instanceType = {44 focus: true,45 ignore: false,46 true: "Focus",47 false: "Ignore"48};4950const actions = {51 view,52 remove,53 set54};5556async function run(pack, { action, ...data }) {57 return actions[action](pack, data);58}596061async function view({ cache, messageDefault }, { patternCode }) {62 if (patternCode) {63 const {64 pattern,65 actionRegistries,66 criteria: {67 channelIDs,68 channelType,69 memberIDs,70 memberType,71 roleIDs,72 roleType73 }74 } = cache.watchPatterns.get(patternCode);75 76 return messageDefault(`**Pattern:** \`/${pattern[0]}/${pattern[1]}\``)77 .addFields([{78 name: "Criteria",79 value: [80 `â«ï¸ ${instanceType[channelType]} channel(s): ${channelIDs.map(channelID => `<#${channelID}>`).join(", ") || "*All*"}`,81 `â«ï¸ ${instanceType[memberType]} member(s): ${memberIDs.map(memberID => `<@${memberID}>`).join(", ") || "*All*"}`,82 `â«ï¸ ${instanceType[roleType]} role(s): ${roleIDs.map(roleID => `<@&${roleID}>`).join(", ") || "*All*"}`83 ].join("\n")84 }, {85 name: "Actions",86 value: `The registered Action Codes are:\n${actionRegistries.map(({ actionCode }) => actionCode).join(", ") || "*None*"}`87 }])88 .author.name = "Watch Pattern | View";89 }90 const patternEntries = cache.watchPatterns.map(([ watcherCode, { pattern } ]) => {91 return `â«ï¸ #${watcherCode}: /${pattern[0]}/${pattern[1]}`;92 }).join("\n");9394 return messageDefault(patternEntries)95 .author.name = "Watch Pattern | View All";96}97async function remove({ cache, messageSuccess }, { patternCode }) {98 const pattern = [ ...cache.watchPatterns.get(patternCode).pattern ];99 cache.watchPatterns.delete(patternCode);100 101 return Promise.all([102 cache.save("watchPatterns"),103 messageSuccess(`Successfully removed pattern \`/${pattern[0]}/${pattern[1]}\` from Pattern Code \`${patternCode}\``)104 ]);105}106async function set({ cache, messageSuccess }, patternData) {107 const patternCode = cache.watchPatterns.register(patternData);108 109 return Promise.all([110 cache.save("watchPatterns"),111 messageSuccess(`Successfully set pattern \`/${patternData.pattern[0]}/${patternData.pattern[1]}\` on Pattern Code \`${patternCode}\`!`)112 ]);113}114115function parse({ botActions, cache, channels, members, roles, messageError }, [ rawAction, patternTag, channelField, memberField, roleField, actionField ]) {116 // $watch word @member/#channel/@&role:focus/ignore -log:type:<message> -warn:<message> -mute:<reason> -kick:<reason>117 // $watch set pattern -channels:focus:#channel,#channel -members:focus:@member,@member -roles:focus:RoleID,RoleID -action:log,<message>,type118 if (!rawAction) return messageError("You did not provide the action you want to perform in this command!");119 const action = rawAction.toLowerCase();120121 // If selection is [view/remove], consider pattern as patternID for viewing/deleting patterns122 if (["view", "remove"].includes(action)) {123 const patternCode = !patternTag ? 0 : parseInt(patternTag, 10);124 console.log(patternTag, patternCode);125 if (isNaN(patternCode)) return messageError("You provided an invalid Pattern ID!");126 127 if (action === "view" && patternCode > 0 && !cache.watchPatterns.has(patternCode)) return messageError(`The pattern by code \`${patternCode}\` does not exist!`);128 if (action === "remove" && !cache.watchPatterns.has(patternCode)) return messageError(`The pattern by code \`${patternCode}\` does not exist!`);129 130 return { action, patternCode };131 }132 133 if (!patternTag) return messageError("You did not provide a pattern that you want to watch!");134 135 const [, patternSource, patternFlags = ""] = patternTag.match(/\/([^]+?)(?<!\\)\/([ig]+)?/);136 137 // Channel Parsing138 const [, channelTypeStr = "focus", channelTags = ""] = channelField.match(/^-channels:(focus|ignore):((?:(?:<#)?\d+>?,?)+)/i) || [];139 const channelIDs = channelTags.split(",").filter(Boolean)140 .map(channelTag => channelTag.match(/(?:<#)?(\d+)>?/)[1]);141 142 const invalidChannels = channelIDs.filter(channelID => !channels.cache.has(channelID));143 if (invalidChannels.length) return messageError(`The following channels by IDs are invalid: ${invalidChannels.join(", ")}`);144 145 // Member Parsing146 const [, memberTypeStr = "focus", memberTags = ""] = memberField.match(/^-members:(focus|ignore):((?:(?:<@!?)?\d+>?,?)+)/i,) || [];147 const memberIDs = memberTags.split(",").filter(Boolean)148 .map(memberTag => memberTag.match(/(?:<@)?!?(\d+)>?/)[1]);149 150 const invalidMembers = memberIDs.filter(memberID => !members.cache.has(memberID));151 if (invalidChannels.length) return messageError(`The following members by IDs are invalid: ${invalidMembers.join(", ")}`);152 153 // Role Parsing154 const [, roleTypeStr = "focus", roleTags = ""] = roleField.match(/^-roles:(focus|ignore):((?:(?:<@&)?\d+>?,?)+)/i) || [];155 const roleIDs = roleTags.split(",").filter(Boolean)156 .map(roleID => roleID.match(/(?:<@&)?(\d+)>?/)[1]);157 158 const invalidRoles = roleIDs.filter(roleID => !roles.cache.has(roleID));159 if (invalidRoles.length) return messageError(`The following roles by IDs are invalid: ${invalidRoles.join(", ")}`);160 161 // Action Parsing162 if (!actionField) return messageError("You did not provide the actions that are supposed to be carried out as a result of this watch pattern!");163 164 const actionIDs = actionField.match(/^-actions:((?:\d+,?)+)/i)[1].split(",").filter(Boolean);165 const actionRegistries = actionIDs.map(actionIDStr => {166 const actionCode = parseInt(actionIDStr, 10);167 if (isNaN(actionCode)) return new Error(`You provided an invalid Action Code \`${actionIDStr}\`!`);168 169 const actionData = botActions.actionData.get(actionCode);170 if (!actionData) return new Error(`Action Data by code \`${actionCode}\` does not exist!`);171 172 return { actionName: actionData.actionName, actionCode };173 });174 175 const actionErrors = actionRegistries.filter(actionRegistry => actionRegistry instanceof Error);176 if (actionErrors.length) return messageError(`The following errors were encountered: \n${actionErrors.map(actionError => `â«ï¸ ${actionError.message}`).join("\n")}`);177 /*178 return new MessageError(`> End of parsing179Action: ${action}180181â«ï¸Pattern182Source: ${patternSource}183Flags: ${patternFlags}184185â«ï¸Channels186Type: ${channelTypeStr}187Values: ${channelIDs.join(", ")}188189â«ï¸Members190Type: ${memberTypeStr}191Values: ${memberIDs.join(", ")}192193â«ï¸Roles194Type: ${roleTypeStr}195Values: ${roleIDs.join(", ")}196*/197 return {198 pattern: [ patternSource, patternFlags ],199 action,200 actionRegistries,201 criteria: {202 channelIDs,203 channelType: instanceType[channelTypeStr.toLowerCase()],204 memberIDs,205 memberType: instanceType[memberTypeStr.toLowerCase()],206 roleIDs,207 roleType: instanceType[roleTypeStr.toLowerCase()]208 }209 };
...
index.js
Source:index.js
1'use strict';2// Native3const fs = require('fs');4const path = require('path');5// Packages6const app = require('express')();7const chokidar = require('chokidar');8const multer = require('multer');9const sha1File = require('sha1-file');10// Ours11const AssetFile = require('./AssetFile');12const {authCheck, debounceName} = require('../util');13const bundles = require('../bundle-manager');14const log = require('../logger')('nodecg/lib/assets');15const Replicant = require('../replicant');16const ASSETS_ROOT = path.join(process.env.NODECG_ROOT, 'assets');17const collectionsRep = new Replicant('collections', '_assets', {defaultValue: [], persistent: false});18const replicantsByNamespace = {};19const watchPatterns = [];20const upload = multer({21 storage: multer.diskStorage({22 destination: ASSETS_ROOT,23 filename(req, file, cb) {24 cb(null, `${req.params.namespace}/${req.params.category}/${file.originalname}`);25 }26 })27});28let _ready = false;29let _deferredFiles = new Map();30const collections = [];31// Create ASSETS_ROOT folder if it does not exist.32/* istanbul ignore next: Simple directory creation. */33if (!fs.existsSync(ASSETS_ROOT)) {34 fs.mkdirSync(ASSETS_ROOT);35}36bundles.all().forEach(bundle => {37 if (!bundle.hasAssignableSoundCues && (!bundle.assetCategories || bundle.assetCategories.length <= 0)) {38 return;39 }40 // If this bundle has sounds && at least one of those sounds is assignable, create the assets:sounds replicant.41 if (bundle.hasAssignableSoundCues) {42 bundle.assetCategories.unshift({43 name: 'sounds',44 title: 'Sounds',45 allowedTypes: ['mp3', 'ogg']46 });47 }48 collections.push({49 name: bundle.name,50 categories: bundle.assetCategories51 });52});53collections.forEach(({name, categories}) => {54 const namespacedAssetsPath = calcNamespacedAssetsPath(name);55 replicantsByNamespace[name] = {};56 collectionsRep.value.push({name, categories});57 categories.forEach(category => {58 /* istanbul ignore next: Simple directory creation. */59 const categoryPath = path.join(namespacedAssetsPath, category.name);60 if (!fs.existsSync(categoryPath)) {61 fs.mkdirSync(categoryPath);62 }63 replicantsByNamespace[name][category.name] = new Replicant(`assets:${category.name}`, name, {64 defaultValue: [],65 persistent: false66 });67 if (category.allowedTypes && category.allowedTypes.length > 0) {68 category.allowedTypes.forEach(type => {69 watchPatterns.push(`${categoryPath}/**/*.${type}`);70 });71 } else {72 watchPatterns.push(`${categoryPath}/**/*`);73 }74 });75});76// Chokidar no longer accepts Windows-style path separators when using globs.77// Therefore, we must replace them with Unix-style ones.78// See https://github.com/paulmillr/chokidar/issues/777 for more details.79const fixedPaths = watchPatterns.map(pattern => pattern.replace(/\\/g, '/'));80const watcher = chokidar.watch(fixedPaths, {ignored: /[/\\]\./});81/* When the Chokidar watcher first starts up, it will fire an 'add' event for each file found.82 * After that, it will emit the 'ready' event.83 * To avoid thrashing the replicant, we want to add all of these first files at once.84 * This is what the _ready Boolean, _deferredFiles Map, and resolveDeferreds function are for.85 */86watcher.on('add', filepath => {87 if (!_ready) {88 _deferredFiles.set(filepath, null);89 }90 sha1File(filepath, (err, sum) => {91 if (err) {92 if (_deferredFiles) {93 _deferredFiles.remove(filepath);94 }95 log.error(err);96 return;97 }98 const uploadedFile = new AssetFile(filepath, sum);99 if (_deferredFiles) {100 _deferredFiles.set(filepath, uploadedFile);101 resolveDeferreds();102 } else {103 replicantsByNamespace[uploadedFile.namespace][uploadedFile.category].value.push(uploadedFile);104 }105 });106});107watcher.on('ready', () => {108 _ready = true;109});110watcher.on('change', filepath => {111 debounceName(filepath, () => {112 sha1File(filepath, (err, sum) => {113 if (err) {114 log.error(err);115 return;116 }117 const newUploadedFile = new AssetFile(filepath, sum);118 const rep = replicantsByNamespace[newUploadedFile.namespace][newUploadedFile.category];119 const index = rep.value.findIndex(uf => uf.url === newUploadedFile.url);120 if (index > -1) {121 rep.value.splice(index, 1, newUploadedFile);122 } else {123 rep.value.push(newUploadedFile);124 }125 });126 });127});128watcher.on('unlink', filepath => {129 const deletedFile = new AssetFile(filepath);130 const rep = replicantsByNamespace[deletedFile.namespace][deletedFile.category];131 rep.value.some((assetFile, index) => {132 if (assetFile.url === deletedFile.url) {133 rep.value.splice(index, 1);134 log.debug('"%s" was deleted', deletedFile.url);135 return true;136 }137 return false;138 });139});140watcher.on('error', e => log.error(e.stack));141// Retrieving existing files142app.get(143 '/assets/:namespace/:category/:filePath',144 // Check if the user is authorized.145 authCheck,146 // Send the file (or an appropriate error).147 (req, res) => {148 const fullPath = path.join(ASSETS_ROOT, req.params.namespace, req.params.category, req.params.filePath);149 res.sendFile(fullPath, err => {150 if (err && !res.headersSent) {151 if (err.code === 'ENOENT') {152 return res.sendStatus(404);153 }154 log.error(`Unexpected error sending file ${fullPath}`, err);155 res.sendStatus(500);156 }157 });158 }159);160const uploader = upload.array('file', 64);161// Uploading new files162app.post(163 '/assets/:namespace/:category',164 // Check if the user is authorized.165 authCheck,166 // Then receive the files they are sending, up to a max of 64.167 (req, res, next) => {168 uploader(req, res, err => {169 if (err) {170 console.error(err);171 res.send(500);172 return;173 }174 next();175 });176 },177 // Then send a response.178 (req, res) => {179 if (req.files) {180 res.status(200).send('Success');181 } else {182 res.status(400).send('Bad Request');183 }184 }185);186// Deleting existing files187app.delete(188 '/assets/:namespace/:category/:filename',189 // Check if the user is authorized.190 authCheck,191 // Delete the file (or an send appropriate error).192 (req, res) => {193 const {namespace, category, filename} = req.params;194 const fullPath = path.join(ASSETS_ROOT, namespace, category, filename);195 fs.unlink(fullPath, err => {196 if (err) {197 if (err.code === 'ENOENT') {198 return res.status(410).send(`The file to delete does not exist: ${filename}`);199 }200 log.error(`Failed to delete file ${fullPath}`, err);201 return res.status(500).send(`Failed to delete file: ${filename}`);202 }203 res.sendStatus(200);204 });205 }206);207module.exports = app;208function calcNamespacedAssetsPath(namespace) {209 const assetsPath = path.join(ASSETS_ROOT, namespace);210 /* istanbul ignore next: Simple directory creation. */211 if (!fs.existsSync(assetsPath)) {212 fs.mkdirSync(assetsPath);213 }214 return assetsPath;215}216function resolveDeferreds() {217 let foundNull = false;218 _deferredFiles.forEach(uf => {219 if (uf === null) {220 foundNull = true;221 }222 });223 if (!foundNull) {224 _deferredFiles.forEach(uploadedFile => {225 replicantsByNamespace[uploadedFile.namespace][uploadedFile.category].value.push(uploadedFile);226 });227 _deferredFiles = null;228 }...
censor.js
Source:censor.js
1module.exports = {2 description: "Manage Word Censors",3 icon: {4 emoji: "ð",5 url: "https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/240/twitter/247/muted-speaker_1f507.png"6 },7 args: {8 usage: [{9 title: "View all censored words (with their synonyms)",10 parameters: [11 "view"12 ]13 }, {14 title: "Censor a word",15 parameters: [16 "set",17 "[Word]",18 "[Ignore Channels]"19 ]20 }, {21 title: "Remove a character from an alphabet",22 parameters: [23 "remove",24 "[Word]"25 ]26 }, {27 title: "Remake the word's pattern when characters or synonyms are updated",28 parameters: [29 "rebase",30 "[Word]"31 ]32 }, {33 title: "Ignore a word (and all its synonyms) in a channel",34 parameters: [35 "addChannel",36 "[Word]",37 "[Channel Tag]"38 ]39 }, {40 title: "Unignore a word (and all its synonyms) from a channel",41 parameters: [42 "removeChannel",43 "[Word]",44 "[Channel Tag]"45 ]46 }],47 detectors: [48 /^view|set|addchannel|removechannel|watch|unwatch|rebase|remove/,49 /^[a-z]+/i,50 /(?:<#)?\d+>?/i51 ]52 },53 run,54 parse55};5657const actions = {58 set,59 view,60 remove,61 watch,62 unwatch,63 rebase,64 addchannel,65 removechannel66};6768async function run(pack, { action, ...data }) {69 return actions[action](pack, data);70}7172async function view({ cache, messageDefault }) {73 const censoredWords = Array.from(cache.wordCensor.entries())74 .map(([ censorWord, { synonyms } ]) => {75 return `${censorWord}${synonyms.length ? ` (${synonyms.join(", ")})` : ""}`;76 })77 .join(", ");78 79 return messageDefault(censoredWords || "*There are no censored words*")80 .author.name = "Word Censor | View"81}8283async function set({ cache, messageSuccess }, { censorWord }) {84 cache.wordCensor.createCensor(censorWord, "censor");85 86 return Promise.all([87 cache.save("wordCensor"),88 cache.save("watchPatterns"),89 messageSuccess(`Successfully censored word "${censorWord}"!`)90 ]);91}9293async function remove({ cache, messageSuccess }, { censorWord, censorID }) {94 cache.watchPatterns.delete(censorID);95 cache.wordCensor.delete(censorWord);96 97 return Promise.all([98 cache.save("watchPatterns"),99 cache.save("wordCensor"),100 messageSuccess(`Successfully uncensored word "${censorWord}"!`)101 ]);102}103104async function watch({ cache, messageSuccess }, { censorWord }) {105 cache.wordCensor.createCensor(censorWord, "watch");106 107 return Promise.all([108 cache.save("wordCensor"),109 cache.save("watchPatterns"),110 messageSuccess(`Successfully listed "${censorWord}" as watch word!`)111 ]);112}113114async function unwatch({ cache, messageSuccess }, { censorWord, censorID }) {115 cache.watchPatterns.delete(censorID);116 cache.wordCensor.delete(censorWord);117 118 return Promise.all([119 cache.save("wordCensor"),120 cache.save("watchPatterns"),121 messageSuccess(`Successfully unlisted word "${censorWord}" from watch words!`)122 ]);123}124125async function rebase({ cache, messageSuccess }, { censorWord, censorID, patternData }) {126 cache.wordCensor.rebaseCensor(censorWord);127 128 return Promise.all([129 cache.save("watchPatterns"),130 messageSuccess(`Successfully rebased censored word "${censorWord}"!`)131 ]);132}133134async function addchannel({ cache, messageSuccess }, { censorWord, censorID, channelID, ignoredChannels, patternData }) {135 const newIgnores = [ ...ignoredChannels, channelID ];136 cache.watchPatterns.edit(censorID, {137 ...patternData,138 criteria: {139 ...patternData.criteria,140 channelIDs: newIgnores141 }142 });143 144 return Promise.all([145 cache.save("watchPatterns"),146 messageSuccess(`Censored word "${censorWord}" will now be ignored in channel <#${channelID}>!`)147 ]);148}149150async function removechannel({ cache, messageSuccess }, { censorWord, censorID, channelID, ignoredChannels, patternData }) {151 const channelIndex = ignoredChannels.indexOf(channelID);152 const newIgnores = [ ...ignoredChannels.slice(0, channelIndex), ...ignoredChannels.slice(channelIndex + 1) ];153 cache.watchPatterns.edit(censorID, {154 ...patternData,155 criteria: {156 ...patternData.criteria,157 channelIDs: newIgnores158 }159 });160 161 return Promise.all([162 cache.save("watchPatterns"),163 messageSuccess(`Censored word "${censorWord}" will now be watched in channel <#"${channelID}>"!`)164 ]);165}166167function parse({ cache, channels, messageError }, [ rawAction, rawCensorWord, channelOrSynonym ]) {168 if (!rawAction) return messageError("You did not provide the action you want to perform in this command!");169 const action = rawAction.toLowerCase();170171 if (action === "view") return { action };172 173 if (!rawCensorWord) return messageError("You did not provide a word you want to work with!");174 const censorWord = rawCensorWord.toLowerCase();175 176 if (action === "set") {177 if (cache.wordCensor.has(censorWord)) return messageError(`The word "${censorWord}" is already censored!`);178 const synonymCensor = Array.from(cache.wordCensor.values()).find(({ synonyms }) => synonyms.includes(censorWord));179 if (synonymCensor) return messageError(`The word "${censorWord}" is set as the synonym of censor word "${synonymCensor.censorWord}"!`);180 181 return { action, censorWord };182 }183 184 const { censorID } = cache.wordCensor.get(censorWord);185 const patternData = cache.watchPatterns.get(censorID);186 187 if ([ "remove", "rebase", "addchannel", "removechannel" ].includes(action) && !cache.wordCensor.has(censorWord)) return messageError(`The word "${censorWord}" is not censored!`);188 if ([ "remove", "rebase" ].includes(action)) return { action, censorWord, censorID, patternData };189 190 const channelID = (channelOrSynonym.match(/(?:<#)?(\d+)>?/) || [])[1];191 if (!channelID) return messageError("You provided an invalid channel!");192 if (!channels.cache.has(channelID)) return messageError("The channel you provided is not a part of this guild!");193 194 const ignoredChannels = patternData.criteria.channelIDs;195 if (action.startsWith("add") && ignoredChannels.includes(channelID)) return messageError(`The provoded channel is already being ignored by the censor for the word "${censorWord}"!`);196 if (action.startsWith("remove") && !ignoredChannels.includes(channelID)) return messageError(`The provided channel was not being ignored by the censor for the word "${censorWord}"!`);197 198 return { action, censorWord, channelID, censorID, ignoredChannels, patternData };
...
watcher.spec.js
Source:watcher.spec.js
...12 beforeEach(() => {13 chokidarWatcher = new mocks.chokidar.FSWatcher()14 })15 it('should watch all the patterns', () => {16 m.watchPatterns(['/some/*.js', '/a/*'], chokidarWatcher)17 expect(chokidarWatcher.watchedPaths_).to.deep.equal(['/some', '/a'])18 })19 it('should expand braces and watch all the patterns', () => {20 m.watchPatterns(['/some/{a,b}/*.js', '/a/*'], chokidarWatcher)21 expect(chokidarWatcher.watchedPaths_).to.deep.equal(['/some/a', '/some/b', '/a'])22 })23 it('should not watch the same path twice', () => {24 m.watchPatterns(['/some/a*.js', '/some/*.txt'], chokidarWatcher)25 expect(chokidarWatcher.watchedPaths_).to.deep.equal(['/some'])26 })27 it('should not watch the same path twice when using braces', () => {28 m.watchPatterns(['/some/*.{js,txt}'], chokidarWatcher)29 expect(chokidarWatcher.watchedPaths_).to.deep.equal(['/some'])30 })31 it('should not watch subpaths that are already watched', () => {32 m.watchPatterns(['/some/sub/*.js', '/some/a*.*'].map(path.normalize), chokidarWatcher)33 expect(chokidarWatcher.watchedPaths_).to.deep.equal([path.normalize('/some')])34 })35 it('should watch a file matching subpath directory', () => {36 // regression #52137 m.watchPatterns(['/some/test-file.js', '/some/test/**'], chokidarWatcher)38 expect(chokidarWatcher.watchedPaths_).to.deep.equal(['/some/test-file.js', '/some/test'])39 })40 it('should watch files matching a subpath directory with braces', () => {41 m.watchPatterns(['/some/{a,b}/test.js'], chokidarWatcher)42 expect(chokidarWatcher.watchedPaths_).to.deep.equal(['/some/a/test.js', '/some/b/test.js'])43 })44 })45 describe('getWatchedPatterns', () => {46 it('should return list of watched patterns (strings)', () => {47 const watchedPatterns = m.getWatchedPatterns([48 config.createPatternObject('/watched.js'),49 config.createPatternObject({ pattern: 'non/*.js', watched: false })50 ])51 expect(watchedPatterns).to.deep.equal(['/watched.js'])52 })53 })54 describe('ignore', () => {55 const FILE_STAT = {...
autotest.js
Source:autotest.js
1var walkdir = require('walkdir');2var collection = require('./spec-collection');3var path = require('path');4var fs = require('fs');5var child_process = require('child_process');6var gaze = require('gaze');7var _ = require('underscore');8var baseArgv = [];9for(var i = 0; i < process.argv.length; i++) {10 if(process.argv[i] !== '--autotest') {11 baseArgv.push(process.argv[i]);12 }13}14var run_external = function(command, args, callback) {15 var child = child_process.spawn(command, args);16 child.stdout.on('data', function(data) {17 process.stdout.write(data);18 });19 child.stderr.on('data', function(data) {20 process.stderr.write(data);21 });22 if(typeof callback == 'function') {23 child.on('exit', callback);24 }25}26var run_everything = function() {27 // run the suite when it starts28 var argv = [].concat(baseArgv);29 run_external(argv.shift(), argv);30}31var last_run_succesful = true;32exports.start = function(loadpaths, watchFolders, patterns) {33 var watchPatterns;34 loadpaths.forEach(function(loadpath){35 // If loadpath is just a single file, we should just watch that file36 stats = fs.statSync(loadpath);37 if (stats.isFile()) {38 watchPatterns = loadpath;39 } else {40 watchPatterns = patterns.map(function(p) { 41 return path.join(loadpath, p);42 });43 }44 changedFunc = function(event, file) {45 console.log(file + ' was changed');46 var match = path.basename(file, path.extname(file)) + ".*";47 match = match.replace(new RegExp("spec", "i"), "");48 var argv = [].concat(baseArgv, ["--match", match]);49 run_external(argv.shift(), argv, function(code) {50 // run everything if we fixed some bugs51 if(code == 0) {52 if(!last_run_succesful) {53 run_everything();54 }55 last_run_succesful = true;56 } else {57 last_run_succesful = false;58 }59 });60 }61 // Vim seems to change a file multiple times, with non-scientific testing62 // the only time we didn't duplicate the call to onChanged was at 2.5s63 // Passing true to have onChanged run on the leading edge of the timeout64 var onChanged = _.debounce(changedFunc, 2500, true);65 gaze(watchPatterns, function(err, watcher) {66 // Get all watched files67 console.log("Watching for changes in " + loadpath);68 // On file changed69 this.on('all', onChanged);70 });71 });72 watchFolders.forEach(function(watchPath) {73 // If watchPath is just a single file, we should just watch that file74 stats = fs.statSync(watchPath);75 if (stats.isFile()) {76 watchPatterns = watchPath;77 } else {78 watchPatterns = patterns.map(function(p) {79 return path.join(watchPath, p);80 });81 }82 // We debounce run_everything here due to the Vim issue described above.83 var onChanged = _.debounce(run_everything, 2500, true);84 85 gaze(watchPatterns, function(err, watcher) {86 console.log("Watching for changes in " + watchPath);87 this.on('all', onChanged);88 });89 90 91 });92 run_everything();...
sass.js
Source:sass.js
1var glob = require('gulp-sass-glob');2var civicrmScssRoot = require('civicrm-scssroot')();3var gulp = require('gulp');4var path = require('path');5var sass = require('gulp-sass');6var stripCssComments = require('gulp-strip-css-comments');7var utils = require('../utils');8module.exports = [9 {10 name: 'sass',11 fn: function (cb) {12 var sequence;13 if (utils.canCurrentExtensionRun('sass')) {14 sequence = utils.addExtensionCustomTasksToSequence([15 utils.spawnTaskForExtension('sass:sync', syncTask),16 utils.spawnTaskForExtension('sass:main', mainTask)17 ], 'sass');18 gulp.series(sequence)(cb);19 } else {20 console.log('Not eligible for this task, skipping...');21 cb();22 }23 }24 },25 {26 name: 'sass:watch',27 fn: function (cb) {28 var extPath, watchPatterns;29 if (utils.canCurrentExtensionRun('sass')) {30 extPath = utils.getExtensionPath();31 watchPatterns = utils.addExtensionCustomWatchPatternsToDefaultList([32 path.join(extPath, 'scss/**/*.scss')33 ], 'sass');34 gulp.watch(watchPatterns, gulp.parallel('sass'));35 cb();36 } else {37 console.log('Not eligible for this task, skipping...');38 cb();39 }40 }41 }42];43/**44 * Compiles SASS files45 *46 * @param {Function} cb47 * @return {Vinyl}48 */49function mainTask (cb) {50 var extPath = utils.getExtensionPath();51 return gulp.src(path.join(extPath, '/scss/*.scss'))52 .pipe(glob())53 .pipe(sass({54 outputStyle: 'compressed',55 includePaths: civicrmScssRoot.getPath(),56 precision: 1057 }).on('error', function (err) {58 sass.logError.call(this, err);59 process.exit(1);60 }))61 .pipe(stripCssComments({ preserve: false }))62 .pipe(gulp.dest(path.join(extPath, 'css')));63}64/**65 * Syncs the SASS cache66 *67 * @param {Function} cb68 */69function syncTask (cb) {70 civicrmScssRoot.updateSync();71 cb();...
livereloadServer.js
Source:livereloadServer.js
1var path = require('path');2var colors = require('colors');3var $q = require('q');4var ip = require('ip');5var livereload = require('livereload');6var defaultLivereloadPort = 35729;7module.exports = createLiveReloadServer;8function createLiveReloadServer(data, port) {9 var _port = port || defaultLivereloadPort;10 var d = $q.defer();11 startupLivereloadServer(_port).then(function(res) {12 console.info(colors.green('Running live reload server:') + ' http://' + ip.address() + ':' + res.port);13 res.server.watch(data.watchPatterns);14 if (data.watchPatterns && data.watchPatterns.length > 0) {15 var result = showWatchPatterns(data.watchPatterns);16 }17 d.resolve(res.port);18 }, function(p) {19 var newPort = p + 1;20 console.log(colors.green(p + ' has been occupied,use ' + newPort + ' instead.'));21 createLiveReloadServer(data, newPort).then(function(port) {22 d.resolve(port);23 });24 });25 return d.promise;26}27function startupLivereloadServer(port) {28 var d = $q.defer();29 var server = livereload.createServer({30 port: port31 });32 server.server.on('error', function(error) {33 var errorInfo = error.toString();34 if (errorInfo.indexOf('Error: listen EADDRINUSE') > -1) {35 //listen error36 d.reject(port);37 } else {38 //other error39 console.log(colors.red(error));40 process.exit();41 }42 });43 server.server.on('listening', function() {44 var data = {45 server: server,46 port: port47 }48 d.resolve(data);49 });50 return d.promise;51}52function showWatchPatterns(taskArr) {53 var str = [];54 for (var i = 0; i < taskArr.length; i++) {55 str.push(i + ' = ' + taskArr[i]);56 }57 console.log(colors.green('Watching::') + colors.white(str.join(', ')));...
test.js
Source:test.js
1var gulp = require('gulp');2var path = require('path');3var test = require('../test');4var utils = require('../utils');5module.exports = [6 {7 name: 'test',8 fn: function (cb) {9 var sequence;10 if (utils.canCurrentExtensionRun('test')) {11 sequence = utils.addExtensionCustomTasksToSequence([12 utils.spawnTaskForExtension('test:main', mainTask)13 ], 'test');14 gulp.series(sequence)(cb);15 } else {16 console.log('Not eligible for this task, skipping...');17 cb();18 }19 }20 },21 {22 name: 'test:watch',23 fn: function (cb) {24 var testFolderPath, watchPatterns;25 if (utils.canCurrentExtensionRun('test')) {26 testFolderPath = path.join(utils.getExtensionPath(), 'js/test');27 watchPatterns = utils.addExtensionCustomWatchPatternsToDefaultList([28 path.join(testFolderPath, '**/*.spec.js'),29 '!' + path.join(testFolderPath, 'test/mocks/**/*.js'),30 '!' + path.join(testFolderPath, 'test/test-main.js')31 ], 'test');32 gulp.watch(watchPatterns).on('change', function (filePath) {33 test.single(filePath);34 });35 cb();36 } else {37 console.log('Not eligible for this task, skipping...');38 cb();39 }40 }41 }42];43/**44 * Runs all the JS unit tests of the extension45 */46function mainTask (cb) {47 test.all(cb);...
Using AI Code Generation
1var path = require('path');2var glob = require('glob');3module.exports = function (config) {4 config.set({5 preprocessors: {6 },7 webpack: {8 module: {9 {10 }11 }12 },13 path.join(__dirname, 'test', '**', '*.js'),14 path.join(__dirname, 'src', '**', '*.js')15 });16};17module.exports = function (config) {18 config.set({19 preprocessors: {20 },21 webpack: {22 module: {23 {24 }25 }26 },27 path.join(__dirname, 'test', '**', '*.js'),28 path.join(__dirname, 'src', '**', '*.js')29 });30};31module.exports = function (config) {32 config.set({33 preprocessors: {34 },35 webpack: {36 module: {37 {
Using AI Code Generation
1module.exports = function(config) {2 config.set({3 });4};5module.exports = function(config) {6 config.set({7 });8};9module.exports = (config) ->10module.exports = (config) => {11 config.set({12 });13};14module.exports = function(config) {15 config.set({16 });17};18module.exports = (config) => {19 config.set({20 });21};22module.exports = (config) ->23module.exports = function(config) {24 config.set({
Using AI Code Generation
1module.exports = function(config) {2 config.set({3 preprocessors: {4 },5 coverageReporter: {6 },7 })8}9module.exports = function(config) {10 config.set({
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!