0

I have written several unit tests recenlty and I wonder if there is a way to make html string (binding template) that appeals to directive (or component) from javascript function. Here is an example.

I have some directive and I'm testing it like this

function test($rootScope, $compile) {
    var scope = $rootScope.$new();
    var elem = $compile(angular.element(
        '<app-foo-bar attr1="val1" attr2="val2"></app-foo-bar>'
    ))(scope);
    scope.$apply();
}

Declaring an element string seems to be a little awkward especially if there is a dozen of attributes. It would be very handul for unit-testing if there is a function that generates html string from object like this.

genHtmlString('fooBar', {
    attr1: 'val1',
    attr2: 'val2'
});

And output would be of course

<app-foo-bar attr1="val1" attr2="val2"></app-foo-bar>

It seems like a common problem to me, but I can't find any angular, karma or jasmine functionality that would be helpful in writing such a function.

1 Answer 1

2

Sure you can do this, the algorithm basically would be iterate over object properties and stringify it.

First you'll have to transform the element camelcased name to dashed like. You can do it using the function bellow (that I stole from this gist, shh).

function camelCaseToDash(myStr) {
  return myStr.replace( /([a-z])([A-Z])/g, '$1-$2' ).toLowerCase();
}

Then you can iterate over each property on the object and render the attrs and finally compose it within an html tag.

The following snippet implements a simple solution with a very poor error handling and also handles only attributes, you perhaps want to implement inner content and stuff.

function camelCaseToDash(myStr) {
  return myStr.replace( /([a-z])([A-Z])/g, '$1-$2' ).toLowerCase();
}

function genHtmlString(elmName, props) {

  props = props || {};

  var
    tagName = camelCaseToDash(elmName),
    htmlString = '<' + tagName;

  Object.keys(props).map(function(key) {
    htmlString += ' ' + (camelCaseToDash(key) + '="' + props[key] + '"');
  });

  return htmlString + '></' + tagName + '>';
}

var htmlString = genHtmlString('fooBar', {
  attr1: 'val1',
  attr2: 'val2',
  A: 'b',
  b: '',
  attrWithMultipleWords: 'HORAY!'
});

console.log(htmlString);

Sign up to request clarification or add additional context in comments.

1 Comment

Easier than I thought. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.