Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit f723d93

Browse files
committed
Added stream command using simple syntax.
1 parent 24cea1c commit f723d93

9 files changed

+174
-2
lines changed

modem/commands.h

+7
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ class BeginCommand : public Command {
6666
std::unique_ptr<Firebase> new_firebase_;
6767
};
6868

69+
class StreamCommand : public Command {
70+
public:
71+
StreamCommand(Firebase* fbase) : Command(fbase) {}
72+
73+
bool execute(const String& command, InputStream* in, OutputStream* out);
74+
};
75+
6976
} // modem
7077
} // firebase
7178

modem/input-stream.h

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class InputStream {
1212
// This call consumes the terminator.
1313
virtual String readStringUntil(const char terminator) = 0;
1414
virtual void drain() = 0;
15+
virtual bool available() = 0;
1516
};
1617

1718
class ArduinoInputStream : public InputStream {
@@ -35,6 +36,10 @@ class ArduinoInputStream : public InputStream {
3536
}
3637
}
3738

39+
bool available() {
40+
return stream_->available();
41+
}
42+
3843
private:
3944
Stream* stream_;
4045
};

modem/output-stream.h

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace modem {
1010
class OutputStream {
1111
public:
1212
virtual int println(const String& string) = 0;
13+
virtual int println(const int value) = 0;
1314
virtual int print(const String& string) = 0;
1415
};
1516

@@ -21,6 +22,10 @@ class ArduinoOutputStream : public OutputStream {
2122
return stream_->println(string.c_str());
2223
}
2324

25+
int println(const int value) override {
26+
return stream_->println(value);
27+
}
28+
2429
int print(const String& string) override {
2530
return stream_->print(string.c_str());
2631
}

modem/stream-command.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "modem/commands.h"
2+
3+
namespace firebase {
4+
namespace modem {
5+
6+
bool StreamCommand::execute(const String& command,
7+
InputStream* in, OutputStream* out) {
8+
if (in == nullptr || out == nullptr) {
9+
return false;
10+
}
11+
12+
if (command != "BEGIN_STREAM") {
13+
return false;
14+
}
15+
16+
String path = in->readLine();
17+
std::unique_ptr<FirebaseStream> stream(fbase().streamPtr(path));
18+
19+
if (stream->error()) {
20+
out->print("-FAIL ");
21+
out->println(stream->error().message());
22+
return false;
23+
}
24+
25+
bool running = true;
26+
while(running) {
27+
if (stream->available()) {
28+
String json;
29+
FirebaseStream::Event event = stream->read(json);
30+
out->print("+");
31+
out->print(FirebaseStream::EventToName(event) + " ");
32+
// TODO(edcoyne): add json parsing and get real path.
33+
out->println("/dummy/path");
34+
out->println(json.length());
35+
out->println(json);
36+
} else if (in->available()) {
37+
String command = in->readLine();
38+
if (command == "END_STREAM") {
39+
running = false;
40+
} else {
41+
out->println("-FAIL Cannot call any command but END_STREAM.");
42+
}
43+
}
44+
}
45+
46+
return true;
47+
}
48+
49+
} // modem
50+
} // firebase

modem/test/Makefile

+10-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ CXXFLAGS += -g -Wall -Wextra -pthread -std=c++11
4848
# All tests produced by this Makefile. Remember to add new tests you
4949
# created to the list.
5050
TESTS = get-command_test set-command_test remove-command_test \
51-
push-command_test begin-command_test
51+
push-command_test begin-command_test stream-command_test
5252

5353
# All Google Test headers. Usually you shouldn't change this
5454
# definition.
@@ -183,4 +183,13 @@ begin-command_test : begin-command.o begin-command_test.o Firebase.o FirebaseHtt
183183
arduino_mock_all.a
184184
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
185185

186+
stream-command.o : $(PROJECT_ROOT)/modem/stream-command.cpp
187+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(PROJECT_ROOT)/modem/stream-command.cpp
188+
189+
stream-command_test.o : $(TEST_DIR)/stream-command_test.cpp $(GMOCK_HEADERS)
190+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/stream-command_test.cpp
191+
192+
stream-command_test : stream-command.o stream-command_test.o Firebase.o FirebaseHttpClient_dummy.o gmock_main.a \
193+
arduino_mock_all.a
194+
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
186195

modem/test/begin-command_test.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ using ::testing::Return;
1212
using ::testing::ByMove;
1313
using ::testing::ReturnRef;
1414
using ::testing::StartsWith;
15+
using ::testing::Matcher;
1516
using ::testing::_;
1617

1718
class BeginCommandTest : public ::testing::Test {
@@ -32,7 +33,9 @@ class BeginCommandTest : public ::testing::Test {
3233
}
3334

3435
void ExpectOutputStartsWith(const String& output) {
35-
EXPECT_CALL(out_, println(StartsWith(output)))
36+
// We have to be explicit here due to the polymorphic nature of println().
37+
const Matcher<const String&> matcher = StartsWith(output);
38+
EXPECT_CALL(out_, println(matcher))
3639
.WillOnce(Return(3));
3740
}
3841

modem/test/mock-input-stream.h

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class MockInputStream : public InputStream {
1212
MOCK_METHOD0(readLine, String ());
1313
MOCK_METHOD1(readStringUntil, String (const char));
1414
MOCK_METHOD0(drain, void ());
15+
MOCK_METHOD0(available, bool ());
1516
};
1617

1718
} // modem

modem/test/mock-output-stream.h

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace modem {
1010
class MockOutputStream : public OutputStream {
1111
public:
1212
MOCK_METHOD1(println, int (const String&));
13+
MOCK_METHOD1(println, int (const int));
1314
MOCK_METHOD1(print, int (const String&));
1415
};
1516

modem/test/stream-command_test.cpp

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "Firebase.h"
2+
#include "gtest/gtest.h"
3+
#include "modem/commands.h"
4+
#include "modem/test/mock-input-stream.h"
5+
#include "modem/test/mock-output-stream.h"
6+
#include "test/mock-firebase.h"
7+
8+
namespace firebase {
9+
namespace modem {
10+
11+
using ::testing::Return;
12+
using ::testing::Invoke;
13+
using ::testing::ByMove;
14+
using ::testing::ReturnRef;
15+
using ::testing::_;
16+
17+
class StreamCommandTest : public ::testing::Test {
18+
protected:
19+
void SetUp() override {
20+
stream_.reset(new MockFirebaseStream());
21+
}
22+
23+
bool RunCommand(const FirebaseError& error) {
24+
EXPECT_CALL(*stream_, error())
25+
.WillRepeatedly(ReturnRef(error));
26+
27+
EXPECT_CALL(fbase_, streamPtr(_))
28+
.WillOnce(Return(ByMove(std::move(stream_))));
29+
30+
StreamCommand cmd(&fbase_);
31+
return cmd.execute("BEGIN_STREAM", &in_, &out_);
32+
}
33+
34+
MockInputStream in_;
35+
MockOutputStream out_;
36+
MockFirebase fbase_;
37+
std::unique_ptr<MockFirebaseStream> stream_;
38+
};
39+
40+
TEST_F(StreamCommandTest, streams) {
41+
const String path("/test/path");
42+
EXPECT_CALL(in_, available())
43+
.WillRepeatedly(Return(true));
44+
45+
EXPECT_CALL(in_, readLine())
46+
.WillOnce(Return(path))
47+
.WillOnce(Return("END_STREAM"));
48+
49+
50+
const String value("Test value");
51+
EXPECT_CALL(*stream_, available())
52+
.WillOnce(Return(true))
53+
.WillRepeatedly(Return(false));
54+
55+
EXPECT_CALL(*stream_, read(_))
56+
.WillOnce(Invoke([&value](String& json) {
57+
json = value;
58+
return FirebaseStream::PUT;
59+
}));
60+
61+
EXPECT_CALL(out_, print(String("+")))
62+
.WillOnce(Return(1));
63+
EXPECT_CALL(out_, print(String("PUT ")))
64+
.WillOnce(Return(1));
65+
EXPECT_CALL(out_, println(String("/dummy/path")))
66+
.WillOnce(Return(1));
67+
68+
EXPECT_CALL(out_, println(value.length()))
69+
.WillOnce(Return(1));
70+
EXPECT_CALL(out_, println(value))
71+
.WillOnce(Return(1));
72+
73+
ASSERT_TRUE(RunCommand(FirebaseError()));
74+
}
75+
76+
TEST_F(StreamCommandTest, handlesError) {
77+
FirebaseError error(-200, "Test Error.");
78+
const String path("/test/path");
79+
EXPECT_CALL(in_, readLine())
80+
.WillOnce(Return(path));
81+
82+
EXPECT_CALL(out_, print(String("-FAIL ")))
83+
.WillOnce(Return(1));
84+
85+
EXPECT_CALL(out_, println(error.message()))
86+
.WillOnce(Return(1));
87+
ASSERT_FALSE(RunCommand(error));
88+
}
89+
90+
} // modem
91+
} // firebase

0 commit comments

Comments
 (0)