GithubHelp home page GithubHelp logo

danielstjules / buddy.js Goto Github PK

View Code? Open in Web Editor NEW
865.0 14.0 30.0 99 KB

Magic number detection for JavaScript

License: MIT License

JavaScript 100.00%
magic-numbers javascript code-smells clean-code

buddy.js's Introduction

buddy.js

Magic number detection for javascript. Let Buddy sniff out the unnamed numerical constants in your code.

Build Status

Overview

We all know magic numbers are frowned upon as a programming practice. They may give no indication of their meaning, and when used multiple times, can result in future inconsistencies. They can expose you to the risk of typos, hinder maintenance and have an impact on readability. That's where Buddy comes in.

Buddy is a cli tool that's eager to find the magic numbers in your code. It accepts a list of paths to parse, and renders any found instances with the selected reporter. In the case of directories, they're walked recursively, and only .js files are analyzed. Any node_modules dirs are also ignored.

Since const is not widespread in JavaScript, it defaults to searching for numbers which are not the sole literal in an object expression or variable declaration. Furthermore, specific values can be ignored, such as 0 and 1, which are ignored by default.

intro-screenshot

Who's a good boy?

What are magic numbers?

Magic numbers are unnamed numerical constants, though the term can sometimes be used to refer to other literals as well. Take the following contrived example:

function getTotal(subtotal) {
  var beforeTax = subtotal + 9.99;
  return beforeTax + (beforeTax * 0.13);
}

In the above function, the meaning of the two numbers might not be clear. What is this 9.99 charge? In our case, let's say it's a shipping rate. And what about the 0.13? It's the sales tax. Buddy will highlight those two instances:

$ buddy example.js

example.js:2 | var beforeTax = subtotal + 9.99;
example.js:3 | return beforeTax + (beforeTax * 0.13);

 2 magic numbers found across 1 file

If the tax rate was used in multiple locations, it's prone to human error. And it might not be immediately clear that the 9.99 charge is a flat rate shipping cost, which can affect maintenance. So how would this be improved?

var FLAT_SHIPPING_COST = 9.99;
var SALES_TAX = 0.13;

function getTotal(subtotal) {
  var beforeTax = subtotal + FLAT_SHIPPING_COST;
  return beforeTax + (beforeTax * SALES_TAX);
}

Or, depending on your target platforms or browsers, by using the const keyword for variable declaration instead of var. While const is available in Node, you should take note of its browser compatibility for front end JavaScript.

$ buddy example.js

 No magic numbers found across 1 file

Installation

It can be installed via npm using:

npm install -g buddy.js

Also available: grunt-buddyjs, and gulp-buddy.js

Usage

Usage: buddy [options] <paths ...>

Options:

  -h, --help                             output usage information
  -V, --version                          output the version number
  -d, --detect-objects                   detect object expressions and properties
  -e, --enforce-const                    require literals to be defined using const
  -i, --ignore <numbers>                 list numbers to ignore (default: 0,1)
  -I, --disable-ignore                   disables the ignore list
  -r, --reporter [simple|detailed|json]  specify reporter to use (default: simple)
  -C, --no-color                         disables colors

If a .buddyrc file is located in the project directory, its values will be used in place of the defaults listed above. For example:

{
  "detectObjects": false,
  "enforceConst":  false,
  "ignore":        [0, 1, 2], // Use empty array to disable ignore
  "reporter":      "detailed"
}

Integration

You can easily run Buddy on your library source as part of your build. It will exit with an error code of 0 when no magic numbers were found. Otherwise it will return a positive error code, and result in a failing build. For example, with Travis CI, you can add the following two entries to your .travis.yml:

before_script:
  - "npm install -g buddy.js"

script:
  - "buddy ./path/to/src"

Reporters

For additional context, try using the detailed reporter. Or, for logging output and integration with your quality assurance process, the json reporter can be used.

detailed-reporter

Ignoring numbers

A magic number can be ignored in any of three ways:

  1. Its value is ignored using the --ignore flag
  2. The line includes the following comment buddy ignore:line
  3. The line is located between a buddy ignore:start and buddy ignore:end

Given the following example, two magic numbers exist that could be ignored:

var SECOND = 1000;
var MINUTE = 60 * SECOND;
var HOUR = 60 * MINUTE;

Using the command line option, you can run buddy with: buddy example.js --ignore 60. Or, if preferred, you can specify that the instances be ignored on a case-by-case basis:

var SECOND = 1000;
var MINUTE = 60 * SECOND; // buddy ignore:line
var HOUR = 60 * MINUTE; // buddy ignore:line

Or better yet, you can make use of directives to ignore all magic numbers within a range:

// buddy ignore:start
var SECOND = 1000;
var MINUTE = 60 * SECOND;
var HOUR = 60 * MINUTE;
// buddy ignore:end

buddy.js's People

Contributors

danielstjules avatar m-bodmer avatar pgilad avatar soyuka avatar sutt0n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

buddy.js's Issues

Ignore path

I added a local version of jQuery to my a repo, and now Buddy is failing with over 60 magic numbers found.

Is there any way to ignore a path?

Or can --ignorePath be added as a cli option?

Thank you!

0.9.0 not on npm

Hey!

The latest version of this project on GitHub is 0.9.0, but the latest version on npm is 0.8.0. Would you be able to publish it, please? Thanks!

Typescript Support

Thanks for this useful and cool package. For my project, typescript support would greatly improve impact. Is this a feature that might be implemented?

Handle first line shebang

Node allows executable scripts to use the unix shebang (#!/usr/bin/env node) convention. It seems buddy.js chokes on this, which is probably an issue with the upstream parser or the configuration thereof:

{ [SyntaxError: Unexpected character '#' (1:0)] pos: 0, loc: { line: 1, column: 0 }, raisedAt: 0 }

Buddy displays hex/octal numbers incorrectly

If you make a file with the following contents:

console.log(0x1A + 0x02);
console.log(071);

The output from Buddy is rather interesting:

$ buddy .

./test.js:1 | console.log(26 + 0x02);
./test.js:1 | console.log(0x1A + 2);
./test.js:2 | console.log(57);

3 magic numbers found across 1 file

Notice how the hex/octal numbers are converted to decimal before being logged.

Doesn't report object literal attribtues

Consider the following file:

var x = {
    statusCode: 200,
    y: function() {
        z = 100;
    }
};

Buddy doesn't report the 200 as being a magic number. Though it will report the 100.

Add the ability to ignore on a case-by-case basis

I have a case where I am converting seconds to ms. e.g.

var MS = SECONDS * 1000;

Currently, I'd have to rewrite 1000 as a const or ignore it everywhere. Instead, I'd like to be able to ignore that line with a comment.

Has no method split

I've been having an issue with buddyjs recently where in my grunt task it will error out saying something along the lines of:

Running "buddyjs:src" (buddyjs) task
[TypeError: Object
## CONTENTS OF ONE OF MY JS FILES ##
 has no method 'split']
Warning: Task "buddyjs:src" failed. Use --force to continue.

Aborted due to warnings.

Now this seems to be because its expecting a large string to split on newlines, however it's an object.

Line of code that assumes this:

lines = contents.split("\n");

The method expects contents to be a string, where in this case it seems to be the raw buffer and not a string, causing the split on newlines to fail.

Ignore comments doesn't work

Hi Daniel,

I'm using buddy.js in version 0.7.0:

./node_modules/buddy.js/bin/buddy --version

My source snippet is:

return b = Math.random() * 16, (a === 'y' ? (b & 3 | 8) : (b | 0)).toString(16); // buddy ignore: line

Calling buddy.js returns warnings:

./snippet.js:1 | return b = Math.random() * 16, (a === 'y' ? (b & 3 | 8) : (b | 0)).toString(16); // buddy ignore: line
./snippet.js:1 | return b = Math.random() * 16, (a === 'y' ? (b & 3 | 8) : (b | 0)).toString(16); // buddy ignore: line
./snippet.js:1 | return b = Math.random() * 16, (a === 'y' ? (b & 3 | 8) : (b | 0)).toString(16); // buddy ignore: line
./snippet.js:1 | return b = Math.random() * 16, (a === 'y' ? (b & 3 | 8) : (b | 0)).toString(16); // buddy ignore: line

 4 magic numbers found across 6 files

Did I miss something?

With kind regards
Marco

Report negative numbers in const

Buddy.js report negative number even though they are stored in const :

src/attachmentMappers/retailMappers.js:3  | const EMPTY_INDEX_OF = -1;

 1 magic number found across 34 files

v0.9

Unexpected token "*"

NOTE: I know nodeJS v0.11.x does not have a stable release yet, so it is not really that important I guess?

With ECMAScript 6, support for generators is added. Currently, this requires one to use the --harmony flag to run node scripts that make use of generators. There is an issue with buddy.js, because these functions are indicated by asterisk notation.

function* foo(x) {
    yield x + 1;

    var y = yield null;
    return x + y;
}

The issue is that buddy.js notices an unexpected token (the *) and shuts down by this error.

buddy binary reports wrong version number

Hi Daniel,

unfortunately buddy binary returns wrong version number if called with:

$ ./bin/buddy --version
0.0.1

Although dependencies are declared the following:

"buddy.js": "^0.2.1"

and the downloaded version contains 0.2.1 in it's own package.json.

Maybe this issue is already fixed in newer versions.

With kind regards
Marco

Add a plug-in for Grunt

This is great! Would it be possible to add a plugin for grunt to execute this at build time?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.