diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index 81e142e47f..341eeec2b8 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -1823,6 +1823,10 @@
True
True
+
+ True
+ True
+
True
True
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index d396f798a3..84a7ea1820 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -2535,6 +2535,9 @@
ripple\app\tx\tests
+
+ ripple\app\tx\tests
+
ripple\app\tx\tests
diff --git a/src/ripple/app/tx/tests/Offer.test.cpp b/src/ripple/app/tx/tests/Offer.test.cpp
new file mode 100644
index 0000000000..1835bac40e
--- /dev/null
+++ b/src/ripple/app/tx/tests/Offer.test.cpp
@@ -0,0 +1,101 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012-2015 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ripple {
+namespace test {
+
+/** An offer exists
+ */
+bool isOffer (jtx::Env const& env,
+ jtx::Account const& account,
+ STAmount const& takerPays,
+ STAmount const& takerGets)
+{
+ bool exists = false;
+ CachedView view(*env.ledger,
+ getApp().getSLECache());
+ forEachItem (view, account.id (),
+ [&](std::shared_ptr const& sle)
+ {
+ if (sle->getType () == ltOFFER &&
+ sle->getFieldAmount (sfTakerPays) == takerPays &&
+ sle->getFieldAmount (sfTakerGets) == takerGets)
+ exists = true;
+ });
+ return exists;
+}
+
+class Offer_test : public beast::unit_test::suite
+{
+public:
+ void testCanceledOffer ()
+ {
+ using namespace jtx;
+ Env env = *this;
+ auto const gw = Account ("gateway");
+ auto const USD = gw["USD"];
+
+ env.fund (XRP (10000), "alice", gw);
+ env.trust (USD (100), "alice");
+
+ env (pay (gw, "alice", USD (50)));
+
+ auto const firstOfferSeq = env.seq ("alice");
+ Json::StaticString const osKey ("OfferSequence");
+
+ env (offer ("alice", XRP (500), USD (100)),
+ require (offers ("alice", 1)));
+
+ expect (isOffer (env, "alice", XRP (500), USD (100)));
+
+ // cancel the offer above and replace it with a new offer
+ env (offer ("alice", XRP (300), USD (100)), json (osKey, firstOfferSeq),
+ require (offers ("alice", 1)));
+
+ expect (isOffer (env, "alice", XRP (300), USD (100)) &&
+ !isOffer (env, "alice", XRP (500), USD (100)));
+
+ // Test canceling non-existant offer.
+ env (offer ("alice", XRP (400), USD (200)), json (osKey, firstOfferSeq),
+ require (offers ("alice", 2)));
+
+ expect (isOffer (env, "alice", XRP (300), USD (100)) &&
+ isOffer (env, "alice", XRP (400), USD (200)));
+ }
+ void run ()
+ {
+ // Hack to silence logging
+ deprecatedLogs ().severity (beast::Journal::Severity::kNone);
+ testCanceledOffer ();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE (Offer, tx, ripple)
+
+} // test
+} // ripple
diff --git a/src/ripple/test/jtx/json.h b/src/ripple/test/jtx/json.h
index c25c3e4923..7aff994567 100644
--- a/src/ripple/test/jtx/json.h
+++ b/src/ripple/test/jtx/json.h
@@ -37,6 +37,12 @@ public:
explicit
json (std::string const&);
+ template
+ json (Json::StaticString const& key, T const& value)
+ {
+ jv_[key] = value;
+ }
+
void
operator()(Env const&, JTx& jt) const;
};
diff --git a/src/ripple/unity/app_tx.cpp b/src/ripple/unity/app_tx.cpp
index 63a1d88ef7..19e08712a0 100644
--- a/src/ripple/unity/app_tx.cpp
+++ b/src/ripple/unity/app_tx.cpp
@@ -46,4 +46,5 @@
#include
#include
#include
+#include
#include