Module: MockRedisLuaExtension

Defined in:
lib/mock_redis_lua_extension.rb,
lib/mock_redis_lua_extension/version.rb

Defined Under Namespace

Classes: InvalidCommand, InvalidDataType

Constant Summary collapse

LIMIT_CMDS =
[
  'zrangebyscore',
  'zrangebylex',
  'zrevrangebyscore',
  'zrevrangebylex'
].freeze
WITHSCORES_CMDS =
[
  'zrange',
  'zrangebyscore',
  'zrevrangebyscore'
].freeze
VERSION =
"0.2.0".freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.is_a_mock?(instance) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/mock_redis_lua_extension.rb', line 42

def self.is_a_mock?(instance)
  instance.class.ancestors.any? { |a| a.to_s == 'MockRedis' }
end

.wrap(instance) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/mock_redis_lua_extension.rb', line 29

def self.wrap(instance)
  if !instance.respond_to?(:mock_redis_lua_extension_enabled) && is_a_mock?(instance)
    class << instance
      if RUFUS_LUA_LOADED
        prepend(MockRedisLuaExtension)
      end
    end
  elsif !is_a_mock?(instance)
    raise ArgumentError, 'Can only wrap MockRedis instances'
  end
  instance
end

Instance Method Details

#eval(script, keys = nil, argv = nil, **args) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/mock_redis_lua_extension.rb', line 81

def eval(script, keys=nil, argv=nil, **args)
  lua_state = Rufus::Lua::State.new
  setup_keys_and_argv(lua_state, keys, argv, args)

  lua_state.function 'redis.call' do |cmd, *args|
    lua_bound_redis_call(cmd, *args)
  end

  lua_state.function 'redis.breakpoint' do
    # Use redis commands such as `self.hgetall("key")` to debug
    binding.pry
  end

  lua_state.function 'redis.debug' do |*args|
    parsed_args = args.map { |arg| arg.is_a?(Rufus::Lua::Table) ? arg.to_ruby : arg }
    puts parsed_args.map(&:to_s).join(", ")
  end

  lua_state.function 'cjson.decode' do |arg|
    lua_bound_cjson_decode(arg)
  end

  lua_state.function 'cjson.encode' do |arg|
    lua_bound_cjson_encode(arg)
  end
  marshal_lua_return_to_ruby(lua_state.eval(script))
end

#evalsha(sha, keys = nil, argv = nil, **args) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/mock_redis_lua_extension.rb', line 73

def evalsha(sha, keys=nil, argv=nil, **args)
  if script(:exists, sha)
    eval(script_catalog[sha], keys, argv, **args)
  else
    raise ArgumentError, "NOSCRIPT No matching script. Please use EVAL."
  end
end

#mock_redis_lua_extension_enabledObject



46
47
48
# File 'lib/mock_redis_lua_extension.rb', line 46

def mock_redis_lua_extension_enabled
  RUFUS_LUA_LOADED
end

#script(subcmd, *args) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/mock_redis_lua_extension.rb', line 50

def script(subcmd, *args)
  case subcmd.downcase.to_sym
  when :load
    args.count == 1 or raise ArgumentError, "Invalid args: #{args.inspect}"
    script = args.first
    Digest::SHA256.hexdigest(script).tap do |sha|
      script_catalog[sha] = script
    end
  when :flush
    @script_catalog = {}
    true
  when :exists
    args = args.first
    if args.is_a?(Array)
      args.map { |sha| script_catalog.include?(sha) }
    else
      script_catalog.include?(args)
    end
  else
    raise ArgumentError, "Invalid script command: #{subcmd}"
  end
end