<commit_before>'use strict';

const Twitter = require ('twitter');

class TwitterCrawler {

	constructor (credentials) {
		if (
			!credentials || credentials.constructor.name !== 'Object' ||
			!(typeof credentials.consumerKey === 'string' && typeof credentials.consumerSecret === 'string')
		) {
			throw TwitterCrawler._exceptInvalidCredentials ();
		}

		const twitterBotCredentials = {
			consumer_key: credentials.consumerKey, consumer_secret: credentials.consumerSecret
		};

		if (credentials.bearerToken) {
			twitterBotCredentials.bearer_token = credentials.bearerToken;
		} else if (credentials.accessTokenKey && credentials.accessTokenSecret) {

			twitterBotCredentials.access_token_key = credentials.accessTokenKey;
			twitterBotCredentials.access_token_secret = credentials.accessTokenSecret;

		} else {
			throw exceptInvalidCredentials ();
		}

		this.twitterBot = new Twitter (twitterBotCredentials);
	}



	// Exceptions
	static _exceptInvalidCredentials () {
		return new Error ('Initialization failed: Invalid credentials object');
	}
	static _exceptInvalidCriteria () {
		return new Error ('Query failed: Invalid criteria object');
	}

	// Static Constants
	static get TWEET_COUNT_PER_CALL () { return 11; } /*****************************/
	static get PATH_SEARCH_TWEETS () { return 'search/tweets'; }


	// Private Methods
	_constructParams (criteria, maxId) {
		if (criteria.hashtags) {
			const q = criteria.hashtags.reduce ((queryString, currentTag) => {
				if (currentTag [0] != '#') {
					currentTag = '#' + currentTag;
				}

				return queryString ? (queryString + ' OR ' + currentTag) : currentTag;
			}, '');

			const params = { q, count: TwitterCrawler.TWEET_COUNT_PER_CALL };

			if (maxId) {
				params.max_id = maxId;
			}

			return params;
		}

		throw _exceptInvalidCriteria ();
	}

	_responseRequiresSecondaryFiltering (criteria) {
		return (
			criteria.retweetCount && criteria.retweetCount.constructor.name === 'Object' &&
			Object.keys (criteria.retweetCount).length > 0
		);
	}



	/**
	 * Public methods
	 */
	getTweets (criteria) {
		if (!criteria || criteria.constructor.name !== 'Object' || !Object.keys (criteria).length) {
			throw _exceptInvalidCriteria ();
		}

		if (this._responseRequiresSecondaryFiltering (criteria)) {
			return new Filter (
				this.twitterBot.get (
					TwitterCrawler.PATH_SEARCH_TWEETS, this._constructParams (criteria, criteria.maxId)
				), criteria
			);
		}
		
		return this.twitterBot.get (
			TwitterCrawler.PATH_SEARCH_TWEETS, this._constructParams (criteria, , criteria.maxId)
		);
	}

}

module.exports = TwitterCrawler;<commit_msg>Re-factored to correctly call static exception methods<commit_after>'use strict';

const Twitter = require ('twitter');

class TwitterCrawler {

	constructor (credentials) {
		if (
			!credentials || credentials.constructor.name !== 'Object' ||
			!(typeof credentials.consumerKey === 'string' && typeof credentials.consumerSecret === 'string')
		) {
			throw TwitterCrawler._exceptInvalidCredentials ();
		}

		const twitterBotCredentials = {
			consumer_key: credentials.consumerKey, consumer_secret: credentials.consumerSecret
		};

		if (credentials.bearerToken) {
			twitterBotCredentials.bearer_token = credentials.bearerToken;
		} else if (credentials.accessTokenKey && credentials.accessTokenSecret) {

			twitterBotCredentials.access_token_key = credentials.accessTokenKey;
			twitterBotCredentials.access_token_secret = credentials.accessTokenSecret;

		} else {
			throw TwitterCrawler._exceptInvalidCredentials ();
		}

		this.twitterBot = new Twitter (twitterBotCredentials);
	}



	// Exceptions
	static _exceptInvalidCredentials () {
		return new Error ('Initialization failed: Invalid credentials object');
	}
	static _exceptInvalidCriteria () {
		return new Error ('Query failed: Invalid criteria object');
	}
	static _exceptInvalidMaxId () {
		return new Error ('Invalid maxId field in criteria, must be a 64-bit Integer');
	}

	// Static Constants
	static get TWEET_COUNT_PER_CALL () { return 11; } /*****************************/
	static get PATH_SEARCH_TWEETS () { return 'search/tweets'; }


	// Private Methods
	_constructParams (criteria, maxId) {
		if (criteria.hashtags) {
			const q = criteria.hashtags.reduce ((queryString, currentTag) => {
				if (currentTag [0] != '#') {
					currentTag = '#' + currentTag;
				}

				return queryString ? (queryString + ' OR ' + currentTag) : currentTag;
			}, '');

			const params = { q, count: TwitterCrawler.TWEET_COUNT_PER_CALL };

			if (maxId) {
				if (maxId.constructor.name !== 'Number') {
					throw TwitterCrawler._exceptInvalidMaxId ();
				}

				params.max_id = maxId;
			}

			return params;
		}

		throw TwitterCrawler._exceptInvalidCriteria ();
	}

	_responseRequiresSecondaryFiltering (criteria) {
		return (
			criteria.retweetCount && criteria.retweetCount.constructor.name === 'Object' &&
			Object.keys (criteria.retweetCount).length > 0
		);
	}



	/**
	 * Public methods
	 */
	getTweets (criteria) {
		if (!criteria || criteria.constructor.name !== 'Object' || !Object.keys (criteria).length) {
			throw TwitterCrawler._exceptInvalidCriteria ();
		}

		if (this._responseRequiresSecondaryFiltering (criteria)) {
			return new Filter (
				this.twitterBot.get (
					TwitterCrawler.PATH_SEARCH_TWEETS, this._constructParams (criteria, criteria.maxId)
				), criteria
			);
		}
		
		return this.twitterBot.get (
			TwitterCrawler.PATH_SEARCH_TWEETS, this._constructParams (criteria, criteria.maxId)
		);
	}

}

module.exports = TwitterCrawler;
{'fraction_non_alphanumeric': 0.12655265526552656, 'fraction_numerical': 0.0018001800180018, 'mean_word_length': 4.1683720930232555, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3237142', 'n_tokens_mistral': 1921, 'n_tokens_neox': 1651, 'n_words': 339}