mudis 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,137 +1,137 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "spec_helper"
4
-
5
- RSpec.describe MudisClient do # rubocop:disable Metrics/BlockLength
6
- let(:socket_path) { "/tmp/mudis.sock" }
7
- let(:mock_socket) { instance_double(UNIXSocket) }
8
- let(:client) { MudisClient.new }
9
-
10
- around do |example|
11
- ClimateControl.modify("SOCKET_PATH" => socket_path) do
12
- example.run
13
- end
14
- end
15
-
16
- before do
17
- allow(UNIXSocket).to receive(:open).and_yield(mock_socket)
18
- end
19
-
20
- describe "#read" do
21
- it "sends a read command and returns the value" do
22
- payload = { cmd: "read", key: "test_key", namespace: nil }
23
- response = { ok: true, value: "test_value" }.to_json
24
-
25
- expect(mock_socket).to receive(:puts).with(payload.to_json)
26
- expect(mock_socket).to receive(:gets).and_return(response)
27
-
28
- expect(client.read("test_key")).to eq("test_value")
29
- end
30
- end
31
-
32
- describe "#write" do
33
- it "sends a write command and returns the value" do
34
- payload = { cmd: "write", key: "test_key", value: "test_value", ttl: nil, namespace: nil }
35
- response = { ok: true, value: nil }.to_json
36
-
37
- expect(mock_socket).to receive(:puts).with(payload.to_json)
38
- expect(mock_socket).to receive(:gets).and_return(response)
39
-
40
- expect(client.write("test_key", "test_value")).to be_nil
41
- end
42
- end
43
-
44
- describe "#delete" do
45
- it "sends a delete command and returns the value" do
46
- payload = { cmd: "delete", key: "test_key", namespace: nil }
47
- response = { ok: true, value: nil }.to_json
48
-
49
- expect(mock_socket).to receive(:puts).with(payload.to_json)
50
- expect(mock_socket).to receive(:gets).and_return(response)
51
-
52
- expect(client.delete("test_key")).to be_nil
53
- end
54
- end
55
-
56
- describe "#exists?" do
57
- it "sends an exists command and returns true" do
58
- payload = { cmd: "exists", key: "test_key", namespace: nil }
59
- response = { ok: true, value: true }.to_json
60
-
61
- expect(mock_socket).to receive(:puts).with(payload.to_json)
62
- expect(mock_socket).to receive(:gets).and_return(response)
63
-
64
- expect(client.exists?("test_key")).to eq(true)
65
- end
66
- end
67
-
68
- describe "#fetch" do
69
- it "fetches an existing value or writes a new one" do
70
- read_response = { ok: true, value: nil }.to_json
71
- write_payload = { cmd: "write", key: "test_key", value: "new_value", ttl: nil, namespace: nil }
72
- write_response = { ok: true, value: nil }.to_json
73
-
74
- expect(mock_socket).to receive(:puts).with({ cmd: "read", key: "test_key", namespace: nil }.to_json)
75
- expect(mock_socket).to receive(:gets).and_return(read_response)
76
- expect(mock_socket).to receive(:puts).with(write_payload.to_json)
77
- expect(mock_socket).to receive(:gets).and_return(write_response)
78
-
79
- result = client.fetch("test_key") { "new_value" } # rubocop:disable Style/RedundantFetchBlock
80
- expect(result).to eq("new_value")
81
- end
82
- end
83
-
84
- describe "#metrics" do
85
- it "sends a metrics command and returns the metrics" do
86
- payload = { cmd: "metrics" }
87
- response = { ok: true, value: { reads: 10, writes: 5 } }.to_json
88
-
89
- expect(mock_socket).to receive(:puts).with(payload.to_json)
90
- expect(mock_socket).to receive(:gets).and_return(response)
91
-
92
- expect(client.metrics).to eq({ reads: 10, writes: 5 })
93
- end
94
- end
95
-
96
- describe "#reset_metrics!" do
97
- it "sends a reset_metrics command" do
98
- payload = { cmd: "reset_metrics" }
99
- response = { ok: true, value: nil }.to_json
100
-
101
- expect(mock_socket).to receive(:puts).with(payload.to_json)
102
- expect(mock_socket).to receive(:gets).and_return(response)
103
-
104
- expect(client.reset_metrics!).to be_nil
105
- end
106
- end
107
-
108
- describe "#reset!" do
109
- it "sends a reset command" do
110
- payload = { cmd: "reset" }
111
- response = { ok: true, value: nil }.to_json
112
-
113
- expect(mock_socket).to receive(:puts).with(payload.to_json)
114
- expect(mock_socket).to receive(:gets).and_return(response)
115
-
116
- expect(client.reset!).to be_nil
117
- end
118
- end
119
-
120
- describe "error handling" do
121
- it "warns when the socket is missing" do
122
- allow(UNIXSocket).to receive(:open).and_raise(Errno::ENOENT)
123
-
124
- expect { client.read("test_key") }.to output(/Socket missing/).to_stderr
125
- expect(client.read("test_key")).to be_nil
126
- end
127
-
128
- it "raises an error when the server returns an error" do
129
- response = { ok: false, error: "Something went wrong" }.to_json
130
-
131
- expect(mock_socket).to receive(:puts)
132
- expect(mock_socket).to receive(:gets).and_return(response)
133
-
134
- expect { client.read("test_key") }.to raise_error("Something went wrong")
135
- end
136
- end
137
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "spec_helper"
4
+
5
+ RSpec.describe MudisClient do # rubocop:disable Metrics/BlockLength
6
+ let(:socket_path) { "/tmp/mudis.sock" }
7
+ let(:mock_socket) { instance_double(UNIXSocket) }
8
+ let(:client) { MudisClient.new }
9
+
10
+ around do |example|
11
+ ClimateControl.modify("SOCKET_PATH" => socket_path) do
12
+ example.run
13
+ end
14
+ end
15
+
16
+ before do
17
+ allow(UNIXSocket).to receive(:open).and_yield(mock_socket)
18
+ end
19
+
20
+ describe "#read" do
21
+ it "sends a read command and returns the value" do
22
+ payload = { cmd: "read", key: "test_key", namespace: nil }
23
+ response = { ok: true, value: "test_value" }.to_json
24
+
25
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
26
+ expect(mock_socket).to receive(:gets).and_return(response)
27
+
28
+ expect(client.read("test_key")).to eq("test_value")
29
+ end
30
+ end
31
+
32
+ describe "#write" do
33
+ it "sends a write command and returns the value" do
34
+ payload = { cmd: "write", key: "test_key", value: "test_value", ttl: nil, namespace: nil }
35
+ response = { ok: true, value: nil }.to_json
36
+
37
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
38
+ expect(mock_socket).to receive(:gets).and_return(response)
39
+
40
+ expect(client.write("test_key", "test_value")).to be_nil
41
+ end
42
+ end
43
+
44
+ describe "#delete" do
45
+ it "sends a delete command and returns the value" do
46
+ payload = { cmd: "delete", key: "test_key", namespace: nil }
47
+ response = { ok: true, value: nil }.to_json
48
+
49
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
50
+ expect(mock_socket).to receive(:gets).and_return(response)
51
+
52
+ expect(client.delete("test_key")).to be_nil
53
+ end
54
+ end
55
+
56
+ describe "#exists?" do
57
+ it "sends an exists command and returns true" do
58
+ payload = { cmd: "exists", key: "test_key", namespace: nil }
59
+ response = { ok: true, value: true }.to_json
60
+
61
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
62
+ expect(mock_socket).to receive(:gets).and_return(response)
63
+
64
+ expect(client.exists?("test_key")).to eq(true)
65
+ end
66
+ end
67
+
68
+ describe "#fetch" do
69
+ it "fetches an existing value or writes a new one" do
70
+ read_response = { ok: true, value: nil }.to_json
71
+ write_payload = { cmd: "write", key: "test_key", value: "new_value", ttl: nil, namespace: nil }
72
+ write_response = { ok: true, value: nil }.to_json
73
+
74
+ expect(mock_socket).to receive(:puts).with({ cmd: "read", key: "test_key", namespace: nil }.to_json)
75
+ expect(mock_socket).to receive(:gets).and_return(read_response)
76
+ expect(mock_socket).to receive(:puts).with(write_payload.to_json)
77
+ expect(mock_socket).to receive(:gets).and_return(write_response)
78
+
79
+ result = client.fetch("test_key") { "new_value" } # rubocop:disable Style/RedundantFetchBlock
80
+ expect(result).to eq("new_value")
81
+ end
82
+ end
83
+
84
+ describe "#metrics" do
85
+ it "sends a metrics command and returns the metrics" do
86
+ payload = { cmd: "metrics" }
87
+ response = { ok: true, value: { reads: 10, writes: 5 } }.to_json
88
+
89
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
90
+ expect(mock_socket).to receive(:gets).and_return(response)
91
+
92
+ expect(client.metrics).to eq({ reads: 10, writes: 5 })
93
+ end
94
+ end
95
+
96
+ describe "#reset_metrics!" do
97
+ it "sends a reset_metrics command" do
98
+ payload = { cmd: "reset_metrics" }
99
+ response = { ok: true, value: nil }.to_json
100
+
101
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
102
+ expect(mock_socket).to receive(:gets).and_return(response)
103
+
104
+ expect(client.reset_metrics!).to be_nil
105
+ end
106
+ end
107
+
108
+ describe "#reset!" do
109
+ it "sends a reset command" do
110
+ payload = { cmd: "reset" }
111
+ response = { ok: true, value: nil }.to_json
112
+
113
+ expect(mock_socket).to receive(:puts).with(payload.to_json)
114
+ expect(mock_socket).to receive(:gets).and_return(response)
115
+
116
+ expect(client.reset!).to be_nil
117
+ end
118
+ end
119
+
120
+ describe "error handling" do
121
+ it "warns when the socket is missing" do
122
+ allow(UNIXSocket).to receive(:open).and_raise(Errno::ENOENT)
123
+
124
+ expect { client.read("test_key") }.to output(/Socket missing/).to_stderr
125
+ expect(client.read("test_key")).to be_nil
126
+ end
127
+
128
+ it "raises an error when the server returns an error" do
129
+ response = { ok: false, error: "Something went wrong" }.to_json
130
+
131
+ expect(mock_socket).to receive(:puts)
132
+ expect(mock_socket).to receive(:gets).and_return(response)
133
+
134
+ expect { client.read("test_key") }.to raise_error("Something went wrong")
135
+ end
136
+ end
137
+ end
@@ -1,90 +1,90 @@
1
- # frozen_string_literal: true
2
-
3
- require "socket"
4
- require "json"
5
-
6
- require_relative "spec_helper"
7
-
8
- RSpec.describe MudisServer do # rubocop:disable Metrics/BlockLength
9
- let(:socket_path) { MudisServer::SOCKET_PATH }
10
-
11
- before do
12
- allow(Mudis).to receive(:read).and_return("mock_value")
13
- allow(Mudis).to receive(:write)
14
- allow(Mudis).to receive(:delete)
15
- allow(Mudis).to receive(:exists?).and_return(true)
16
- allow(Mudis).to receive(:fetch).and_return("mock_fetched_value")
17
- allow(Mudis).to receive(:metrics).and_return({ reads: 1, writes: 1 })
18
- allow(Mudis).to receive(:reset_metrics!)
19
- allow(Mudis).to receive(:reset!)
20
-
21
- # Start the server in a separate thread
22
- Thread.new { MudisServer.start! }
23
- sleep 0.1 # Allow the server to start
24
- end
25
-
26
- after do
27
- File.unlink(socket_path) if File.exist?(socket_path)
28
- end
29
-
30
- def send_request(request)
31
- UNIXSocket.open(socket_path) do |sock|
32
- sock.puts(JSON.dump(request))
33
- JSON.parse(sock.gets, symbolize_names: true)
34
- end
35
- end
36
-
37
- it "handles the 'read' command" do
38
- response = send_request({ cmd: "read", key: "test_key", namespace: "test_ns" })
39
- expect(response).to eq({ ok: true, value: "mock_value" })
40
- expect(Mudis).to have_received(:read).with("test_key", namespace: "test_ns")
41
- end
42
-
43
- it "handles the 'write' command" do
44
- response = send_request({ cmd: "write", key: "test_key", value: "test_value", ttl: 60, namespace: "test_ns" })
45
- expect(response).to eq({ ok: true })
46
- expect(Mudis).to have_received(:write).with("test_key", "test_value", expires_in: 60, namespace: "test_ns")
47
- end
48
-
49
- it "handles the 'delete' command" do
50
- response = send_request({ cmd: "delete", key: "test_key", namespace: "test_ns" })
51
- expect(response).to eq({ ok: true })
52
- expect(Mudis).to have_received(:delete).with("test_key", namespace: "test_ns")
53
- end
54
-
55
- it "handles the 'exists' command" do
56
- response = send_request({ cmd: "exists", key: "test_key", namespace: "test_ns" })
57
- expect(response).to eq({ ok: true, value: true })
58
- expect(Mudis).to have_received(:exists?).with("test_key", namespace: "test_ns")
59
- end
60
-
61
- it "handles the 'fetch' command" do
62
- response = send_request({ cmd: "fetch", key: "test_key", ttl: 60, namespace: "test_ns",
63
- fallback: "fallback_value" })
64
- expect(response).to eq({ ok: true, value: "mock_fetched_value" })
65
- expect(Mudis).to have_received(:fetch).with("test_key", expires_in: 60, namespace: "test_ns")
66
- end
67
-
68
- it "handles the 'metrics' command" do
69
- response = send_request({ cmd: "metrics" })
70
- expect(response).to eq({ ok: true, value: { reads: 1, writes: 1 } })
71
- expect(Mudis).to have_received(:metrics)
72
- end
73
-
74
- it "handles the 'reset_metrics' command" do
75
- response = send_request({ cmd: "reset_metrics" })
76
- expect(response).to eq({ ok: true })
77
- expect(Mudis).to have_received(:reset_metrics!)
78
- end
79
-
80
- it "handles the 'reset' command" do
81
- response = send_request({ cmd: "reset" })
82
- expect(response).to eq({ ok: true })
83
- expect(Mudis).to have_received(:reset!)
84
- end
85
-
86
- it "handles unknown commands" do
87
- response = send_request({ cmd: "unknown_command" })
88
- expect(response).to eq({ ok: false, error: "unknown command: unknown_command" })
89
- end
90
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "json"
5
+
6
+ require_relative "spec_helper"
7
+
8
+ RSpec.describe MudisServer do # rubocop:disable Metrics/BlockLength
9
+ let(:socket_path) { MudisServer::SOCKET_PATH }
10
+
11
+ before do
12
+ allow(Mudis).to receive(:read).and_return("mock_value")
13
+ allow(Mudis).to receive(:write)
14
+ allow(Mudis).to receive(:delete)
15
+ allow(Mudis).to receive(:exists?).and_return(true)
16
+ allow(Mudis).to receive(:fetch).and_return("mock_fetched_value")
17
+ allow(Mudis).to receive(:metrics).and_return({ reads: 1, writes: 1 })
18
+ allow(Mudis).to receive(:reset_metrics!)
19
+ allow(Mudis).to receive(:reset!)
20
+
21
+ # Start the server in a separate thread
22
+ Thread.new { MudisServer.start! }
23
+ sleep 0.1 # Allow the server to start
24
+ end
25
+
26
+ after do
27
+ File.unlink(socket_path) if File.exist?(socket_path)
28
+ end
29
+
30
+ def send_request(request)
31
+ UNIXSocket.open(socket_path) do |sock|
32
+ sock.puts(JSON.dump(request))
33
+ JSON.parse(sock.gets, symbolize_names: true)
34
+ end
35
+ end
36
+
37
+ it "handles the 'read' command" do
38
+ response = send_request({ cmd: "read", key: "test_key", namespace: "test_ns" })
39
+ expect(response).to eq({ ok: true, value: "mock_value" })
40
+ expect(Mudis).to have_received(:read).with("test_key", namespace: "test_ns")
41
+ end
42
+
43
+ it "handles the 'write' command" do
44
+ response = send_request({ cmd: "write", key: "test_key", value: "test_value", ttl: 60, namespace: "test_ns" })
45
+ expect(response).to eq({ ok: true })
46
+ expect(Mudis).to have_received(:write).with("test_key", "test_value", expires_in: 60, namespace: "test_ns")
47
+ end
48
+
49
+ it "handles the 'delete' command" do
50
+ response = send_request({ cmd: "delete", key: "test_key", namespace: "test_ns" })
51
+ expect(response).to eq({ ok: true })
52
+ expect(Mudis).to have_received(:delete).with("test_key", namespace: "test_ns")
53
+ end
54
+
55
+ it "handles the 'exists' command" do
56
+ response = send_request({ cmd: "exists", key: "test_key", namespace: "test_ns" })
57
+ expect(response).to eq({ ok: true, value: true })
58
+ expect(Mudis).to have_received(:exists?).with("test_key", namespace: "test_ns")
59
+ end
60
+
61
+ it "handles the 'fetch' command" do
62
+ response = send_request({ cmd: "fetch", key: "test_key", ttl: 60, namespace: "test_ns",
63
+ fallback: "fallback_value" })
64
+ expect(response).to eq({ ok: true, value: "mock_fetched_value" })
65
+ expect(Mudis).to have_received(:fetch).with("test_key", expires_in: 60, namespace: "test_ns")
66
+ end
67
+
68
+ it "handles the 'metrics' command" do
69
+ response = send_request({ cmd: "metrics" })
70
+ expect(response).to eq({ ok: true, value: { reads: 1, writes: 1 } })
71
+ expect(Mudis).to have_received(:metrics)
72
+ end
73
+
74
+ it "handles the 'reset_metrics' command" do
75
+ response = send_request({ cmd: "reset_metrics" })
76
+ expect(response).to eq({ ok: true })
77
+ expect(Mudis).to have_received(:reset_metrics!)
78
+ end
79
+
80
+ it "handles the 'reset' command" do
81
+ response = send_request({ cmd: "reset" })
82
+ expect(response).to eq({ ok: true })
83
+ expect(Mudis).to have_received(:reset!)
84
+ end
85
+
86
+ it "handles unknown commands" do
87
+ response = send_request({ cmd: "unknown_command" })
88
+ expect(response).to eq({ ok: false, error: "unknown command: unknown_command" })
89
+ end
90
+ end