* ACLTest.cs: chore: 完善 query 实现和测试

* LCObject.cs:
* QueryTest.cs:
* LCHttpClient.cs:
* LeanCloudJsonConverter.cs:
* LCCompositionalCondition.cs:
oneRain 2020-02-26 13:01:22 +08:00
parent 788f0bf1c3
commit 00941b3082
6 changed files with 292 additions and 85 deletions

View File

@ -0,0 +1,54 @@
using NUnit.Framework;
using System.Threading.Tasks;
using LeanCloud.Storage;
namespace LeanCloud.Test {
public class ACLTest {
[SetUp]
public void SetUp() {
Logger.LogDelegate += Utils.Print;
LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com");
}
[TearDown]
public void TearDown() {
Logger.LogDelegate -= Utils.Print;
}
[Test]
public async Task PrivateReadAndWrite() {
LCObject account = new LCObject("Account");
LCACL acl = new LCACL();
acl.PublicReadAccess = false;
acl.PublicWriteAccess = false;
account.ACL = acl;
account["balance"] = 1024;
await account.Save();
Assert.IsFalse(acl.PublicReadAccess);
Assert.IsFalse(acl.PublicWriteAccess);
}
[Test]
public async Task UserReadAndWrite() {
//await LCUser.Login('hello', 'world');
//LCObject account = new LCObject('Account');
//LCUser currentUser = await LCUser.getCurrent();
//LCACL acl = LCACL.createWithOwner(currentUser);
//account.acl = acl;
//account['balance'] = 512;
//await account.save();
//assert(acl.getUserReadAccess(currentUser) == true);
//assert(acl.getUserWriteAccess(currentUser) == true);
//LCQuery<LCObject> query = new LCQuery('Account');
//LCObject result = await query.get(account.objectId);
//print(result.objectId);
//assert(result.objectId != null);
//LCUser.logout();
//result = await query.get(account.objectId);
//assert(result == null);
}
}
}

View File

@ -1,121 +1,267 @@
using NUnit.Framework; using NUnit.Framework;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq; using LeanCloud.Storage;
using Newtonsoft.Json;
namespace LeanCloud.Test { namespace LeanCloud.Test {
public class QueryTest { public class QueryTest {
[SetUp] [SetUp]
public void SetUp() { public void SetUp() {
Utils.InitNorthChina(); Logger.LogDelegate += Utils.Print;
LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com");
}
[TearDown]
public void TearDown() {
Logger.LogDelegate -= Utils.Print;
} }
[Test] [Test]
public async Task BasicQuery() { public async Task BaseQuery() {
var query = new AVQuery<AVObject>("Account"); LCQuery<LCObject> query = new LCQuery<LCObject>("Hello");
query.WhereGreaterThanOrEqualTo("balance", 100); query.Limit(2);
query.WhereLessThanOrEqualTo("balance", 100); List<LCObject> list = await query.Find();
var results = await query.FindAsync(); TestContext.WriteLine(list.Count);
foreach (var result in results) { Assert.AreEqual(list.Count, 2);
TestContext.Out.WriteLine(result.ObjectId);
foreach (LCObject item in list) {
Assert.NotNull(item.ClassName);
Assert.NotNull(item.ObjectId);
Assert.NotNull(item.CreatedAt);
Assert.NotNull(item.UpdatedAt);
TestContext.WriteLine(item.ClassName);
TestContext.WriteLine(item.ObjectId);
TestContext.WriteLine(item.CreatedAt);
TestContext.WriteLine(item.UpdatedAt);
TestContext.WriteLine(item["intValue"]);
TestContext.WriteLine(item["boolValue"]);
TestContext.WriteLine(item["stringValue"]);
} }
} }
[Test] [Test]
public async Task Count() { public async Task Count() {
var query = new AVQuery<AVObject>("Foo"); LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
query.WhereEqualTo("content", "hello, world"); query.WhereGreaterThan("balance", 200);
var count = await query.CountAsync(); int count = await query.Count();
Assert.Greater(count, 8); TestContext.WriteLine(count);
Assert.Greater(count, 0);
} }
[Test] [Test]
public async Task Or() { public async Task OrderBy() {
AVQuery<AVObject> q1 = new AVQuery<AVObject>("Foo"); LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
q1.WhereEqualTo("content", "hello"); query.OrderBy("balance");
AVQuery<AVObject> q2 = new AVQuery<AVObject>("Foo"); List<LCObject> results = await query.Find();
q2.WhereEqualTo("content", "world"); Assert.LessOrEqual((int)results[0]["balance"], (int)results[1]["balance"]);
AVQuery<AVObject> query = AVQuery<AVObject>.Or(new List<AVQuery<AVObject>> { q1, q2 });
IEnumerable<AVObject> results = await query.FindAsync(); query = new LCQuery<LCObject>("Account");
foreach (AVObject result in results) { query.OrderByDescending("balance");
TestContext.Out.WriteLine(result.ObjectId); results = await query.Find();
Assert.GreaterOrEqual((int)results[0]["balance"], (int)results[1]["balance"]);
} }
[Test]
public async Task Include() {
LCQuery<LCObject> query = new LCQuery<LCObject>("Hello");
query.Include("objectValue");
LCObject hello = await query.Get("5e0d55aedd3c13006a53cd87");
LCObject world = hello["objectValue"] as LCObject;
TestContext.WriteLine(world["content"]);
Assert.AreEqual(world["content"], "7788");
}
[Test]
public async Task Get() {
LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
LCObject account = await query.Get("5e0d9f7fd4b56c008e5d048a");
Assert.AreEqual(account["balance"], 400);
}
[Test]
public async Task First() {
LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
LCObject account = await query.First();
Assert.NotNull(account.ObjectId);
}
[Test]
public async Task GreaterQuery() {
LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
query.WhereGreaterThan("balance", 200);
List<LCObject> list = await query.Find();
TestContext.WriteLine(list.Count);
Assert.Greater(list.Count, 0);
} }
[Test] [Test]
public async Task And() { public async Task And() {
AVQuery<AVObject> q1 = new AVQuery<AVObject>("Foo"); LCQuery<LCObject> q1 = new LCQuery<LCObject>("Account");
q1.WhereContains("content", "hello"); q1.WhereGreaterThan("balance", 100);
AVQuery<AVObject> q2 = new AVQuery<AVObject>("Foo"); LCQuery<LCObject> q2 = new LCQuery<LCObject>("Account");
q2.WhereContains("content", "world"); q2.WhereLessThan("balance", 500);
AVQuery<AVObject> query = AVQuery<AVObject>.And(new List<AVQuery<AVObject>> { q1, q2 }); LCQuery<LCObject> query = LCQuery<LCObject>.And(new List<LCQuery<LCObject>> { q1, q2 });
IEnumerable<AVObject> results = await query.FindAsync(); List<LCObject> results = await query.Find();
TestContext.Out.WriteLine($"Count: {results.Count()}"); TestContext.WriteLine(results.Count);
foreach (AVObject result in results) { results.ForEach(item => {
TestContext.Out.WriteLine(result.ObjectId); int balance = (int)item["balance"];
} Assert.IsTrue(balance >= 100 || balance <= 500);
});
} }
[Test] [Test]
public async Task OrPro() { public async Task Or() {
AVQuery<AVObject> q1 = AVQuery<AVObject>.Or(new List<AVQuery<AVObject>> { LCQuery<LCObject> q1 = new LCQuery<LCObject>("Account");
new AVQuery<AVObject>("Account").WhereEqualTo("balance", 100) q1.WhereLessThanOrEqualTo("balance", 100);
LCQuery<LCObject> q2 = new LCQuery<LCObject>("Account");
q2.WhereGreaterThanOrEqualTo("balance", 500);
LCQuery<LCObject> query = LCQuery<LCObject>.Or(new List<LCQuery<LCObject>> { q1, q2 });
List<LCObject> results = await query.Find();
TestContext.WriteLine(results.Count);
results.ForEach(item => {
int balance = (int)item["balance"];
Assert.IsTrue(balance <= 100 || balance >= 500);
}); });
AVQuery<AVObject> q2 = AVQuery<AVObject>.Or(new List<AVQuery<AVObject>> {
new AVQuery<AVObject>("Account").WhereEqualTo("balance", 200)
});
AVQuery<AVObject> query = AVQuery<AVObject>.Or(new List<AVQuery<AVObject>> {
q1, q2
});
query.WhereEqualTo("balance", 100);
IEnumerable<AVObject> results = await query.FindAsync();
foreach (AVObject result in results) {
TestContext.Out.WriteLine(result.ObjectId);
}
} }
[Test] [Test]
public async Task Related() { public async Task WhereObjectEquals() {
AVObject todo = AVObject.CreateWithoutData("Todo", "5d71f798d5de2b006c0136bc"); LCQuery<LCObject> worldQuery = new LCQuery<LCObject>("World");
AVQuery<AVObject> query = new AVQuery<AVObject>("Tag"); LCObject world = await worldQuery.Get("5e0d55ae21460d006a1ec931");
query.WhereRelatedTo(todo, "tags"); LCQuery<LCObject> helloQuery = new LCQuery<LCObject>("Hello");
IEnumerable<AVObject> results = await query.FindAsync(); helloQuery.WhereEqualTo("objectValue", world);
foreach (AVObject tag in results) { LCObject hello = await helloQuery.First();
TestContext.Out.WriteLine(tag.ObjectId); TestContext.WriteLine(hello.ObjectId);
} Assert.AreEqual(hello.ObjectId, "5e0d55aedd3c13006a53cd87");
} }
[Test] [Test]
public void Where() { public async Task Exist() {
AVQuery<AVObject> q1 = new AVQuery<AVObject>(); LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
q1.WhereEqualTo("aa", "bb"); query.WhereExists("user");
AVQuery<AVObject> q2 = new AVQuery<AVObject>(); List<LCObject> results = await query.Find();
q2.WhereEqualTo("cc", "dd"); results.ForEach(item => {
q2.WhereEqualTo("ee", "ff"); Assert.NotNull(item["user"]);
List<AVQuery<AVObject>> queryList = new List<AVQuery<AVObject>> { });
q1, q2
};
AVQuery<AVObject> query = AVQuery<AVObject>.Or(queryList);
IDictionary<string, object> obj = query.BuildWhere();
TestContext.Out.WriteLine(JsonConvert.SerializeObject(obj));
AVQuery<AVObject> q3 = new AVQuery<AVObject>(); query = new LCQuery<LCObject>("Account");
q3.WhereEqualTo("xx", "yy"); query.WhereDoesNotExist("user");
IDictionary<string, object> q3Obj = q3.BuildWhere(); results = await query.Find();
TestContext.Out.WriteLine(JsonConvert.SerializeObject(q3Obj)); results.ForEach(item => {
Assert.IsNull(item["user"]);
});
}
AVQuery<AVObject> q4 = new AVQuery<AVObject>(); [Test]
q4.WhereEqualTo("aaa", "bbb"); public async Task Select() {
q4.WhereEqualTo("ccc", "ddd"); LCQuery<LCObject> query = new LCQuery<LCObject>("Account");
IDictionary<string, object> q4Obj = q4.BuildWhere(); query.Select("balance");
TestContext.Out.WriteLine(JsonConvert.SerializeObject(q4Obj)); List<LCObject> results = await query.Find();
results.ForEach(item => {
Assert.NotNull(item["balance"]);
Assert.IsNull(item["user"]);
});
}
AVQuery<AVObject> q5 = new AVQuery<AVObject>(); [Test]
q5.WhereEqualTo("aaa", "bbb"); public async Task String() {
q5.WhereEqualTo("aaa", "ccc"); // Start
IDictionary<string, object> q5Obj = q5.BuildWhere(); LCQuery<LCObject> query = new LCQuery<LCObject>("Hello");
TestContext.Out.WriteLine(JsonConvert.SerializeObject(q5Obj)); query.WhereStartsWith("stringValue", "hello");
List<LCObject> results = await query.Find();
results.ForEach(item => {
string str = item["stringValue"] as string;
Assert.IsTrue(str.StartsWith("hello"));
});
// End
query = new LCQuery<LCObject>("Hello");
query.WhereEndsWith("stringValue", "world");
results = await query.Find();
results.ForEach(item => {
string str = item["stringValue"] as string;
Assert.IsTrue(str.EndsWith("world"));
});
// Contains
query = new LCQuery<LCObject>("Hello");
query.WhereContains("stringValue", ",");
results = await query.Find();
results.ForEach(item => {
string str = item["stringValue"] as string;
Assert.IsTrue(str.Contains(','));
});
}
[Test]
public async Task Array() {
// equal
LCQuery<LCObject> query = new LCQuery<LCObject>("Book");
query.WhereEqualTo("pages", 3);
List<LCObject>results = await query.Find();
results.ForEach(item => {
List<object> pages = item["pages"] as List<object>;
Assert.IsTrue(pages.Contains(3));
});
// contain all
List<int> containAlls = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
query = new LCQuery<LCObject>("Book");
query.WhereContainsAll("pages", containAlls);
results = await query.Find();
results.ForEach(item => {
List<object> pages = item["pages"] as List<object>;
pages.ForEach(i => {
Assert.IsTrue(pages.Contains(i));
});
});
// contain in
List<int> containIns = new List<int> { 4, 5, 6 };
query = new LCQuery<LCObject>("Book");
query.WhereContainedIn("pages", containIns);
results = await query.Find();
results.ForEach(item => {
List<object> pages = item["pages"] as List<object>;
bool f = false;
containIns.ForEach(i => {
f |= pages.Contains(i);
});
Assert.IsTrue(f);
});
// size
query = new LCQuery<LCObject>("Book");
query.WhereSizeEqualTo("pages", 7);
results = await query.Find();
results.ForEach(item => {
List<object> pages = item["pages"] as List<object>;
Assert.AreEqual(pages.Count, 7);
});
}
[Test]
public async Task Geo() {
LCObject obj = new LCObject("Todo");
LCGeoPoint location = new LCGeoPoint(39.9, 116.4);
obj["location"] = location;
await obj.Save();
// near
LCQuery<LCObject> query = new LCQuery<LCObject>("Todo");
LCGeoPoint point = new LCGeoPoint(39.91, 116.41);
query.WhereNear("location", point);
List<LCObject> results = await query.Find();
Assert.Greater(results.Count, 0);
// in box
query = new LCQuery<LCObject>("Todo");
LCGeoPoint southwest = new LCGeoPoint(30, 115);
LCGeoPoint northeast = new LCGeoPoint(40, 118);
query.WhereWithinGeoBox("location", southwest, northeast);
results = await query.Find();
Assert.Greater(results.Count, 0);
} }
} }
} }

View File

@ -118,7 +118,7 @@ namespace LeanCloud.Storage.Internal.Http {
try { try {
// 尝试获取 LeanCloud 返回错误信息 // 尝试获取 LeanCloud 返回错误信息
Dictionary<string, object> error = JsonConvert.DeserializeObject<Dictionary<string, object>>(resultString, new LeanCloudJsonConverter()); Dictionary<string, object> error = JsonConvert.DeserializeObject<Dictionary<string, object>>(resultString, new LeanCloudJsonConverter());
code = (int)(long)error["code"]; code = (int)error["code"];
message = error["error"].ToString(); message = error["error"].ToString();
} catch (Exception e) { } catch (Exception e) {
Logger.Error(e.Message); Logger.Error(e.Message);
@ -162,7 +162,7 @@ namespace LeanCloud.Storage.Internal.Http {
try { try {
// 尝试获取 LeanCloud 返回错误信息 // 尝试获取 LeanCloud 返回错误信息
Dictionary<string, object> error = JsonConvert.DeserializeObject<Dictionary<string, object>>(resultString, new LeanCloudJsonConverter()); Dictionary<string, object> error = JsonConvert.DeserializeObject<Dictionary<string, object>>(resultString, new LeanCloudJsonConverter());
code = (int)(long)error["code"]; code = (int)error["code"];
message = error["error"].ToString(); message = error["error"].ToString();
} catch (Exception e) { } catch (Exception e) {
Logger.Error(e.Message); Logger.Error(e.Message);

View File

@ -23,6 +23,11 @@ namespace LeanCloud.Storage.Internal {
serializer.Populate(reader, arr); serializer.Populate(reader, arr);
return arr; return arr;
} }
if (reader.TokenType == JsonToken.Integer) {
if ((long)reader.Value < int.MaxValue) {
return Convert.ToInt32(reader.Value);
}
}
return serializer.Deserialize(reader); return serializer.Deserialize(reader);
} }

View File

@ -72,7 +72,7 @@ namespace LeanCloud.Storage.Internal.Query {
} }
internal void WhereLessThan(string key, object value) { internal void WhereLessThan(string key, object value) {
AddOperation(key, "$lt$lt", value); AddOperation(key, "$lt", value);
} }
internal void WhereLessThanOrEqualTo(string key, object value) { internal void WhereLessThanOrEqualTo(string key, object value) {

View File

@ -57,6 +57,8 @@ namespace LeanCloud.Storage {
public LCACL ACL { public LCACL ACL {
get { get {
return this["ACL"] as LCACL ; return this["ACL"] as LCACL ;
} set {
this["ACL"] = value;
} }
} }