5
\$\begingroup\$

I've made this developer-tool for my own use. Perhaps for colleagues too.

Currently I'm thinking about enhancing it. So that different data-types could be chosen.

But before that I like it to be reviewed.

Therefore: Any hints and suggestions concerning algorithm, design, user-interface, whatever welcomed.

var textArea = document.querySelector('textarea');
var exec     = document.querySelector('#exec');
var countOfStrings = document.querySelector('#count-strings');
var linebreak = document.querySelector('#linebreak');
var arrayName = document.querySelector('#array-name');
var maxSelect = document.querySelector('#max');
var separator = document.querySelector('#separator');
// Set of arbitrary words.
var words = [ 'red', 'blue', 'green', 'orange',  
              'yellow', 'white', 'black', 
              'pink', 'cyan', 'crimson',
              'teal', 'lime', 'Alpha', 'Beta', 
              'Gamma', 'Delta', 'North', 
              'East', 'South', 'West' ];
// Create the options of the select-input.
(function() {
  var options = '';
  var currentNumber;
  var i;
  const max = 5;

  for (i = 0; i <= max; i++) {
    currentNumber = Math.pow(10, i);
    options += '<option value="' + currentNumber + '"';

    if (i === 3) {
      options += 'selected="selected" ';
    }

    options += '>' + currentNumber + '</option>\n';
  }

  countOfStrings.innerHTML = options;
})();

/* Creates a stringified array. This array contains 
 *  strings as elements. Each string is made out
 *  of one or multiple random-words.
 *
 * @param { array } words - An array with strings. 
 * @param { number } countOfStrings - Count of strings
 *  within the array.
 * @min { number } [min = 1] - Minimal count of random-words. 
 * @max { number } [max = 1] - Maximal count of random-words. 
 * @param { string } [separator = '-'] - Separator between the
 *  random-words.
 * @param { boolean } [linebreak = false] - Add a linebreak
 *  after each element.
 * @param { string } [arrayName = 'testData'] - The name to the 
 *  returned array.
 * 
 * @returns { string } - Stringified array in case of success. 
 *  Empty string in case of failure.
 */
function getArrayWithTestStrings( words, countOfStrings, min, max, 
                                  separator, linebreak, arrayName ) {
  var ret = [];
  var i;
  // -- Helper-functions -------
  var checkIfNumber = function(num) {
      return typeof num === 'number' && !isNaN(num);
  }

  var getTestStrings = function() {
    var size = Math.floor(min + (Math.random() * (max + 1 - min)));
    var ret = '';
    var i;

    for (i = 0; i < size; i++) {
      ret += words[Math.floor(Math.random() * words.length)] +
        separator;
    }

    return ret.slice(0, ret.length - 1);
  }
  // -- Param-checks ------------
  if ( !words || !Array.isArray(words) || !words.length ) {
    return '';
  }

  if (!countOfStrings || !checkIfNumber(countOfStrings)) {
    return '';
  }
  
  if (!min) {
    min = 1;
  } else if (!checkIfNumber(min)) {
    return '';
  }
  
  if (!max) {
    max = 1;
  } else if (!checkIfNumber(max)) {
    return '';
  }

  arrayName = arrayName || 'testData';
  min = min || 1;
  max = max || 1;
  separator = separator || '-';
  // -- Assemble the array ------- 
  ret = 'var ' + arrayName + ' = [';

  for (i = 0; i < countOfStrings; i++) {
    ret += '"' + getTestStrings() + '",';

    (linebreak && i < countOfStrings - 1) ? 
      ret += '\n' :
      ret += ' ';
  }

  ret = ret.slice(0, ret.length - 2);
  ret += '];';

  return ret;
}

exec.addEventListener('click', function() {
  textArea.textContent =
    getArrayWithTestStrings( words, 
                           parseInt(countOfStrings.value), 
                           1, 
                           parseInt(maxSelect.value), 
                           separator.value, 
                           linebreak.checked, 
                           arrayName.value );
  textArea.select();
});

// -- From here on everything is just an 
//  usage-example! ---------------------

function transferString ( someString ) {
  var ret = someString.replace(/-/g, '_'); 
  return ret.toUpperCase();
}
// Real testing is done with much larger arrays.
var firstParam = ["pink-cyan-pink-crimson",
"North-orange-crimson-black-Beta-yellow",
"Delta-Beta-Alpha-blue-red-Alpha",
"Beta-Delta-North-Beta-cyan-yellow",
"white-Beta-black",
"teal-Gamma-North-pink",
"blue",
"Beta-Delta-lime-Beta-orange",
"orange-orange-cyan-cyan",
"South-white-South"];

var startDate = Date.now();

firstParam.forEach(function(item, i) {
  item = transferString(item);

  if (/-|[a-z]/.test(item)) {
    console.error('Test %s failed.', i);
    console.error(item);
  } else {
  	console.log('Test %s succeeded.', i);
    console.log(item);
  }
});

console.log( 'Time needed to process the array: %s ms', 
	         Date.now() - startDate );
body {
  background-color: #f0f0f0; }

.wrap {
  max-width: 1000px;
  margin: 2% auto; }

.input-group label {
  display: inline-block; }

.input-group {
  margin-bottom: 2%;
  background-color: #fafafa;
  border-radius: 10px;
  padding: 10px 10px;
  display: flex;
  justify-content: space-around; }

.input-group-part {
  width: 45%; }

textarea {
  width: 100%;
  min-height: 80px; }

.input-group button {
  font-weight: bold;
  border-radius: 2px;
  padding: 5px 5px; }

@media screen and (max-width: 800px) {
  .input-group {
    display: block; }

  .input-group-part {
    width: 100%; }

  .input-group-part:first-of-type {
    margin-bottom: 4%; }

  .input-group label {
    width: 45%; }

  #exec {
    margin-left: 47%; } }
<div class="wrap">
  <div class="input-group">
    <textarea></textarea>
  </div>

  <div class="input-group">
    <div class="input-group-part">
      <label for="array-name">Name of array: </label>
      <input type="text" id="array-name" value="testData" />
    </div>
    <div class="input-group-part">
      <label for="separator">Word-Separator: </label>
      <input type="text" id="separator" size="5" value="-" />
    </div>
  </div>

  <div class="input-group">
    <div class="input-group-part">
      <label for="count-strings">Count of strings: </label>
      <select id="count-strings" ></select>
    </div>
    <div class="input-group-part">
      <label for="max">Max. parts within string: </label>
      <select id="max">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option selected="selected">5</option>
        <option>6</option>
      </select>
    </div>
  </div>

  <div class="input-group">
    <div class="input-group-part">
      <label for="linebreak">Add a linebreak: </label>
      <input type="checkbox" id="linebreak" />
    </div>
    <div class="input-group-part">
      <button id="exec" >Execute</button>
    </div>
  </div>
</div>

Any help or advice is appreciated, thank you in advance.

\$\endgroup\$
2
\$\begingroup\$

HTML Textarea element is quite slow with very large amounts of text so you might want to use a simple yet advanced editor like CodeMirror. Even with syntax highlight enabled it's much faster than the native textarea control in the abovementioned case.

Might be useful to auto-copy the result to clipboard - add a [x] auto copy to clipboard checkbox, for example.

Showing a length of the code in characters might be useful.

<input type="search"> would automatically remember past used values in autocomplete.

The log pane on the bottom doesn't seem to be meaningful. And if it is, just showing successfully completed tests in green(-ish) color or using a green mark would be much more obvious.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.