PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/test/test_client.lua

http://github.com/nrk/redis-lua
Lua | 2645 lines | 2067 code | 536 blank | 42 comment | 135 complexity | 418ae1b497192bbfcbbdded8c45e1776 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. package.path = "../src/?.lua;src/?.lua;" .. package.path
  2. pcall(require, "luarocks.require")
  3. local unpack = _G.unpack or table.unpack
  4. local tsc = require "telescope"
  5. local redis = require "redis"
  6. local settings = {
  7. host = '127.0.0.1',
  8. port = 6379,
  9. database = 14,
  10. password = nil,
  11. }
  12. function table.merge(self, tbl2)
  13. local new_table = {}
  14. for k,v in pairs(self) do new_table[k] = v end
  15. for k,v in pairs(tbl2) do new_table[k] = v end
  16. return new_table
  17. end
  18. function table.keys(self)
  19. local keys = {}
  20. for k, _ in pairs(self) do table.insert(keys, k) end
  21. return keys
  22. end
  23. function table.values(self)
  24. local values = {}
  25. for _, v in pairs(self) do table.insert(values, v) end
  26. return values
  27. end
  28. function table.contains(self, value)
  29. for _, v in pairs(self) do
  30. if v == value then return true end
  31. end
  32. return false
  33. end
  34. function table.slice(self, first, length)
  35. -- TODO: must be improved
  36. local new_table = {}
  37. for i = first, first + length - 1 do
  38. table.insert(new_table, self[i])
  39. end
  40. return new_table
  41. end
  42. function table.compare(self, other)
  43. -- NOTE: the body of this function was taken and slightly adapted from
  44. -- Penlight (http://github.com/stevedonovan/Penlight)
  45. if #self ~= #other then return false end
  46. local visited = {}
  47. for i = 1, #self do
  48. local val, gotcha = self[i], nil
  49. for j = 1, #other do
  50. if not visited[j] then
  51. if (type(val) == 'table') then
  52. if (table.compare(val, other[j])) then
  53. gotcha = j
  54. break
  55. end
  56. else
  57. if val == other[j] then
  58. gotcha = j
  59. break
  60. end
  61. end
  62. end
  63. end
  64. if not gotcha then return false end
  65. visited[gotcha] = true
  66. end
  67. return true
  68. end
  69. function parse_version(version_str)
  70. local major, minor, patch, status = version_str:match('^(%d+)%.(%d+)%.(%d+)%-?(%w-)$')
  71. local info = {
  72. string = version_str,
  73. compare = function(self, other)
  74. if type(other) == 'string' then
  75. other = parse_version(other)
  76. end
  77. if self.unrecognized or other.unrecognized then
  78. error('Cannot compare versions')
  79. end
  80. for _, part in ipairs({ 'major', 'minor', 'patch' }) do
  81. if self[part] < other[part] then
  82. return -1
  83. end
  84. if self[part] > other[part] then
  85. return 1
  86. end
  87. end
  88. return 0
  89. end,
  90. is = function(self, op, other)
  91. local comparation = self:compare(other);
  92. if op == '<' then return comparation < 0 end
  93. if op == '<=' then return comparation <= 0 end
  94. if op == '=' then return comparation == 0 end
  95. if op == '>=' then return comparation >= 0 end
  96. if op == '>' then return comparation > 0 end
  97. error('Invalid comparison operator: '..op)
  98. end,
  99. }
  100. if major and minor and patch then
  101. info.major = tonumber(major)
  102. info.minor = tonumber(minor)
  103. info.patch = tonumber(patch)
  104. if status then
  105. info.status = status
  106. end
  107. else
  108. info.unrecognized = true
  109. end
  110. return info
  111. end
  112. local utils = {
  113. create_client = function(parameters)
  114. if parameters == nil then
  115. parameters = settings
  116. end
  117. local client = redis.connect(parameters.host, parameters.port)
  118. if parameters.password then client:auth(parameters.password) end
  119. if parameters.database then client:select(parameters.database) end
  120. client:flushdb()
  121. local info = client:info()
  122. local version = parse_version(info.redis_version or info.server.redis_version)
  123. if version:is('<', '1.2.0') then
  124. error("redis-lua does not support Redis < 1.2.0 (current: "..version.string..")")
  125. end
  126. return client, version
  127. end,
  128. rpush_return = function(client, key, values, wipe)
  129. if wipe then client:del(key) end
  130. for _, v in ipairs(values) do
  131. client:rpush(key, v)
  132. end
  133. return values
  134. end,
  135. sadd_return = function(client, key, values, wipe)
  136. if wipe then client:del(key) end
  137. for _, v in ipairs(values) do
  138. client:sadd(key, v)
  139. end
  140. return values
  141. end,
  142. zadd_return = function(client, key, values, wipe)
  143. if wipe then client:del(key) end
  144. for k, v in pairs(values) do
  145. client:zadd(key, v, k)
  146. end
  147. return values
  148. end,
  149. sleep = function(sec)
  150. socket.select(nil, nil, sec)
  151. end,
  152. }
  153. local shared = {
  154. kvs_table = function()
  155. return {
  156. foo = 'bar',
  157. hoge = 'piyo',
  158. foofoo = 'barbar',
  159. }
  160. end,
  161. kvs_ns_table = function()
  162. return {
  163. ['metavars:foo'] = 'bar',
  164. ['metavars:hoge'] = 'piyo',
  165. ['metavars:foofoo'] = 'barbar',
  166. }
  167. end,
  168. lang_table = function()
  169. return {
  170. italian = "ciao",
  171. english = "hello",
  172. japanese = "こんいちは!",
  173. }
  174. end,
  175. numbers = function()
  176. return { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }
  177. end,
  178. zset_sample = function()
  179. return { a = -10, b = 0, c = 10, d = 20, e = 20, f = 30 }
  180. end,
  181. }
  182. tsc.make_assertion("table_values", "'%s' to have the same values as '%s'", table.compare)
  183. tsc.make_assertion("response_queued", "to be queued", function(response)
  184. if type(response) == 'table' and response.queued == true then
  185. return true
  186. else
  187. return false
  188. end
  189. end)
  190. tsc.make_assertion("error_message", "result to be an error with the expected message", function(msg, f)
  191. local ok, err = pcall(f)
  192. return not ok and err:match(msg)
  193. end)
  194. -- ------------------------------------------------------------------------- --
  195. context("Client initialization", function()
  196. test("Can connect successfully", function()
  197. local client = redis.connect(settings.host, settings.port)
  198. assert_type(client, 'table')
  199. assert_true(table.contains(table.keys(client.network), 'socket'))
  200. client.network.socket:send("PING\r\n")
  201. assert_equal(client.network.socket:receive('*l'), '+PONG')
  202. end)
  203. test("Can handle connection failures", function()
  204. assert_error_message("could not connect to .*:%d+ %[connection refused%]", function()
  205. redis.connect(settings.host, settings.port + 100)
  206. end)
  207. end)
  208. test("Accepts an URI for connection parameters", function()
  209. local uri = 'redis://'..settings.host..':'..settings.port
  210. local client = redis.connect(uri)
  211. assert_type(client, 'table')
  212. end)
  213. test("Accepts a table for connection parameters", function()
  214. local client = redis.connect(settings)
  215. assert_type(client, 'table')
  216. end)
  217. test("Can use an already connected socket", function()
  218. local connection = require('socket').tcp()
  219. connection:connect(settings.host, settings.port)
  220. local client = redis.connect({ socket = connection })
  221. assert_type(client, 'table')
  222. assert_true(client:ping())
  223. end)
  224. test("Can specify a timeout for connecting", function()
  225. local time, timeout = os.time(), 2;
  226. assert_error_message("could not connect to .*:%d+ %[timeout%]", function()
  227. redis.connect({ host = '169.254.255.255', timeout = timeout })
  228. end)
  229. assert_equal(time + timeout, os.time())
  230. end)
  231. end)
  232. context("Client features", function()
  233. before(function()
  234. client = utils.create_client(settings)
  235. end)
  236. test("Send raw commands", function()
  237. assert_equal(client:raw_cmd("PING\r\n"), 'PONG')
  238. assert_true(client:raw_cmd("*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"))
  239. assert_equal(client:raw_cmd("GET foo\r\n"), 'bar')
  240. end)
  241. test("Tansform nil command arguments into empty strings", function()
  242. assert_true(client:set(nil, 'bar'))
  243. assert_equal(client:get(''), 'bar')
  244. end)
  245. test("Create a new unbound command object", function()
  246. local cmd = redis.command('doesnotexist')
  247. assert_nil(client.doesnotexist)
  248. assert_error(function() cmd(client) end)
  249. local cmd = redis.command('ping', {
  250. response = function(response) return response == 'PONG' end
  251. })
  252. assert_equal(cmd(client), true)
  253. end)
  254. test("Define commands at module level", function()
  255. redis.commands.doesnotexist = redis.command('doesnotexist')
  256. local client2 = utils.create_client(settings)
  257. redis.commands.doesnotexist = nil
  258. local client3 = utils.create_client(settings)
  259. assert_nil(client.doesnotexist)
  260. assert_not_nil(client2.doesnotexist)
  261. assert_nil(client3.doesnotexist)
  262. end)
  263. test("Define commands at module level (OLD)", function()
  264. redis.define_command('doesnotexist')
  265. local client2 = utils.create_client(settings)
  266. redis.undefine_command('doesnotexist')
  267. local client3 = utils.create_client(settings)
  268. assert_nil(client.doesnotexist)
  269. assert_not_nil(client2.doesnotexist)
  270. assert_nil(client3.doesnotexist)
  271. end)
  272. test("Define new commands at client instance level", function()
  273. client.doesnotexist = redis.command('doesnotexist')
  274. assert_not_nil(client.doesnotexist)
  275. assert_error(function() client:doesnotexist() end)
  276. client.doesnotexist = nil
  277. assert_nil(client.doesnotexist)
  278. client.ping = redis.command('ping')
  279. assert_not_nil(client.ping)
  280. assert_equal(client:ping(), 'PONG')
  281. client.ping = redis.command('ping', {
  282. request = client.requests.multibulk
  283. })
  284. assert_not_nil(client.ping)
  285. assert_equal(client:ping(), 'PONG')
  286. client.ping = redis.command('ping', {
  287. request = client.requests.multibulk,
  288. response = function(reply) return reply == 'PONG' end
  289. })
  290. assert_not_nil(client.ping)
  291. assert_true(client:ping())
  292. end)
  293. test("Define new commands at client instance level (OLD)", function()
  294. client:define_command('doesnotexist')
  295. assert_not_nil(client.doesnotexist)
  296. assert_error(function() client:doesnotexist() end)
  297. client:undefine_command('doesnotexist')
  298. assert_nil(client.doesnotexist)
  299. client:define_command('ping')
  300. assert_not_nil(client.ping)
  301. assert_equal(client:ping(), 'PONG')
  302. client:define_command('ping', {
  303. request = client.requests.multibulk
  304. })
  305. assert_not_nil(client.ping)
  306. assert_equal(client:ping(), 'PONG')
  307. client:define_command('ping', {
  308. request = client.requests.multibulk,
  309. response = function(reply) return reply == 'PONG' end
  310. })
  311. assert_not_nil(client.ping)
  312. assert_true(client:ping())
  313. end)
  314. test("Pipelining commands", function()
  315. local replies, count = client:pipeline(function(p)
  316. p:ping()
  317. p:exists('counter')
  318. p:incrby('counter', 10)
  319. p:incrby('counter', 30)
  320. p:exists('counter')
  321. p:get('counter')
  322. p:mset({ foo = 'bar', hoge = 'piyo'})
  323. p:del('foo', 'hoge')
  324. p:mget('does_not_exist', 'counter')
  325. p:info()
  326. p:get('nilkey')
  327. end)
  328. assert_type(replies, 'table')
  329. assert_equal(count, 11)
  330. assert_equal(#replies, 10)
  331. assert_true(replies[1])
  332. assert_type(replies[9], 'table')
  333. assert_equal(replies[9][2], '40')
  334. assert_type(replies[10], 'table')
  335. end)
  336. after(function()
  337. client:quit()
  338. end)
  339. end)
  340. context("Redis commands", function()
  341. before(function()
  342. client, version = utils.create_client(settings)
  343. end)
  344. after(function()
  345. client:quit()
  346. end)
  347. context("Connection related commands", function()
  348. test("PING (client:ping)", function()
  349. assert_true(client:ping())
  350. end)
  351. test("ECHO (client:echo)", function()
  352. local str_ascii, str_utf8 = "Can you hear me?", "聞こえますか?"
  353. assert_equal(client:echo(str_ascii), str_ascii)
  354. assert_equal(client:echo(str_utf8), str_utf8)
  355. end)
  356. test("SELECT (client:select)", function()
  357. if not settings.database then return end
  358. assert_true(client:select(0))
  359. assert_true(client:select(settings.database))
  360. assert_error(function() client:select(100) end)
  361. assert_error(function() client:select(-1) end)
  362. end)
  363. end)
  364. context("Commands operating on the key space", function()
  365. test("KEYS (client:keys)", function()
  366. local kvs_prefixed = shared.kvs_ns_table()
  367. local kvs_unprefixed = { aaa = 1, aba = 2, aca = 3 }
  368. local kvs_all = table.merge(kvs_prefixed, kvs_unprefixed)
  369. client:mset(kvs_all)
  370. assert_empty(client:keys('nokeys:*'))
  371. assert_table_values(
  372. table.values(client:keys('*')),
  373. table.keys(kvs_all)
  374. )
  375. assert_table_values(
  376. table.values(client:keys('metavars:*')),
  377. table.keys(kvs_prefixed)
  378. )
  379. assert_table_values(
  380. table.values(client:keys('a?a')),
  381. table.keys(kvs_unprefixed)
  382. )
  383. end)
  384. test("EXISTS (client:exists)", function()
  385. client:set('foo', 'bar')
  386. assert_true(client:exists('foo'))
  387. assert_false(client:exists('hoge'))
  388. end)
  389. test("DEL (client:del)", function()
  390. client:mset(shared.kvs_table())
  391. assert_equal(client:del('doesnotexist'), 0)
  392. assert_equal(client:del('foofoo'), 1)
  393. assert_equal(client:del('foo', 'hoge', 'doesnotexist'), 2)
  394. end)
  395. test("TYPE (client:type)", function()
  396. assert_equal(client:type('doesnotexist'), 'none')
  397. client:set('fooString', 'bar')
  398. assert_equal(client:type('fooString'), 'string')
  399. client:rpush('fooList', 'bar')
  400. assert_equal(client:type('fooList'), 'list')
  401. client:sadd('fooSet', 'bar')
  402. assert_equal(client:type('fooSet'), 'set')
  403. client:zadd('fooZSet', 0, 'bar')
  404. assert_equal(client:type('fooZSet'), 'zset')
  405. if version:is('>=', '2.0.0') then
  406. client:hset('fooHash', 'value', 'bar')
  407. assert_equal('hash', client:type('fooHash'))
  408. end
  409. end)
  410. test("RANDOMKEY (client:randomkey)", function()
  411. local kvs = shared.kvs_table()
  412. assert_nil(client:randomkey())
  413. client:mset(kvs)
  414. assert_true(table.contains(table.keys(kvs), client:randomkey()))
  415. end)
  416. test("RENAME (client:rename)", function()
  417. local kvs = shared.kvs_table()
  418. client:mset(kvs)
  419. assert_true(client:rename('hoge', 'hogehoge'))
  420. assert_false(client:exists('hoge'))
  421. assert_equal(client:get('hogehoge'), 'piyo')
  422. -- rename overwrites existing keys
  423. assert_true(client:rename('foo', 'foofoo'))
  424. assert_false(client:exists('foo'))
  425. assert_equal(client:get('foofoo'), 'bar')
  426. -- rename fails when the key does not exist
  427. assert_error(function()
  428. client:rename('doesnotexist', 'fuga')
  429. end)
  430. end)
  431. test("RENAMENX (client:renamenx)", function()
  432. local kvs = shared.kvs_table()
  433. client:mset(kvs)
  434. assert_true(client:renamenx('hoge', 'hogehoge'))
  435. assert_false(client:exists('hoge'))
  436. assert_equal(client:get('hogehoge'), 'piyo')
  437. -- rename overwrites existing keys
  438. assert_false(client:renamenx('foo', 'foofoo'))
  439. assert_true(client:exists('foo'))
  440. -- rename fails when the key does not exist
  441. assert_error(function()
  442. client:renamenx('doesnotexist', 'fuga')
  443. end)
  444. end)
  445. test("TTL (client:ttl)", function()
  446. client:set('foo', 'bar')
  447. assert_equal(client:ttl('foo'), -1)
  448. assert_true(client:expire('foo', 5))
  449. assert_lte(client:ttl('foo'), 5)
  450. end)
  451. test("PTTL (client:pttl)", function()
  452. if version:is('<', '2.5.0') then return end
  453. client:set('foo', 'bar')
  454. assert_equal(client:pttl('foo'), -1)
  455. local ttl = 5
  456. assert_true(client:expire('foo', ttl))
  457. assert_lte(client:pttl('foo'), 5 * 1000)
  458. assert_gte(client:pttl('foo'), 5 * 1000 - 500)
  459. end)
  460. test("EXPIRE (client:expire)", function()
  461. client:set('foo', 'bar')
  462. assert_true(client:expire('foo', 2))
  463. assert_true(client:exists('foo'))
  464. assert_lte(client:ttl('foo'), 2)
  465. utils.sleep(3)
  466. assert_false(client:exists('foo'))
  467. client:set('foo', 'bar')
  468. assert_true(client:expire('foo', 100))
  469. utils.sleep(3)
  470. assert_lte(client:ttl('foo'), 97)
  471. assert_true(client:expire('foo', -100))
  472. assert_false(client:exists('foo'))
  473. end)
  474. test("PEXPIRE (client:pexpire)", function()
  475. if version:is('<', '2.5.0') then return end
  476. local ttl = 1
  477. client:set('foo', 'bar')
  478. assert_true(client:pexpire('foo', ttl * 1000))
  479. assert_true(client:exists('foo'))
  480. assert_lte(client:pttl('foo'), ttl * 1000)
  481. assert_gte(client:pttl('foo'), ttl * 1000 - 500)
  482. utils.sleep(ttl)
  483. assert_false(client:exists('foo'))
  484. end)
  485. test("EXPIREAT (client:expireat)", function()
  486. client:set('foo', 'bar')
  487. assert_true(client:expireat('foo', os.time() + 2))
  488. assert_lte(client:ttl('foo'), 2)
  489. utils.sleep(3)
  490. assert_false(client:exists('foo'))
  491. client:set('foo', 'bar')
  492. assert_true(client:expireat('foo', os.time() - 100))
  493. assert_false(client:exists('foo'))
  494. end)
  495. test("PEXPIREAT (client:pexpireat)", function()
  496. if version:is('<', '2.5.0') then return end
  497. local ttl = 2
  498. client:set('foo', 'bar')
  499. assert_true(client:pexpireat('foo', os.time() + ttl * 1000))
  500. assert_lte(client:pttl('foo'), ttl * 1000)
  501. utils.sleep(ttl + 1)
  502. assert_false(client:exists('foo'))
  503. client:set('foo', 'bar')
  504. assert_true(client:pexpireat('foo', os.time() - 100 * 1000))
  505. assert_false(client:exists('foo'))
  506. end)
  507. test("MOVE (client:move)", function()
  508. if not settings.database then return end
  509. local other_db = settings.database + 1
  510. client:set('foo', 'bar')
  511. client:select(other_db)
  512. client:flushdb()
  513. client:select(settings.database)
  514. assert_true(client:move('foo', other_db))
  515. assert_false(client:move('foo', other_db))
  516. assert_false(client:move('doesnotexist', other_db))
  517. client:set('hoge', 'piyo')
  518. assert_error(function() client:move('hoge', 100) end)
  519. end)
  520. test("DBSIZE (client:dbsize)", function()
  521. assert_equal(client:dbsize(), 0)
  522. client:mset(shared.kvs_table())
  523. assert_greater_than(client:dbsize(), 0)
  524. end)
  525. test("PERSIST (client:persist)", function()
  526. if version:is('<', '2.1.0') then return end
  527. client:set('foo', 'bar')
  528. assert_true(client:expire('foo', 1))
  529. assert_equal(client:ttl('foo'), 1)
  530. assert_true(client:persist('foo'))
  531. assert_equal(client:ttl('foo'), -1)
  532. assert_false(client:persist('foo'))
  533. assert_false(client:persist('foobar'))
  534. end)
  535. test("SCAN (client:scan)", function()
  536. if version:is('<', '2.8.0') then return end
  537. client:mset(
  538. 'scan:1', '1',
  539. 'scan:2', '2',
  540. 'scan:3', '3',
  541. 'scan:4', '4'
  542. )
  543. local cursor, keys = unpack(client:scan(0, {
  544. match = 'scan:*', count = 10
  545. }))
  546. assert_type(cursor, 'string')
  547. assert_type(keys, 'table')
  548. assert_table_values(keys, {'scan:1','scan:2','scan:3','scan:4'})
  549. end)
  550. end)
  551. context("Commands operating on the key space - SORT", function()
  552. -- TODO: missing tests for params GET and BY
  553. before(function()
  554. -- TODO: code duplication!
  555. list01, list01_values = "list01", { "4","2","3","5","1" }
  556. for _,v in ipairs(list01_values) do client:rpush(list01,v) end
  557. list02, list02_values = "list02", { "1","10","2","20","3","30" }
  558. for _,v in ipairs(list02_values) do client:rpush(list02,v) end
  559. end)
  560. test("SORT (client:sort)", function()
  561. local sorted = client:sort(list01)
  562. assert_table_values(sorted, { "1","2","3","4","5" })
  563. end)
  564. test("SORT (client:sort) with parameter ASC/DESC", function()
  565. assert_table_values(client:sort(list01, { sort = 'asc'}), { "1","2","3","4","5" })
  566. assert_table_values(client:sort(list01, { sort = 'desc'}), { "5","4","3","2","1" })
  567. end)
  568. test("SORT (client:sort) with parameter LIMIT", function()
  569. assert_table_values(client:sort(list01, { limit = { 0,3 } }), { "1","2", "3" })
  570. assert_table_values(client:sort(list01, { limit = { 3,2 } }), { "4","5" })
  571. end)
  572. test("SORT (client:sort) with parameter ALPHA", function()
  573. assert_table_values(client:sort(list02, { alpha = false }), { "1","2","3","10","20","30" })
  574. assert_table_values(client:sort(list02, { alpha = true }), { "1","10","2","20","3","30" })
  575. end)
  576. test("SORT (client:sort) with parameter GET", function()
  577. client:rpush('uids', 1003)
  578. client:rpush('uids', 1001)
  579. client:rpush('uids', 1002)
  580. client:rpush('uids', 1000)
  581. local sortget = {
  582. ['uid:1000'] = 'foo', ['uid:1001'] = 'bar',
  583. ['uid:1002'] = 'hoge', ['uid:1003'] = 'piyo',
  584. }
  585. client:mset(sortget)
  586. assert_table_values(client:sort('uids', { get = 'uid:*' }), table.values(sortget))
  587. assert_table_values(client:sort('uids', { get = { 'uid:*' } }), table.values(sortget))
  588. end)
  589. test("SORT (client:sort) with multiple parameters", function()
  590. assert_table_values(client:sort(list02, {
  591. alpha = false,
  592. sort = 'desc',
  593. limit = { 1, 4 }
  594. }), { "20","10","3","2" })
  595. end)
  596. test("SORT (client:sort) with parameter STORE", function()
  597. assert_equal(client:sort(list01, { store = 'list01_ordered' }), 5)
  598. assert_true(client:exists('list01_ordered'))
  599. end)
  600. end)
  601. context("Commands operating on string values", function()
  602. test("SET (client:set)", function()
  603. assert_true(client:set('foo', 'bar'))
  604. assert_equal(client:get('foo'), 'bar')
  605. end)
  606. test("GET (client:get)", function()
  607. client:set('foo', 'bar')
  608. assert_equal(client:get('foo'), 'bar')
  609. assert_nil(client:get('hoge'))
  610. assert_error(function()
  611. client:rpush('metavars', 'foo')
  612. client:get('metavars')
  613. end)
  614. end)
  615. test("SETNX (client:setnx)", function()
  616. assert_true(client:setnx('foo', 'bar'))
  617. assert_false(client:setnx('foo', 'baz'))
  618. assert_equal(client:get('foo'), 'bar')
  619. end)
  620. test("SETEX (client:setex)", function()
  621. if version:is('<', '2.0.0') then return end
  622. assert_true(client:setex('foo', 10, 'bar'))
  623. assert_true(client:exists('foo'))
  624. assert_lte(client:ttl('foo'), 10)
  625. assert_true(client:setex('hoge', 1, 'piyo'))
  626. utils.sleep(2)
  627. assert_false(client:exists('hoge'))
  628. assert_error(function() client:setex('hoge', 2.5, 'piyo') end)
  629. assert_error(function() client:setex('hoge', 0, 'piyo') end)
  630. assert_error(function() client:setex('hoge', -10, 'piyo') end)
  631. end)
  632. test("PSETEX (client:psetex)", function()
  633. if version:is('<', '2.5.0') then return end
  634. local ttl = 10 * 1000
  635. assert_true(client:psetex('foo', ttl, 'bar'))
  636. assert_true(client:exists('foo'))
  637. assert_lte(client:pttl('foo'), ttl)
  638. assert_gte(client:pttl('foo'), ttl - 500)
  639. assert_true(client:psetex('hoge', 1 * 1000, 'piyo'))
  640. utils.sleep(2)
  641. assert_false(client:exists('hoge'))
  642. assert_error(function() client:psetex('hoge', 2.5, 'piyo') end)
  643. assert_error(function() client:psetex('hoge', 0, 'piyo') end)
  644. assert_error(function() client:psetex('hoge', -10, 'piyo') end)
  645. end)
  646. test("MSET (client:mset)", function()
  647. local kvs = shared.kvs_table()
  648. assert_true(client:mset(kvs))
  649. for k,v in pairs(kvs) do
  650. assert_equal(client:get(k), v)
  651. end
  652. assert_true(client:mset('a', '1', 'b', '2', 'c', '3'))
  653. assert_equal(client:get('a'), '1')
  654. assert_equal(client:get('b'), '2')
  655. assert_equal(client:get('c'), '3')
  656. end)
  657. test("MSETNX (client:msetnx)", function()
  658. assert_true(client:msetnx({ a = '1', b = '2' }))
  659. assert_false(client:msetnx({ c = '3', a = '100'}))
  660. assert_equal(client:get('a'), '1')
  661. assert_equal(client:get('b'), '2')
  662. end)
  663. test("MGET (client:mget)", function()
  664. local kvs = shared.kvs_table()
  665. local keys, values = table.keys(kvs), table.values(kvs)
  666. assert_true(client:mset(kvs))
  667. assert_table_values(client:mget(unpack(keys)), values)
  668. end)
  669. test("GETSET (client:getset)", function()
  670. assert_nil(client:getset('foo', 'bar'))
  671. assert_equal(client:getset('foo', 'barbar'), 'bar')
  672. assert_equal(client:getset('foo', 'baz'), 'barbar')
  673. end)
  674. test("INCR (client:incr)", function()
  675. assert_equal(client:incr('foo'), 1)
  676. assert_equal(client:incr('foo'), 2)
  677. assert_true(client:set('hoge', 'piyo'))
  678. if version:is('<', '2.0.0') then
  679. assert_equal(client:incr('hoge'), 1)
  680. else
  681. assert_error(function()
  682. client:incr('hoge')
  683. end)
  684. end
  685. end)
  686. test("INCRBY (client:incrby)", function()
  687. client:set('foo', 2)
  688. assert_equal(client:incrby('foo', 20), 22)
  689. assert_equal(client:incrby('foo', -12), 10)
  690. assert_equal(client:incrby('foo', -110), -100)
  691. end)
  692. test("INCRBYFLOAT (client:incrbyfloat)", function()
  693. if version:is('<', '2.5.0') then return end
  694. client:set('foo', 2)
  695. assert_equal(client:incrbyfloat('foo', 20.123), 22.123)
  696. assert_equal(client:incrbyfloat('foo', -12.123), 10)
  697. assert_equal(client:incrbyfloat('foo', -110.01), -100.01)
  698. end)
  699. test("DECR (client:decr)", function()
  700. assert_equal(client:decr('foo'), -1)
  701. assert_equal(client:decr('foo'), -2)
  702. assert_true(client:set('hoge', 'piyo'))
  703. if version:is('<', '2.0.0') then
  704. assert_equal(client:decr('hoge'), -1)
  705. else
  706. assert_error(function()
  707. client:decr('hoge')
  708. end)
  709. end
  710. end)
  711. test("DECRBY (client:decrby)", function()
  712. client:set('foo', -2)
  713. assert_equal(client:decrby('foo', 20), -22)
  714. assert_equal(client:decrby('foo', -12), -10)
  715. assert_equal(client:decrby('foo', -110), 100)
  716. end)
  717. test("APPEND (client:append)", function()
  718. if version:is('<', '2.0.0') then return end
  719. client:set('foo', 'bar')
  720. assert_equal(client:append('foo', '__'), 5)
  721. assert_equal(client:append('foo', 'bar'), 8)
  722. assert_equal(client:get('foo'), 'bar__bar')
  723. assert_equal(client:append('hoge', 'piyo'), 4)
  724. assert_equal(client:get('hoge'), 'piyo')
  725. assert_error(function()
  726. client:rpush('metavars', 'foo')
  727. client:append('metavars', 'bar')
  728. end)
  729. end)
  730. test("SUBSTR (client:substr)", function()
  731. if version:is('<', '2.0.0') then return end
  732. client:set('var', 'foobar')
  733. assert_equal(client:substr('var', 0, 2), 'foo')
  734. assert_equal(client:substr('var', 3, 5), 'bar')
  735. assert_equal(client:substr('var', -3, -1), 'bar')
  736. assert_equal(client:substr('var', 5, 0), '')
  737. client:set('numeric', 123456789)
  738. assert_equal(client:substr('numeric', 0, 4), '12345')
  739. assert_error(function()
  740. client:rpush('metavars', 'foo')
  741. client:substr('metavars', 0, 3)
  742. end)
  743. end)
  744. test("STRLEN (client:strlen)", function()
  745. if version:is('<', '2.1.0') then return end
  746. client:set('var', 'foobar')
  747. assert_equal(client:strlen('var'), 6)
  748. assert_equal(client:append('var', '___'), 9)
  749. assert_equal(client:strlen('var'), 9)
  750. assert_error(function()
  751. client:rpush('metavars', 'foo')
  752. qclient:strlen('metavars')
  753. end)
  754. end)
  755. test("SETRANGE (client:setrange)", function()
  756. if version:is('<', '2.1.0') then return end
  757. assert_equal(client:setrange('var', 0, 'foobar'), 6)
  758. assert_equal(client:get('var'), 'foobar')
  759. assert_equal(client:setrange('var', 3, 'foo'), 6)
  760. assert_equal(client:get('var'), 'foofoo')
  761. assert_equal(client:setrange('var', 10, 'barbar'), 16)
  762. assert_equal(client:get('var'), "foofoo\0\0\0\0barbar")
  763. assert_error(function()
  764. client:setrange('var', -1, 'bogus')
  765. end)
  766. assert_error(function()
  767. client:rpush('metavars', 'foo')
  768. client:setrange('metavars', 0, 'hoge')
  769. end)
  770. end)
  771. test("GETRANGE (client:getrange)", function()
  772. if version:is('<', '2.1.0') then return end
  773. client:set('var', 'foobar')
  774. assert_equal(client:getrange('var', 0, 2), 'foo')
  775. assert_equal(client:getrange('var', 3, 5), 'bar')
  776. assert_equal(client:getrange('var', -3, -1), 'bar')
  777. assert_equal(client:substr('var', 5, 0), '')
  778. client:set('numeric', 123456789)
  779. assert_equal(client:getrange('numeric', 0, 4), '12345')
  780. assert_error(function()
  781. client:rpush('metavars', 'foo')
  782. client:getrange('metavars', 0, 3)
  783. end)
  784. end)
  785. test("SETBIT (client:setbit)", function()
  786. if version:is('<', '2.1.0') then return end
  787. assert_equal(client:setbit('binary', 31, 1), 0)
  788. assert_equal(client:setbit('binary', 0, 1), 0)
  789. assert_equal(client:strlen('binary'), 4)
  790. assert_equal(client:get('binary'), "\128\0\0\1")
  791. assert_equal(client:setbit('binary', 0, 0), 1)
  792. assert_equal(client:setbit('binary', 0, 0), 0)
  793. assert_equal(client:get('binary'), "\0\0\0\1")
  794. assert_error(function()
  795. client:setbit('binary', -1, 1)
  796. end)
  797. assert_error(function()
  798. client:setbit('binary', 'invalid', 1)
  799. end)
  800. assert_error(function()
  801. client:setbit('binary', 'invalid', 1)
  802. end)
  803. assert_error(function()
  804. client:setbit('binary', 15, 255)
  805. end)
  806. assert_error(function()
  807. client:setbit('binary', 15, 'invalid')
  808. end)
  809. assert_error(function()
  810. client:rpush('metavars', 'foo')
  811. client:setbit('metavars', 0, 1)
  812. end)
  813. end)
  814. test("GETBIT (client:getbit)", function()
  815. if version:is('<', '2.1.0') then return end
  816. client:set('binary', "\128\0\0\1")
  817. assert_equal(client:getbit('binary', 0), 1)
  818. assert_equal(client:getbit('binary', 15), 0)
  819. assert_equal(client:getbit('binary', 31), 1)
  820. assert_equal(client:getbit('binary', 63), 0)
  821. assert_error(function()
  822. client:getbit('binary', -1)
  823. end)
  824. assert_error(function()
  825. client:getbit('binary', 'invalid')
  826. end)
  827. assert_error(function()
  828. client:rpush('metavars', 'foo')
  829. client:getbit('metavars', 0)
  830. end)
  831. end)
  832. test("BITOP (client:bitop)", function()
  833. if version:is('<', '2.5.10') then return end
  834. client:set('foo', 'a')
  835. client:set('bar', 'b')
  836. client:bitop('AND', 'foo&bar', 'foo', 'bar')
  837. client:bitop('OR', 'foo|bar', 'foo', 'bar')
  838. client:bitop('XOR', 'foo^bar', 'foo', 'bar')
  839. client:bitop('NOT', '-foo', 'foo')
  840. assert_equal(client:get('foo&bar'), '\96')
  841. assert_equal(client:get('foo|bar'), '\99')
  842. assert_equal(client:get('foo^bar'), '\3')
  843. assert_equal(client:get('-foo'), '\158')
  844. end)
  845. test("BITCOUNT (client:bitcount)", function()
  846. if version:is('<', '2.5.10') then return end
  847. client:set('foo', 'abcde')
  848. assert_equal(client:bitcount('foo', 1, 3), 10)
  849. assert_equal(client:bitcount('foo', 0, -1), 17)
  850. end)
  851. end)
  852. context("Commands operating on lists", function()
  853. test("RPUSH (client:rpush)", function()
  854. if version:is('<', '2.0.0') then
  855. assert_true(client:rpush('metavars', 'foo'))
  856. assert_true(client:rpush('metavars', 'hoge'))
  857. else
  858. assert_equal(client:rpush('metavars', 'foo'), 1)
  859. assert_equal(client:rpush('metavars', 'hoge'), 2)
  860. end
  861. assert_error(function()
  862. client:set('foo', 'bar')
  863. client:rpush('foo', 'baz')
  864. end)
  865. end)
  866. test("RPUSHX (client:rpushx)", function()
  867. if version:is('<', '2.1.0') then return end
  868. assert_equal(client:rpushx('numbers', 1), 0)
  869. assert_equal(client:rpush('numbers', 2), 1)
  870. assert_equal(client:rpushx('numbers', 3), 2)
  871. assert_equal(client:llen('numbers'), 2)
  872. assert_table_values(client:lrange('numbers', 0, -1), { '2', '3' })
  873. assert_error(function()
  874. client:set('foo', 'bar')
  875. client:rpushx('foo', 'baz')
  876. end)
  877. end)
  878. test("LPUSH (client:lpush)", function()
  879. if version:is('<', '2.0.0') then
  880. assert_true(client:lpush('metavars', 'foo'))
  881. assert_true(client:lpush('metavars', 'hoge'))
  882. else
  883. assert_equal(client:lpush('metavars', 'foo'), 1)
  884. assert_equal(client:lpush('metavars', 'hoge'), 2)
  885. end
  886. assert_error(function()
  887. client:set('foo', 'bar')
  888. client:lpush('foo', 'baz')
  889. end)
  890. end)
  891. test("LPUSHX (client:lpushx)", function()
  892. if version:is('<', '2.1.0') then return end
  893. assert_equal(client:lpushx('numbers', 1), 0)
  894. assert_equal(client:lpush('numbers', 2), 1)
  895. assert_equal(client:lpushx('numbers', 3), 2)
  896. assert_equal(client:llen('numbers'), 2)
  897. assert_table_values(client:lrange('numbers', 0, -1), { '3', '2' })
  898. assert_error(function()
  899. client:set('foo', 'bar')
  900. client:lpushx('foo', 'baz')
  901. end)
  902. end)
  903. test("LLEN (client:llen)", function()
  904. local kvs = shared.kvs_table()
  905. for _, v in pairs(kvs) do
  906. client:rpush('metavars', v)
  907. end
  908. assert_equal(client:llen('metavars'), 3)
  909. assert_equal(client:llen('doesnotexist'), 0)
  910. assert_error(function()
  911. client:set('foo', 'bar')
  912. client:llen('foo')
  913. end)
  914. end)
  915. test("LRANGE (client:lrange)", function()
  916. local numbers = utils.rpush_return(client, 'numbers', shared.numbers())
  917. assert_table_values(client:lrange('numbers', 0, 3), table.slice(numbers, 1, 4))
  918. assert_table_values(client:lrange('numbers', 4, 8), table.slice(numbers, 5, 5))
  919. assert_table_values(client:lrange('numbers', 0, 0), table.slice(numbers, 1, 1))
  920. assert_empty(client:lrange('numbers', 1, 0))
  921. assert_table_values(client:lrange('numbers', 0, -1), numbers)
  922. assert_table_values(client:lrange('numbers', 5, -5), { '5' })
  923. assert_empty(client:lrange('numbers', 7, -5))
  924. assert_table_values(client:lrange('numbers', -5, -2), table.slice(numbers, 6, 4))
  925. assert_table_values(client:lrange('numbers', -100, 100), numbers)
  926. end)
  927. test("LTRIM (client:ltrim)", function()
  928. local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
  929. assert_true(client:ltrim('numbers', 0, 2))
  930. assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 1, 3))
  931. local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
  932. assert_true(client:ltrim('numbers', 5, 9))
  933. assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 6, 5))
  934. local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
  935. assert_true(client:ltrim('numbers', 0, -6))
  936. assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 1, 5))
  937. local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
  938. assert_true(client:ltrim('numbers', -5, -3))
  939. assert_table_values(client:lrange('numbers', 0, -1), table.slice(numbers, 6, 3))
  940. local numbers = utils.rpush_return(client, 'numbers', shared.numbers(), true)
  941. assert_true(client:ltrim('numbers', -100, 100))
  942. assert_table_values(client:lrange('numbers', 0, -1), numbers)
  943. assert_error(function()
  944. client:set('foo', 'bar')
  945. client:ltrim('foo', 0, 1)
  946. end)
  947. end)
  948. test("LINDEX (client:lindex)", function()
  949. local numbers = utils.rpush_return(client, 'numbers', shared.numbers())
  950. assert_equal(client:lindex('numbers', 0), numbers[1])
  951. assert_equal(client:lindex('numbers', 5), numbers[6])
  952. assert_equal(client:lindex('numbers', 9), numbers[10])
  953. assert_nil(client:lindex('numbers', 100))
  954. assert_equal(client:lindex('numbers', -0), numbers[1])
  955. assert_equal(client:lindex('numbers', -1), numbers[10])
  956. assert_equal(client:lindex('numbers', -3), numbers[8])
  957. assert_nil(client:lindex('numbers', -100))
  958. assert_error(function()
  959. client:set('foo', 'bar')
  960. client:lindex('foo', 0)
  961. end)
  962. end)
  963. test("LSET (client:lset)", function()
  964. utils.rpush_return(client, 'numbers', shared.numbers())
  965. assert_true(client:lset('numbers', 5, -5))
  966. assert_equal(client:lindex('numbers', 5), '-5')
  967. assert_error(function()
  968. client:lset('numbers', 99, 99)
  969. end)
  970. assert_error(function()
  971. client:set('foo', 'bar')
  972. client:lset('foo', 0, 0)
  973. end)
  974. end)
  975. test("LREM (client:lrem)", function()
  976. local mixed = { '0', '_', '2', '_', '4', '_', '6', '_' }
  977. utils.rpush_return(client, 'mixed', mixed, true)
  978. assert_equal(client:lrem('mixed', 2, '_'), 2)
  979. assert_table_values(client:lrange('mixed', 0, -1), { '0', '2', '4', '_', '6', '_' })
  980. utils.rpush_return(client, 'mixed', mixed, true)
  981. assert_equal(client:lrem('mixed', 0, '_'), 4)
  982. assert_table_values(client:lrange('mixed', 0, -1), { '0', '2', '4', '6' })
  983. utils.rpush_return(client, 'mixed', mixed, true)
  984. assert_equal(client:lrem('mixed', -2, '_'), 2)
  985. assert_table_values(client:lrange('mixed', 0, -1), { '0', '_', '2', '_', '4', '6' })
  986. utils.rpush_return(client, 'mixed', mixed, true)
  987. assert_equal(client:lrem('mixed', 2, '|'), 0)
  988. assert_table_values(client:lrange('mixed', 0, -1), mixed)
  989. assert_equal(client:lrem('doesnotexist', 2, '_'), 0)
  990. assert_error(function()
  991. client:set('foo', 'bar')
  992. client:lrem('foo', 0, 0)
  993. end)
  994. end)
  995. test("LPOP (client:lpop)", function()
  996. local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2', '3', '4' })
  997. assert_equal(client:lpop('numbers'), numbers[1])
  998. assert_equal(client:lpop('numbers'), numbers[2])
  999. assert_equal(client:lpop('numbers'), numbers[3])
  1000. assert_table_values(client:lrange('numbers', 0, -1), { '3', '4' })
  1001. client:lpop('numbers')
  1002. client:lpop('numbers')
  1003. assert_nil(client:lpop('numbers'))
  1004. assert_nil(client:lpop('doesnotexist'))
  1005. assert_error(function()
  1006. client:set('foo', 'bar')
  1007. client:lpop('foo')
  1008. end)
  1009. end)
  1010. test("RPOP (client:rpop)", function()
  1011. local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2', '3', '4' })
  1012. assert_equal(client:rpop('numbers'), numbers[5])
  1013. assert_equal(client:rpop('numbers'), numbers[4])
  1014. assert_equal(client:rpop('numbers'), numbers[3])
  1015. assert_table_values(client:lrange('numbers', 0, -1), { '0', '1' })
  1016. client:rpop('numbers')
  1017. client:rpop('numbers')
  1018. assert_nil(client:rpop('numbers'))
  1019. assert_nil(client:rpop('doesnotexist'))
  1020. assert_error(function()
  1021. client:set('foo', 'bar')
  1022. client:rpop('foo')
  1023. end)
  1024. end)
  1025. test("RPOPLPUSH (client:rpoplpush)", function()
  1026. local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2' }, true)
  1027. assert_equal(client:llen('temporary'), 0)
  1028. assert_equal(client:rpoplpush('numbers', 'temporary'), '2')
  1029. assert_equal(client:rpoplpush('numbers', 'temporary'), '1')
  1030. assert_equal(client:rpoplpush('numbers', 'temporary'), '0')
  1031. assert_equal(client:llen('numbers'), 0)
  1032. assert_equal(client:llen('temporary'), 3)
  1033. local numbers = utils.rpush_return(client, 'numbers', { '0', '1', '2' }, true)
  1034. client:rpoplpush('numbers', 'numbers')
  1035. client:rpoplpush('numbers', 'numbers')
  1036. client:rpoplpush('numbers', 'numbers')
  1037. assert_table_values(client:lrange('numbers', 0, -1), numbers)
  1038. assert_nil(client:rpoplpush('doesnotexist1', 'doesnotexist2'))
  1039. assert_error(function()
  1040. client:set('foo', 'bar')
  1041. client:rpoplpush('foo', 'hoge')
  1042. end)
  1043. assert_error(function()
  1044. client:set('foo', 'bar')
  1045. client:rpoplpush('temporary', 'foo')
  1046. end)
  1047. end)
  1048. test("BLPOP (client:blpop)", function()
  1049. if version:is('<', '2.0.0') then return end
  1050. -- TODO: implement tests
  1051. end)
  1052. test("BRPOP (client:brpop)", function()
  1053. if version:is('<', '2.0.0') then return end
  1054. -- TODO: implement tests
  1055. end)
  1056. test("BRPOPLPUSH (client:brpoplpush)", function()
  1057. if version:is('<', '2.1.0') then return end
  1058. -- TODO: implement tests
  1059. end)
  1060. test("LINSERT (client:linsert)", function()
  1061. if version:is('<', '2.1.0') then return end
  1062. utils.rpush_return(client, 'numbers', shared.numbers(), true)
  1063. assert_equal(client:linsert('numbers', 'before', 0, -2), 11)
  1064. assert_equal(client:linsert('numbers', 'after', -2, -1), 12)
  1065. assert_table_values(client:lrange('numbers', 0, 3), { '-2', '-1', '0', '1' });
  1066. assert_equal(client:linsert('numbers', 'before', 100, 200), -1)
  1067. assert_equal(client:linsert('numbers', 'after', 100, 50), -1)
  1068. assert_error(function()
  1069. client:set('foo', 'bar')
  1070. client:linsert('foo', 0, 0)
  1071. end)
  1072. end)
  1073. end)
  1074. context("Commands operating on sets", function()
  1075. test("SADD (client:sadd)", function()
  1076. assert_equal(client:sadd('set', 0), 1)
  1077. assert_equal(client:sadd('set', 1), 1)
  1078. assert_equal(client:sadd('set', 0), 0)
  1079. assert_error(function()
  1080. client:set('foo', 'bar')
  1081. client:sadd('foo', 0)
  1082. end)
  1083. end)
  1084. test("SREM (client:srem)", function()
  1085. utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4' })
  1086. assert_equal(client:srem('set', 0), 1)
  1087. assert_equal(client:srem('set', 4), 1)
  1088. assert_equal(client:srem('set', 10), 0)
  1089. assert_error(function()
  1090. client:set('foo', 'bar')
  1091. client:srem('foo', 0)
  1092. end)
  1093. end)
  1094. test("SPOP (client:spop)", function()
  1095. local set = utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4' })
  1096. assert_true(table.contains(set, client:spop('set')))
  1097. assert_nil(client:spop('doesnotexist'))
  1098. assert_error(function()
  1099. client:set('foo', 'bar')
  1100. client:spop('foo')
  1101. end)
  1102. end)
  1103. test("SMOVE (client:smove)", function()
  1104. utils.sadd_return(client, 'setA', { '0', '1', '2', '3', '4', '5' })
  1105. utils.sadd_return(client, 'setB', { '5', '6', '7', '8', '9', '10' })
  1106. assert_true(client:smove('setA', 'setB', 0))
  1107. assert_equal(client:srem('setA', 0), 0)
  1108. assert_equal(client:srem('setB', 0), 1)
  1109. assert_true(client:smove('setA', 'setB', 5))
  1110. assert_false(client:smove('setA', 'setB', 100))
  1111. assert_error(function()
  1112. client:set('foo', 'bar')
  1113. client:smove('foo', 'setB', 5)
  1114. end)
  1115. assert_error(function()
  1116. client:set('foo', 'bar')
  1117. client:smove('setA', 'foo', 5)
  1118. end)
  1119. end)
  1120. test("SCARD (client:scard)", function()
  1121. utils.sadd_return(client, 'setA', { '0', '1', '2', '3', '4', '5' })
  1122. assert_equal(client:scard('setA'), 6)
  1123. -- empty set
  1124. client:sadd('setB', 0)
  1125. client:spop('setB')
  1126. assert_equal(client:scard('doesnotexist'), 0)
  1127. -- non-existent set
  1128. assert_equal(client:scard('doesnotexist'), 0)
  1129. assert_error(function()
  1130. client:set('foo', 'bar')
  1131. client:scard('foo')
  1132. end)
  1133. end)
  1134. test("SISMEMBER (client:sismember)", function()
  1135. utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4', '5' })
  1136. assert_true(client:sismember('set', 3))
  1137. assert_false(client:sismember('set', 100))
  1138. assert_false(client:sismember('doesnotexist', 0))
  1139. assert_error(function()
  1140. client:set('foo', 'bar')
  1141. client:sismember('foo', 0)
  1142. end)
  1143. end)
  1144. test("SMEMBERS (client:smembers)", function()
  1145. local set = utils.sadd_return(client, 'set', { '0', '1', '2', '3', '4', '5' })
  1146. assert_table_values(client:smembers('set'), set)
  1147. if version:is('<', '2.0.0') then
  1148. assert_nil(client:smembers('doesnotexist'))
  1149. else
  1150. assert_table_values(client:smembers('doesnotexist'), {})
  1151. end
  1152. assert_error(function()
  1153. client:set('foo', 'bar')
  1154. client:smembers('foo')
  1155. end)
  1156. end)
  1157. test("SINTER (client:sinter)", function()
  1158. local setA = utils.sadd_return(client, 'setA', { '0', '1', '2', '3', '4', '5', '6' })
  1159. local setB = utils.sadd_return(client, 'setB', { '1', '3', '4', '6', '9', '10' })

Large files files are truncated, but you can click here to view the full file