How to Build Runnable JavaScript Specifications

How to Build Runnable JavaScript Specifications

Programming is not only about giving the computer instructions about how to accomplish a task, it’s also about communicating ideas in a precise way with other people, or even to your future self. Such communication can have multiple goals, maybe to share information or just to allow easier modifications—it’s hard to change something if you don’t understand it or if you don’t remember what you did long time ago. Documentation is key, either as simple comments in your code or as whole documents describing the overall functionality of a program.

Programming is not only about giving the computer instructions about how to accomplish a task, it’s also about communicating ideas in a precise way with other people, or even to your future self. Such communication can have multiple goals, maybe to share information or just to allow easier modifications—it’s hard to change something if you don’t understand it or if you don’t remember what you did long time ago. Documentation is key, either as simple comments in your code or as whole documents describing the overall functionality of a program.

When we write software we also need to make sure that the code has the intended functionality. While there are formal methods to define semantics, the easiest and quickest (but less rigorous) way is to put that functionality into use and see if it produces the expected results.

Most developers are familiar with these practices: code documentation as comments to make explicit the goal of a block of code, and a series of tests to make sure functions give the desired output.

But usually the documentation and testing is done in different steps, and by unifying these practices, we can offer a better experience for anyone involved in the development of a project. This article explores as simple implementation of a program to run JavaScript specifications that work for both documentation and testing.

We are going to build a command-line interface that finds all the specification files in a directory, extracts all the assertions found inside each specification and evaluates their result, finally showing the results of which assertions failed and which ones passed.

The Specification Format

Each specification file will export a single string from a template literal. The first line can be taken as the title of the specification. The template literal will allow us to embed JS expressions between the string and each expression will represent an assertion. To identify each assertion we can start the line with a distinctive character, in this case, we can use the combination of the bar character (|) and a dash (-), which resembles a turnstile symbol that can sometimes be found as a symbolic representation for logical assertions.

The following is an example with some explanations of its use:

const dependency = require('./dependency')

module.exports = `
  Example of a Specification File

  This project allows to test JavaScript programs using specification files.
  Every *.spec.js file exports a single template literal that includes a general
  explanation of the file being specified. Each file represents a logical
  component of a bigger system. Each logical component is composed of several
  units of functionality that can be tested for certain properties.
  Each one of this units of functionality may have one or more
  assertions. Each assertion is denoted by a line as the following:

  |- ${dependency} The dependency has been loaded and the first assert has
  been evaluated.

  Multiple assertions can be made for each file:

  |- ${false} This assertion will fail.

  |- ${2 + 2 === 4} This assertion will succeed.

  The combination of | and - will form a Turnstile ligature (|-) using the appropriate
  font. Fira Code is recommended. A Turnstile symbol was used by Gottlob Frege
  at the start of sentenses being asserted as true.

  The intended usage is for specification-first software. Where the programmer
  defines the high level structure of a program in terms of a specification,
  then progressively builds the parts conforming that specification until all
  the tests are passed. A desired side-effect is having a simple way to generate
  up-to-date documentation outside the code for API consumers.
`

Now let’s proceed with the high level structure of our program.

The Structure of Our Program

The whole structure of our program can be defined in a few lines of code, and without any dependencies other than two Node.js libraries to work with the filesystem (fs) and directory paths (path). In this section we define just the structure of our program, function definitions will come in the next sections.

#!/usr/bin/env node

const fs = require('fs')
const path = require('path')

const specRegExp = /\.spec\.js$/
const target = path.join(process.cwd(), process.argv[2])

// Get all the specification file paths
// If a specification file is provided then just test that file
// Otherwise find all the specification files in the target directory
const paths = specRegExp.test(target)
  ? [ target ]
  : findSpecifications(target, specRegExp).filter(x => x)

// Get the content of each specification file
// Get the assertions of each specification file
const assertionGroups = getAssertions(getSpecifications(paths))

// Log all the assertions
logAssertions(assertionGroups)

// Check for any failed assertions and return an appropriate exit code
process.exitCode = checkAssertions(assertionGroups)

Because this is also the entry point of our CLI (command-line interface), we need to add the first line, the shebang, that indicates that this file should be executed by the node program. There is no need to add a specific library to handle the command options, since we are only interested in a single parameter. However, you may consider other options if you plan to extend this program in a considerable manner.

To get the target testing file or directory, we have to join the path where the command was executed (using process.cwd()) with the argument provided by the user as the first argument when executing the command (using process.argv[2]). You can find a reference to these values in the Node.js documentation for the process object. In this way we obtain the absolute path of the target directory/file.

Now, the first thing that we have to do is to find all the JavaScript specification files. As seen in line 12, we can use the conditional operator to provide more flexibility: if the user provides a specification file as the target then we just use that file path directly, otherwise, if the user provides a directory path then we have to find all the files that match our pattern as defined by the specRegExp constant, we do this using a findSpecifications function that we will define later. This function will return an array of paths for each specification file in the target directory. Note the filter(x=> x) function at the end, this will filter any empty strings that our findSpecifications() function might return.

In line 18 we are defining the assertionGroups constant as the result of combining two functions getSpecifications() and getAssertions(). First we get the content of each specification file and then we extract the assertions from them. We will define those two functions later, for now just note that we use the output of the first function as the parameter of the second one, thus simplifying the procedure and making a direct connection between those two functions. While we could have just one function, by splitting them, we can get a better overview of what is the actual process, remember that a program should be clear to understand; just making it work is not enough.

The structure of the assertionsGroup constant would be as follows:

assertionGroup[specification][assertion]

Next, we log all those assertions to the user as a way to report the results using a logAssertions() function. Each assertion will contain the result (true or false) and a small description, we can use that information to give a special color for each type of result.

Finally, we define the exit code depending on the results of the assertions. This gives the process information about how the program ended: was the process successful or something failed?. An exit code of 0 means that the process exited successfully, or 1 if something failed, or in our case, when at least one assertion failed.

Finding All the Specification Files

To find all the JavaScript specification files we can use a recursive function that traverses the directory indicated by the user as a parameter to the CLI. While we search, each file should be checked with the regular expression that we defined at the beginning of the program (/\.spec\.js$/), which is going to match all file paths ending with .spec.js.

function findSpecifications (dir, matchPattern, fileList = []) {
  fs.readdirSync(dir).forEach(file => {
    const filePath = path.join(dir, file) // Get the full path

    fileList = fs.statSync(filePath).isDirectory() // Check if we are in a directory then
      ? findSpecifications(filePath, matchPattern, fileList) // Continue the recursion
      : fileList.concat(matchPattern.test(filePath) ? filePath : '') // Otherwise check if the file matches the pattern
  })

  return fileList // Return the list of found files
}

Our findSpecifications function takes a target directory (dir), a regular expression that identifies the specification file (matchPattern) and an array (fileList) that stores the found files.

Getting the Contents of Each Specification

Since we are exporting template literals, getting the content and the evaluated assertions is simple, we have to import each file and when it gets imported all the assertions get evaluated automatically.

function getSpecifications (paths) {
  return paths.map(path => require(path))
}

Using the map() function we replace the path of the array with the content of the file using the node’s require function.

Extracting the Assertions from the Text

At this point we have an array with the contents of each specification file and their assertions already evaluated. We use the turnstile indicator (|-) to find all those assertions and extract them.

function getAssertions (specifications) {
  return specifications.map(specification => ({
    title: specification.split('\n\n', 1)[0].trim(),
    assertions: specification.match(/^( |\t)*(\|-)(.|\n)*?\./gm).map(assertion => {
      const assertionFragments = /(?:\|-) (\w*) ((?:.|\n)*)/.exec(assertion)

      return {
        value: assertionFragments[1],
        description: assertionFragments[2].replace(/\n /, '')
      }
    })
  }))
}

This function will return a similar array, but replacing the content of each specification with an object following this structure:

{
  title: <String: Name of this particular specification>,
  assertions: [
    {
      value: <Boolean: The result of the assertion>,
      description: <String: The short description for the assertion>
    }
  ]
}

The title is set with the first line of the specification string. Then each assertion is stored as an array in the assertions key. The value represents the result of the assertion as a Boolean. We will use this value to know if the assertion was successful or not. Also, the description will be shown to the user as a way to identify which assertions succeeded and which ones failed. We use regular expressions in each case.

Logging Results

The array that we have built along the program now has a series of JavaScript specification files containing a list of found assertions with their result and description, so there is not much to do other than reporting the results to the user.

function logAssertions(assertionGroups) {
  // Methods to log text with colors
  const ansiColor = {
    blue: text => console.log(`\x1b[1m\x1b[34m${text}\x1b[39m\x1b[22m`),
    green: text => console.log(`\x1b[32m    ${text}\x1b[39m`),
    red: text => console.log(`\x1b[31m    ${text}\x1b[39m`)
  }

  // Log the results
  assertionGroups.forEach(group => {
    ansiColor.blue(group.title)

    group.assertions.forEach(assertion => {
      assertion.value === 'true'
        ? ansiColor.green(assertion.description)
        : ansiColor.red(assertion.description)
    })
  })

  console.log('\n')
}

We can format our input with colors depending on the results. To show colors on the terminal we need to add ANSI escape codes. To simplify their usage in the next block we have saved each color as methods of an ansiColor object.

First we want to show the title of the specification, remember that we are using the first dimension of the array for each specification, which we have named it as a group (of assertions.) Then we log all the assertions depending on their value using their respective color: green for assertions that evaluated as true and red for assertions that had another value. Note the comparison, we are checking for true, as a string, since we are receiving strings from each file.

Checking Results

Finally, the last step is to check if all the tests were successful or not.

function checkAssertions (assertionGroups) {
  return assertionGroups.some(
    group => group.assertions.some(assertion => assertion.value === 'false')
  ) ? 1 : 0
}

We check every assertion group (specification) to see if at least one value is '``false``' using the some() method of Array. We have nested two of them because we have a two dimensional array.

Running Our Program

At this point our CLI should be ready to run some JavaScript specifications and see if assertions are picked up and evaluated. In a test directory you can copy the specification example from the beginning of this article, and paste the following command inside your package.json file:

"scripts": {
  "test": "node index.js test"
}

… where test is the name of the directory where you have included the sample specification file.

When running the npm test command, you should see the results with their respective colors.

Last Words

We have implemented a very simple but useful command-line program that can help us to make better software. There are some lessons that we can gain from this:

  • Software can be simple and useful at the same time.
  • We can build our own tools if we want something different, there is no reason to conform.
  • Software is more than “making it work” but also about communicating ideas.
  • Some times we can improve something just by changing the point of view. In this case, the format of the specification files: just a simple string!

An example workflow for this program, would be to place one .spec.js file per module in your projects, describing in detail the intended functionality and properties that the program should have in form of assertions. You can sketch the idea of a new project in this way, and continuously improve until all the assertions have passed.

You can find the source code used in this article here.

Originally published on https://www.sitepoint.com

JavaScript Tutorial: if-else Statement in JavaScript

JavaScript Tutorial: if-else Statement in JavaScript

This JavaScript tutorial is a step by step guide on JavaScript If Else Statements. Learn how to use If Else in javascript and also JavaScript If Else Statements. if-else Statement in JavaScript. JavaScript's conditional statements: if; if-else; nested-if; if-else-if. These statements allow you to control the flow of your program's execution based upon conditions known only during run time.

Decision Making in programming is similar to decision making in real life. In programming also we face some situations where we want a certain block of code to be executed when some condition is fulfilled.
A programming language uses control statements to control the flow of execution of the program based on certain conditions. These are used to cause the flow of execution to advance and branch based on changes to the state of a program.

JavaScript’s conditional statements:

  • if
  • if-else
  • nested-if
  • if-else-if

These statements allow you to control the flow of your program’s execution based upon conditions known only during run time.

  • if: if statement is the most simple decision making statement. It is used to decide whether a certain statement or block of statements will be executed or not i.e if a certain condition is true then a block of statement is executed otherwise not.
    Syntax:
if(condition) 
{
   // Statements to execute if
   // condition is true
}

Here, condition after evaluation will be either true or false. if statement accepts boolean values – if the value is true then it will execute the block of statements under it.
If we do not provide the curly braces ‘{‘ and ‘}’ after if( condition ) then by default if statement will consider the immediate one statement to be inside its block. For example,

if(condition)
   statement1;
   statement2;

// Here if the condition is true, if block 
// will consider only statement1 to be inside 
// its block.

Flow chart:

Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate If statement 

var i = 10; 

if (i > 15) 
document.write("10 is less than 15"); 

// This statement will be executed 
// as if considers one statement by default 
document.write("I am Not in if"); 

< /script> 

Output:

I am Not in if
  • if-else: The if statement alone tells us that if a condition is true it will execute a block of statements and if the condition is false it won’t. But what if we want to do something else if the condition is false. Here comes the else statement. We can use the else statement with if statement to execute a block of code when the condition is false.
    Syntax:
if (condition)
{
    // Executes this block if
    // condition is true
}
else
{
    // Executes this block if
    // condition is false
}


Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate If-else statement 

var i = 10; 

if (i < 15) 
document.write("10 is less than 15"); 
else
document.write("I am Not in if"); 

< /script> 

Output:

i is smaller than 15
  • nested-if A nested if is an if statement that is the target of another if or else. Nested if statements means an if statement inside an if statement. Yes, JavaScript allows us to nest if statements within if statements. i.e, we can place an if statement inside another if statement.
    Syntax:
if (condition1) 
{
   // Executes when condition1 is true
   if (condition2) 
   {
      // Executes when condition2 is true
   }
}

Example:

<script type = "text/javaScript"> 

// JavaScript program to illustrate nested-if statement 

var i = 10; 

if (i == 10) { 

// First if statement 
if (i < 15) 
	document.write("i is smaller than 15"); 

// Nested - if statement 
// Will only be executed if statement above 
// it is true 
if (i < 12) 
	document.write("i is smaller than 12 too"); 
else
	document.write("i is greater than 15"); 
} 
< /script> 

Output:

i is smaller than 15
i is smaller than 12 too
  • if-else-if ladder Here, a user can decide among multiple options.The if statements are executed from the top down. As soon as one of the conditions controlling the if is true, the statement associated with that if is executed, and the rest of the ladder is bypassed. If none of the conditions is true, then the final else statement will be executed.
if (condition)
    statement;
else if (condition)
    statement;
.
.
else
    statement;


Example:

<script type = "text/javaScript"> 
// JavaScript program to illustrate nested-if statement 

var i = 20; 

if (i == 10) 
document.wrte("i is 10"); 
else if (i == 15) 
document.wrte("i is 15"); 
else if (i == 20) 
document.wrte("i is 20"); 
else
document.wrte("i is not present"); 
< /script> 

Output:

i is 20

How to Retrieve full Profile of LinkedIn User using Javascript

How to Retrieve full Profile of LinkedIn User using Javascript

I am trying to retrieve the full profile (especially job history and educational qualifications) of a linkedin user via the Javascript (Fetch LinkedIn Data Using JavaScript)

Here we are fetching LinkedIn data like Username, Email and other fields using JavaScript SDK.

Here we have 2 workarounds.

  1. Configuration of linkedIn developer api
  2. Javascript Code to fetch records

Configuration of linkedIn developer api

In order to fetch records, first we need to create developer api in linkedin which will act as token/identity while fetching data from other linkedin accounts.

So to create api, navigate to https://linkedin.com/developer/apps and click on 'Create Application'.

After navigating, fill in details like name, description and other required fields and then submit.

As we submit, it will create Client ID and Client Secret shown below, which we will be using in our code while communicating to fetch records from other LinkedIn account.

Note: We need to provide localhost Url here under Oauth 2.0. I am using my localhost, but you can probably use other production URLs under Oauth 2.0 where your app is configured. It will make your api  consider the Url as trusted which fetching records.

Javascript Code to fetch records

For getting user details like first name, last name,User image can be written as,

<script type="text/javascript" src="https://platform.linkedin.com/in.js">  
    api_key: XXXXXXX //Client ID  
    onLoad: OnLinkedInFrameworkLoad //Method that will be called on page load  
    authorize: true  
</script>  
<script type="text/javascript">  
    function OnLinkedInFrameworkLoad() {  
        IN.Event.on(IN, "auth", OnLinkedInAuth);  
    }  
  
    function OnLinkedInAuth() {  
        IN.API.Profile("me").result(ShowProfileData);  
    }  
  
    function ShowProfileData(profiles) {  
        var member = profiles.values[0];  
        var id = member.id;  
        var firstName = member.firstName;  
        var lastName = member.lastName;  
        var photo = member.pictureUrl;  
        var headline = member.headline;  
        //use information captured above  
        var stringToBind = "<p>First Name: " + firstName + " <p/><p> Last Name: " + lastName + "<p/><p>User ID: " + id + " and Head Line Provided: " + headline + "<p/>"  
        document.getElementById('profiles').innerHTML = stringToBind;  
    }  
</script>    

Kindly note we need to include 'https://platform.linkedin.com/in.js' as src under script type as it will act on this Javascript SDK provided by Linkedin.

In the same way we can also fetch records of any organization with the companyid as keyword.

<head>  
    <script type="text/javascript" src="https://platform.linkedin.com/in.js">  
        api_key: XXXXXXX ////Client ID  
        onLoad: onLinkedInLoad  
        authorize: true  
    </script>  
</head>  
  
<body>  
    <div id="displayUpdates"></div>  
    <script type="text/javascript">  
        function onLinkedInLoad() {  
            IN.Event.on(IN, "auth", onLinkedInAuth);  
            console.log("On auth");  
        }  
  
        function onLinkedInAuth() {  
            var cpnyID = XXXXX; //the Company ID for which we want updates  
            IN.API.Raw("/companies/" + cpnyID + "/updates?event-type=status-update&start=0&count=10&format=json").result(displayCompanyUpdates);  
            console.log("After auth");  
        }  
  
        function displayCompanyUpdates(result) {  
            var div = document.getElementById("displayUpdates");  
            var el = "<ul>";  
            var resValues = result.values;  
            for (var i in resValues) {  
                var share = resValues[i].updateContent.companyStatusUpdate.share;  
                var isContent = share.content;  
                var isTitled = isContent,  
                    isLinked = isContent,  
                    isDescription = isContent,  
                    isThumbnail = isContent,  
                    isComment = isContent;  
                if (isTitled) {  
                    var title = isContent.title;  
                } else {  
                    var title = "News headline";  
                }  
                var comment = share.comment;  
                if (isLinked) {  
                    var link = isContent.shortenedUrl;  
                } else {  
                    var link = "#";  
                }  
                if (isDescription) {  
                    var description = isContent.description;  
                } else {  
                    var description = "No description";  
                }  
                /* 
                if (isThumbnailz) { 
                var thumbnailUrl = isContent.thumbnailUrl; 
                } else { 
                var thumbnailUrl = "http://placehold.it/60x60"; 
                } 
                */  
                if (share) {  
                    var content = "<a target='_blank' href=" + link + ">" + comment + "</a><br>";  
                    //el += "<li><img src='" + thumbnailUrl + "' alt=''>" + content + "</li>";  
                    el += "<li><div>" + content + "</div></li>";  
                }  
                console.log(share);  
            }  
            el += "</ul>";  
            document.getElementById("displayUpdates").innerHTML = el;  
        }  
    </script>  
</body>  

We can get multiple metadata while fetching records for any any organization. We can get company updates as shown below.

Conclusion

We can also fetch any company specific data like company job updates/post, total likes, comments, and number of views along with a lot of metadata we can fetch which I have shown below.

Thank you for reading !

7 Best Javascript Iframe Libraries

7 Best Javascript Iframe Libraries

Iframes let you build user experiences into embeddable ‘cross-domain components’, which let users interact with other sites without being redirected. I have compiled 7 best Javascript iframe libraries.

Iframes let you build user experiences into embeddable ‘cross-domain components’, which let users interact with other sites without being redirected. I have compiled 7 best Javascript iframe libraries.

1. Zoid

A cross-domain component toolkit, supporting:

  • Render an iframe or popup on a different domain, and pass down props, including objects and functions
  • Call callbacks natively from the child window without worrying about post-messaging or cross-domain restrictions
  • Create and expose components to share functionality from your site to others!
  • Render your component directly as a React, Vue or Angular component!
    It's 'data-down, actions up' style components, but 100% cross-domain using iframes and popups!

Download


2. Postmate

Postmate is a promise-based API built on postMessage. It allows a parent page to speak with a child iFrame across origins with minimal effort.

Download


3. Iframe Resizer

Keep same and cross domain iFrames sized to their content with support for window/content resizing, in page links, nesting and multiple iFrames

Demo

Download


4. Iframely

Embed proxy. Supports over 1800 domains via custom parsers, oEmbed, Twitter Cards and Open Graph

Demo

Download


5. React Frame component

This component allows you to encapsulate your entire React application or per component in an iFrame.

Demo

Download


6. Seamless.js

A seamless iframe makes it so that visitors are unable to distinguish between content within the iframe and content beside the iframe. Seamless.js is a JavaScript library (with no dependencies) that makes working with iframes easy by doing all the seamless stuff for you automatically.

Demo

Download


7. Porthole

A proxy to safely communicate to cross-domain iframes in javascript

Demo

Download


Thank for read!