Class: Synthra::Types::Formula

Inherits:
Base
  • Object
show all
Defined in:
lib/synthra/types/formula.rb

Overview

Formula type generator — computes a value from sibling numeric fields.

Defined Under Namespace

Classes: SafeArithmetic

Instance Method Summary collapse

Instance Method Details

#generate_edge(rng, context, args) ⇒ Object



28
29
30
# File 'lib/synthra/types/formula.rb', line 28

def generate_edge(rng, context, args)
  rng.sample([0, 1, -1, 999999])
end

#generate_invalid(rng, context, args) ⇒ Object



32
33
34
# File 'lib/synthra/types/formula.rb', line 32

def generate_invalid(rng, context, args)
  rng.sample([nil, "not-a-number", [], {}])
end

#generate_random(rng, context, args) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/synthra/types/formula.rb', line 7

def generate_random(rng, context, args)
  expression = args[:expression] || args[:expr] || "0"
  return 0 if expression.to_s.empty?

  # Substitute sibling numeric fields, then evaluate the expression.
  result = replace_field_references(expression, context)

  if Synthra.configuration.allow_eval
    # Opt-in raw Ruby eval — RCE with tenant input, so for fully-trusted schemas only.
    eval(result) # rubocop:disable Security/Eval -- gated behind allow_eval (trusted-schema opt-in)
  else
    # Default: sandboxed arithmetic (no eval, no RCE). Anything that isn't pure
    # arithmetic over numbers / the whitelisted math functions evaluates to 0.
    value = SafeArithmetic.eval(result)
    value.nil? ? 0 : value
  end

rescue StandardError
  0
end

#replace_field_references(expr, context) ⇒ Object (private)



38
39
40
41
42
43
44
45
46
47
# File 'lib/synthra/types/formula.rb', line 38

def replace_field_references(expr, context)
  return expr unless context
  return expr unless context.respond_to?(:each)

  result = expr.dup
  context.each do |key, value|
    result.gsub!(/\b#{key}\b/, value.to_s) if value.is_a?(Numeric)
  end
  result
end