mirror of
				https://github.com/node-red/node-red-nodes.git
				synced 2025-03-01 10:37:43 +00:00 
			
		
		
		
	Update node-red-random to add option to dynamically pass in 'To' and 'From' (#707)
* Add option to dynamically pass in 'From' and 'To' - fixed bug when 'From' was greater than 'To' by flipping the two * Set initial values of 'From' and 'To to "" to allow dynamic overriding them
This commit is contained in:
		| @@ -19,4 +19,6 @@ If set to return an integer it can include both the low and high values. | ||||
| If set to return a floating point value it will be from the low value, up to, but | ||||
| **not** including the high value. `min <= n < max` - so selecting 1 to 6 will return values 1 <= n < 6 . | ||||
|  | ||||
| You can dynamically pass in the 'From' and 'To' values to the node using msg.to and/or msg.from. **NOTE:** hard coded values in the node **always take precedence**. | ||||
|  | ||||
| **Note:** This returns numbers - objects of type **number**. | ||||
|   | ||||
| @@ -1,7 +1,14 @@ | ||||
| <script type="text/html" data-help-name="random"> | ||||
|     <p>Generates a random number between a low and high value.</p> | ||||
|     <p>Generates a random number between a low and high value. Defaults to 1 to 10.</p> | ||||
|     <p>If set to return an integer it can <i>include</i> both the low and high values. | ||||
|     <code>min <= n <= max</code></p> | ||||
|     <p>If set to return a floating point value it will be from the low value, up to, but | ||||
|     not including the high value. <code>min <= n < max</code></p> | ||||
|     <p><b>Inputs</b></p> | ||||
|     <p>You can dynamically pass in the 'From' and 'To' values to the node. <b>NOTE:</b> hard coded values in the node <b>always take precedence.</b> | ||||
|     <ul> | ||||
|     <i><b>From</b> [msg.from] Number containing the low value to be used.</i> | ||||
|     <br> | ||||
|     <i><b>To</b> [msg.to] Number containing the high value to be used.</i> | ||||
|     </ul> | ||||
| </script> | ||||
|   | ||||
| @@ -31,8 +31,8 @@ | ||||
|         color:"#E2D96E", | ||||
|         defaults: { | ||||
|             name: {value:""}, | ||||
|             low: {value:"1"}, | ||||
|             high: {value:"10"}, | ||||
|             low:  {value: 1,validate:function(v) { return  !isNaN(v) || v.length === 0;} }, | ||||
|             high: {value: 10,validate:function(v) { return  !isNaN(v) || v.length === 0;} }, | ||||
|             inte: {value:"true"}, | ||||
|             property: {value:"payload",required:true} | ||||
|         }, | ||||
|   | ||||
| @@ -3,21 +3,73 @@ module.exports = function(RED) { | ||||
|     "use strict"; | ||||
|     function RandomNode(n) { | ||||
|         RED.nodes.createNode(this,n); | ||||
|         this.low = Number(n.low || 1); | ||||
|         this.high = Number(n.high || 10); | ||||
|  | ||||
|         this.low = n.low | ||||
|         this.high = n.high | ||||
|         this.inte = n.inte || false; | ||||
|         this.property = n.property||"payload"; | ||||
|         var node = this; | ||||
|         var tmp = {}; | ||||
|  | ||||
|         this.on("input", function(msg) { | ||||
|             var value; | ||||
|             if (node.inte == "true" || node.inte === true) { | ||||
|                 value = Math.round(Math.random() * (node.high - node.low + 1) + node.low - 0.5); | ||||
|  | ||||
|           tmp.low = 1                 // set this as the default low value | ||||
|           tmp.low_e = "" | ||||
|           if (node.low) {             // if the the node has a value use it | ||||
|               tmp.low = node.low | ||||
|           } else if ('from' in msg) { // else see if a 'from' is in the msg | ||||
|               if (Number(msg.from)) { // if it is, and is a number, use it | ||||
|                   tmp.low = Number(msg.from); | ||||
|               } else {                // otherwise setup NaN error | ||||
|                   tmp.low = NaN; | ||||
|                   tmp.low_e = " From: " + msg.from; // setup to show bad incoming msg.from | ||||
|               } | ||||
|             else { | ||||
|                 value = Math.random() * (node.high - node.low) + node.low; | ||||
|           }  | ||||
|                | ||||
|           tmp.high = 10               // set this as the default high value   | ||||
|           tmp.high_e = ""; | ||||
|           if (node.high) {            // if the the node has a value use it  | ||||
|               tmp.high = node.high | ||||
|           } else if ('to' in msg) {   // else see if a 'to' is in the msg | ||||
|               if (Number(msg.to)) {   // if it is, and is a number, use it | ||||
|                   tmp.high = Number(msg.to); | ||||
|               } else {                // otherwise setup NaN error  | ||||
|                   tmp.high = NaN | ||||
|                   tmp.high_e = " To: " + msg.to // setup to show bad incoming msg.to | ||||
|               } | ||||
|           }  | ||||
|                             | ||||
|           // if tmp.low or high are not numbers, send an error msg with bad values | ||||
|           if ( (isNaN(tmp.low)) || (isNaN(tmp.high)) ) { | ||||
|               this.error("Random: one of the input values is not a number. " + tmp.low_e + tmp.high_e); | ||||
|           } else { | ||||
|           // at this point we have valid values so now to generate the random number!  | ||||
|  | ||||
|              // flip the values if low > high so random will work | ||||
|              var value = 0; | ||||
|              if (tmp.low > tmp.high) {   | ||||
|                  value = tmp.low | ||||
|                  tmp.low = tmp.high | ||||
|                  tmp.high = value | ||||
|              } | ||||
|  | ||||
|              // if returning an integer, do a math.ceil() on the low value and a  | ||||
|              // Math.floor()high value before generate the random number. This must be  | ||||
|              // done to insure the rounding doesn't round up if using something like 4.7 | ||||
|              // which would end up with 5 | ||||
|              if ( (node.inte == "true") || (node.inte === true) ) { | ||||
|                  tmp.low  = Math.ceil(tmp.low); | ||||
|                  tmp.high = Math.floor(tmp.high); | ||||
|                  // use this to round integers | ||||
|                  value = Math.round(Math.random() * (tmp.high - tmp.low + 1) + tmp.low - 0.5); | ||||
|              } else { | ||||
|                  // use this to round floats | ||||
|                  value = (Math.random() * (tmp.high - tmp.low)) + tmp.low; | ||||
|              } | ||||
|              | ||||
|              RED.util.setMessageProperty(msg,node.property,value); | ||||
|              node.send(msg); | ||||
|           } | ||||
|         }); | ||||
|     } | ||||
|     RED.nodes.registerType("random",RandomNode); | ||||
|   | ||||
| @@ -16,73 +16,256 @@ describe('random node', function() { | ||||
|         }); | ||||
|     }); | ||||
|      | ||||
|     it("should be loaded with correct defaults", function(done) { | ||||
|         var flow = [{"id":"n1", "type":"random", "name":"random1", "wires":[[]]}]; | ||||
|         helper.load(testNode, flow, function() { | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             //console.log(n1); | ||||
|             n1.should.have.property("low", 1); | ||||
|             n1.should.have.property("high", 10); | ||||
|             n1.should.have.property("inte", false); | ||||
|             done(); | ||||
|         }); | ||||
|     }); | ||||
| // ============================================================ | ||||
|  | ||||
|     it('should output an integer between -3 and 3', function(done) { | ||||
|         var flow = [{"id":"n1", "type":"random", low:-3, high:3, inte:true, wires:[["n2"]] }, | ||||
|    it ("Test i1 (integer) - DEFAULT no overrides defaults to 1 and 10", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "" , high:"" , inte:true, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             var c = 0; | ||||
|             n2.on("input", function(msg) {   | ||||
|                 if (c === 0) { | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.approximately(0,3); | ||||
|                     msg.payload.should.be.within(1,10);      | ||||
|                     msg.payload.toString().indexOf(".").should.equal(-1); // see if it's really an integer and not a float... | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test i1"});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|    it ("Test f1 (float)   - DEFAULT no overrides defaults to 1 and 10", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low:"" , high:"" , inte:false, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(1.0,9.999);      | ||||
|                     //msg.payload.toString().indexOf(".").should.not.equal(-1);  | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test f-1"});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| // ============================================================ | ||||
|  | ||||
|    it ("Test i2 (integer) - FLIP node From = 3 To = -3", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: 3, high: -3, inte:true, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(-3,3);      | ||||
|                     msg.payload.toString().indexOf(".").should.equal(-1); // slightly dumb test to see if it really is an integer and not a float... | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test i2"});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|    it ("Test f2 (float)   - FLIP node From = 3 To = -3", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: 3, high: -3, inte:false, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(-3.0,3.0);      | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test f2"});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| // ============================================================ | ||||
|  | ||||
|    it ("Test i3 (integer) - values in msg From = 2 To = '5', node no entries", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "", high: "", inte:true, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(2,5);      | ||||
|                     msg.payload.toString().indexOf(".").should.equal(-1); // slightly dumb test to see if it really is an integer and not a float... | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test i3", "from":2, "to":'5'});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|    it ("Test f3 (float)   - values in msg From = 2 To = '5', node no entries", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "", high: "", inte:false, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(2.0,5.0);      | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test f3", "from":2, "to":'5'});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|  | ||||
|  // ============================================================ | ||||
|  | ||||
|   it ("Test i4 (integer) - value in msg From = 2, node From = 5 To = '' - node overides From = 5 To defaults to 10", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: 5, high:"", inte:true, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(5,10);      | ||||
|                     msg.payload.toString().indexOf(".").should.equal(-1);  | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {payload:"a"}); | ||||
|             n1.emit("input", {"test":"Test i4", "from": 2});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should output an float between 20 and 30', function(done) { | ||||
|         var flow = [{"id":"n1", "type":"random", low:20, high:30, inte:false, wires:[["n2"]] }, | ||||
|   it ("Test f4 (float)   - value in msg From = 2, node From = 5 To = '' - node wins 'To' defaults to 10", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: 5, high:"", inte:false, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             var c = 0; | ||||
|             n2.on("input", function(msg) {   | ||||
|                 if (c === 0) { | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.approximately(25,5); | ||||
|                     msg.payload.toString().indexOf(".").should.not.equal(-1); | ||||
|                     msg.payload.should.be.within(5.0,10.0);      | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {payload:"a"}); | ||||
|             n1.emit("input", {"test":"Test f4", "from": 2});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should output an integer between -3 and 3 on chosen property - foo', function(done) { | ||||
|         var flow = [{"id":"n1", "type":"random", property:"foo", low:-3, high:3, inte:true, wires:[["n2"]] }, | ||||
| // ============================================================ | ||||
|  | ||||
|   it ("Test i5 (integer) - msg From = '6' To = '9' node no entries", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "", high: "", inte:true, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             var c = 0; | ||||
|             n2.on("input", function(msg) {   | ||||
|                 if (c === 0) { | ||||
|                     msg.should.have.a.property("foo"); | ||||
|                     msg.foo.should.be.approximately(0,3); | ||||
|                     msg.foo.toString().indexOf(".").should.equal(-1); | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(6,9);      | ||||
|                     msg.payload.toString().indexOf(".").should.equal(-1); // slightly dumb test to see if it really is an integer and not a float... | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {payload:"a"}); | ||||
|             n1.emit("input", {"test":"Test i5", "from": '6', "to": '9'});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|   it ("Test f5 (float)   - msg From = '6' To = '9' node no entries", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "", high: "", inte:false, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(6.0,9.0);      | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test f5", "from": '6', "to": '9'});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| // ============================================================ | ||||
|  | ||||
|   it ("Test i6 (integer) - msg From = 2.4 To = '7.3' node no entries", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "", high: "", inte:true, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(2,7);      | ||||
|                     msg.payload.toString().indexOf(".").should.equal(-1); // slightly dumb test to see if it really is an integer and not a float... | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test i6", "from": 2.4, "to": '7.3'});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|   it ("Test f6 (float)   - msg From = 2.4 To = '7.3' node no entries", function(done) {   | ||||
|         var flow = [{id:"n1", type:"random", low: "", high: "", inte:false, wires:[["n2"]] },   | ||||
|             {id:"n2", type:"helper"} ]; | ||||
|         helper.load(testNode, flow, function() {  | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) {   | ||||
|                 try { | ||||
|                     //console.log(msg);     | ||||
|                     msg.should.have.a.property("payload");        | ||||
|                     msg.payload.should.be.within(2.4,7.3);      | ||||
|                     done();  | ||||
|                 } | ||||
|                 catch(err) { done(err); }    | ||||
|             }); | ||||
|             n1.emit("input", {"test":"Test f6", "from": 2.4, "to": '7.3'});   | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| // ============================================================ | ||||
|  | ||||
|  | ||||
|     | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user