127

I want to confirm that a value is a decimal (or 0), so the number should be greater than or equal to zero and less than 1.

describe('percent',function(){  

  it('should be a decimal', function() {

    var percent = insights.percent; 
    expect(percent).toBeGreaterThan(0);
    expect(percent).toBeLessThan(1);

  });

});

How do I mimic " >= 0 "?

Bryce Johnson
  • 6,689
  • 6
  • 40
  • 51
  • Could be related: [Checking two boundaries with Jasmine (between matcher)](http://stackoverflow.com/questions/28732881/checking-two-boundaries-with-jasmine-between-matcher/28732882#28732882). – alecxe Feb 26 '15 at 01:31
  • 6
    Try: `expect(percent).not.toBeLessThan(0);` – jcubic Jul 15 '16 at 12:12
  • 2
    As mentioned by @Patrizio Rullo in an answer below, his matchers have been merged in. There is now a toBeGreaterThanOrEqual matcher available in Jasmine 2.6: https://jasmine.github.io/api/2.6/matchers.html#toBeGreaterThanOrEqual – Chris Parton May 22 '17 at 01:41

10 Answers10

133

I figured I should update this since the API has changed in newer versions of Jasmine. The Jasmine API now has built in functions for:

  • toBeGreaterThanOrEqual
  • toBeLessThanOrEqual

You should use these functions in preference to the advice below.

Click here for more information on the Jasmine matchers API


I know that this is an old and solved question, but I noticed that a fairly neat solution was missed. Since greater than or equal to is the inverse of the less than function, Try:

expect(percent).not.toBeLessThan(0);

In this approach, the value of percent can be returned by an async function and processed as a part of the control flow.

Andrew
  • 2,390
  • 1
  • 15
  • 9
  • 7
    This one should be accepted answer. Also: `expect(2 + 2).not.toBe(5)`, `expect(2 + 2).toBeGreaterThan(0)`, `expect(2 + 2).toBeLessThan(5)` – S Panfilov Dec 24 '15 at 05:57
  • 1
    This is dangerous, because `expect(NaN).not.toBeLessThan(0);` passes instead of failing. (`not.toBeLessThan` is only the inverse if you assume that `percent` is a Number. Otherwise, it is not the inverse.) – Kristian Hanekamp Feb 12 '18 at 11:56
  • Exactly as pointed by @KristianHanekamp the expect is not reliable as it also passes when value of 'percent' is not a Number (NaN). – Rohit Feb 20 '18 at 10:32
85

You just need to run the comparison operation first, and then check if it's truthy.

describe('percent',function(){
  it('should be a decimal',function(){

    var percent = insights.percent;

    expect(percent >= 0).toBeTruthy();
    expect(percent).toBeLessThan(1);

  });   
});
Bryce Johnson
  • 6,689
  • 6
  • 40
  • 51
  • 9
    This works, but unfortunately, the message produced by a failing ">=" test is not particularly expressive ("expected false to be truthy"). And by the way, there is no need for the test to be async (ok, just nitpicking ;). – hashchange Jul 17 '15 at 11:16
  • 2
    @hashchange With a plugin such as [jasmine2-custom-message](https://github.com/avrelian/jasmine2-custom-message), the error message can be customised: `since('expected percent to be greater than or equal to zero').expect(percent >= 0).toBeTruthy();` – TachyonVortex Aug 20 '15 at 09:41
  • @TachyonVortex Sounds interesting! I didn't know about that thing. For common comparisons like `>=`, I prefer a custom matcher because it keeps the tests uncluttered (easy enough to do, see my answer below), but for comparisons which come up less frequently, or are not expressive enough, that plugin seems to be exactly the right thing. Thanks! – hashchange Aug 20 '15 at 10:38
  • What about `expect(percent).toBeGreaterThan(-1);` xD I didn't try it – Cyril CHAPON Sep 10 '15 at 10:07
20

The current version of Jasmine supports toBeGreaterThan and toBeLessThan.

expect(myVariable).toBeGreaterThan(0);
DrMcCleod
  • 3,865
  • 1
  • 15
  • 24
8

I'm late to this but posting it just in case some one still visits this question looking for answers, I'm using Jasmine version 3.0 and as mentioned by @Patrizio Rullo you can use toBeGreaterThanOrEqual/toBeLessThanOrEqual.

It was added in version 2.5 as per release notes - https://github.com/jasmine/jasmine/blob/master/release_notes/2.5.0.md

For e.g.

expect(percent).toBeGreaterThanOrEqual(1,"This is optional expect failure message");

or

expect(percent).toBeGreaterThanOrEqual(1);
Rohit
  • 396
  • 6
  • 9
  • I think jasmine version > 2.3.4 does not execute specs in order. So if they want specs in order then they can create custom matchers but if they're okay with unordered specs then they can choose the above mentioned version. – TraxX Apr 03 '18 at 06:39
5

Somewhat strangley this isn't basic functionality

You can add a custom matcher like this:

JasmineExtensions.js

yourGlobal.addExtraMatchers = function () {
    var addMatcher = function (name, func) {
        func.name = name;
        jasmine.matchers[name] = func;
    };

    addMatcher("toBeGreaterThanOrEqualTo", function () {
                   return {
                       compare: function (actual, expected) {
                           return {
                               pass: actual >= expected
                           };
                       }
                   };
               }
    );
};

In effect you're defining a constructor for your matcher - it's a function that returns a matcher object.

Include that before you 'boot'. The basic matchers are loaded at boot time.

Your html file should look like this:

<!-- jasmine test framework-->
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>

<!-- custom matchers -->
<script type="text/javascript" src="Tests/JasmineExtensions.js"></script>
<!-- initialisation-->
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>

Then in your boot.js add the call to add the matchers after jasmine has been defined but before jasmine.getEnv(). Get env is actually a (slightly misleadingly named) setup call.

The matchers get setup in the call to setupCoreMatchers in the Env constructor.

/**
 * ## Require &amp; Instantiate
 *
 * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
 */
window.jasmine = jasmineRequire.core(jasmineRequire);
yourGlobal.addExtraMatchers();

/**
 * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
 */
jasmineRequire.html(jasmine);

/**
 * Create the Jasmine environment. This is used to run all specs in a project.
 */
var env = jasmine.getEnv();

They show another way of adding custom matchers in the sample tests, however the way it works is to recreate the matcher(s) before every single test using a beforeEach. That seems pretty horrible so I thought I'd go with this approach instead.

JonnyRaa
  • 7,559
  • 6
  • 45
  • 49
5

I have run into the same issue today, and as it turns out, it is not that difficult to add a custom matcher for it. The main advantage of a custom matcher is that it can return meaningful messages when a test fails.

So here is the code for two matchers, .toBeAtLeast() and .toBeAtMost(), in case it helps someone.

beforeEach( function () {

  // When beforeEach is called outside of a `describe` scope, the matchers are
  // available globally. See http://stackoverflow.com/a/11942151/508355

  jasmine.addMatchers( {

    toBeAtLeast: function () {
      return {
        compare: function ( actual, expected ) {
          var result = {};
          result.pass = actual >= expected;
          if ( result.pass ) {
            result.message = "Expected " + actual + " to be less than " + expected;
          } else {
            result.message = "Expected " + actual + " to be at least " + expected;
          }
          return result;
        }
      };
    },

    toBeAtMost: function () {
      return {
        compare: function ( actual, expected ) {
          var result = {};
          result.pass = actual <= expected;
          if ( result.pass ) {
            result.message = "Expected " + actual + " to be greater than " + expected;
          } else {
            result.message = "Expected " + actual + " to be at most " + expected;
          }
          return result;
        }
      };
    }

  } );

} );
hashchange
  • 7,029
  • 1
  • 45
  • 41
4

It was just merged in the Jasmine GitHub master branch my patch to add the matchers you need:

Add toBeGreatThanOrEqual and toBeLessThanOrEqual matchers

But I have no idea in which release it will be. In the while, you can try to use the code of my commit in your local Jasmine copy.

Patrizio Rullo
  • 491
  • 1
  • 4
  • 13
4

Using This Updated Formula:

toBeGreaterThanOrEqual toBeLessThanOrEqual

Should Work!

1

I recommend use this Jasmine pluging: https://github.com/JamieMason/Jasmine-Matchers

Broda Noel
  • 1,760
  • 1
  • 19
  • 38
1

You can use the function least to check if a value is greater than or equal to some other value.

An alias of least is gte (great than or equal to). Vice versa, you can use lte (less than or equal to) to check the opposite.

So, to answer the question, you can do:

expect(percent).to.be.gte(0)

Robinson Collado
  • 316
  • 4
  • 12
  • Which version of Jasmine do you use? I just upgrade from 2.6.2 to 2.8 and I still get the error `TypeError: Cannot read property 'be' of undefined` for `expect(1).to.be.gte(-1);` – Jonathan Parent Lévesque Nov 09 '17 at 17:11