-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix_function_room.member_#173 #211
Conversation
Sorry, I found I fix what I need, but bring in other bug, so please wait until I fix all |
this commit can help to find member in room by nick/display/remark
|
@zixia
I didn't modify
Could you help me to fix? Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your PR looks workable, it's good.
However, part of them need to be redesign, please follow my reviews and follow them.
Thanks.
@@ -114,7 +122,7 @@ export class Room extends EventEmitter implements Sayable { | |||
const data = await contactGetter(this.id) | |||
log.silly('Room', `contactGetter(${this.id}) resolved`) | |||
this.rawObj = data | |||
this.obj = this.parse(data) | |||
this.obj = await this.parse(data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Create a new async function named
readyAllMembers()
, use it make all membersready()
for furture use. - Put
await readyAllMembers()
afterthis.rawObj = data
- Please keep
parse()
to be sync function instand of change it to be an async function. AlsoparseNickMap()
parseRemarkMap()
parseDisplayName()
should not be async function too. Because after introducedreadyAllMembers()
they are all ready to use.
this.rawObj = data await this.readyAllMembers(this.rawObj.MemberList)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you typo here..
Also parseNickMap() parseRemarkMap() parseDisplayName() should not be async function too.
you mean parseNickMap() parseRemarkMap() parseDisplayName() should be sync function?
const nickMap = this.parseNickMap(rawObj.MemberList) | ||
const nickMap = await this.parseNickMap(rawObj.MemberList) | ||
const remarkMap = await this.parseRemarkMap(rawObj.MemberList) | ||
const displayMap = await this.parseDisplayName(rawObj.MemberList) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of await(s) for parse...
functions.
member.DisplayName || member.NickName | ||
// @rui: cannot use argument NickName because it mix real nick and remark | ||
contact = Contact.load(member.UserName) | ||
await contact.ready() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete ready()
here, move the logic to readyAllMembers()
if (memberList && memberList.map) { | ||
for (let member of memberList) { | ||
contact = Contact.load(member.UserName) | ||
await contact.ready() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete ready()
here, move the logic to readyAllMembers()
*/ | ||
public member(name: string): Contact | null { | ||
log.verbose('Room', 'member(%s)', name) | ||
public member(quaryArg: MemberQueryFilter): Contact | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- When we rewrite a function, the best practice is to keep the old function parameters still work. So please keep
member(name: string)
for compatible. - when call
member(name:string)
, please search name as remark/display/nick, until we get the Contact(or null)
@@ -234,7 +234,7 @@ async function checkRoomJoin(m: Message): Promise<void> { | |||
} | |||
|
|||
if (!inviterContact) { | |||
inviterContact = room.member(inviter) | |||
inviterContact = room.member({remark: inviter}) || room.member({nick: inviter}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep room.member(inviteeList[i])
here, after you follow the review for member()
parameters suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.
I don't agree with this suggestion, because of the following reason:
We keep function room.member()
work, but it should work only with the function find member by nickName.
We cannot use it both find remark and nickName, because one can set a remark same as nick, then it would be confused.
So, what do you think about it?
@@ -316,7 +316,7 @@ async function checkRoomLeave(m: Message): Promise<void> { | |||
/** | |||
* FIXME: leaver maybe is a list | |||
*/ | |||
let leaverContact = room.member(leaver) | |||
let leaverContact = room.member({remark: leaver}) || room.member({nick: leaver}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep room.member(leaver)
here, after you follow the review for member()
parameters suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.
I don't agree with this suggestion, because of the following reason:
We keep function room.member()
work, but it should work only with the function find member by nickName.
We cannot use it both find remark and nickName, because one can set a remark same as nick, then it would be confused.
So, what do you think about it?
@@ -367,7 +366,7 @@ async function checkRoomTopic(m: Message): Promise<void> { | |||
if (/^You$/.test(changer) || /^你$/.test(changer)) { | |||
changerContact = Contact.load(this.userId) | |||
} else { | |||
changerContact = room.member(changer) | |||
changerContact = room.member({remark: changer}) || room.member({nick: changer}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep room.member(changer)
here, after you follow the review for member()
parameters suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.
I don't agree with this suggestion, because of the following reason:
We keep function room.member()
work, but it should work only with the function find member by nickName.
We cannot use it both find remark and nickName, because one can set a remark same as nick, then it would be confused.
So, what do you think about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why you copy/paste the same answer four times here?
I comment more than one times because I want to point out the position for you where needs to change.
What you were arguing about is not wrong, but it's not entirely right. Remember always to KISS(Keep It Simple, Stupid).
The most scenario is we just want to get a member by name(whatever remark/nick/display). I do not agree with you that "it should work only with the function find the member by nickname", instead it should return a contact with name match nick/display/remark. And If "one set a remark same as nick", then it's the time to use the new QueryFilter as the parameter to be more precise.
So just change it to what I said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have two questions:
1. room.member() should use which order?
I have found the rules of the name display order in wechat group's in #173 as follows:
Display order:
@ Event:displayName > nickName
system messageremark > nickName
on-screen Names:remark > displayName > nickName
I suggest choosing on-screen Name
, because it contains system message
and it is useful in firer.ts
2. Now room.member can just return one contact, should it return a contact list?
@@ -209,21 +221,53 @@ export class Room extends EventEmitter implements Sayable { | |||
return rawMemberList.map(m => Contact.load(m.UserName)) | |||
} | |||
|
|||
private parseNickMap(memberList: RoomRawMember[]): Map<string, string> { | |||
private async parseNickMap(memberList: RoomRawMember[]): Promise<Map<string, string>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use async
here. use readyMembers()
in my review suggestion instead.
@@ -182,14 +190,16 @@ export class Room extends EventEmitter implements Sayable { | |||
|
|||
public get(prop): string { return (this.obj && this.obj[prop]) || (this.dirtyObj && this.dirtyObj[prop]) } | |||
|
|||
private parse(rawObj: RoomRawObj): RoomObj | null { | |||
private async parse(rawObj: RoomRawObj): Promise<RoomObj | null> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep parse()
a sync function is better.
@zixia done for what you request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow my new reviews.
@@ -90,6 +98,15 @@ export class Room extends EventEmitter implements Sayable { | |||
// return this.load(contactGetter) | |||
// } | |||
|
|||
private async readyAllMembers(memberList: RoomRawMember[]): Promise<void> { | |||
let contact: Contact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of this line
private async readyAllMembers(memberList: RoomRawMember[]): Promise<void> { | ||
let contact: Contact | ||
for (let member of memberList) { | ||
contact = Contact.load(member.UserName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change this line to:
let contact = Contact.load(member.UserName)
because it's only used inside this closure.
@@ -114,6 +131,7 @@ export class Room extends EventEmitter implements Sayable { | |||
const data = await contactGetter(this.id) | |||
log.silly('Room', `contactGetter(${this.id}) resolved`) | |||
this.rawObj = data | |||
await this.readyAllMembers(this.rawObj.MemberList) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good
if (memberList && memberList.map) { | ||
memberList.forEach(member => { | ||
/** | ||
* ISSUE #64 emoji need to be striped | ||
* ISSUE #104 never use remark name because sys group message will never use that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep the original comments in the code, and add new comments if needed, for keep the history clear.(until someday we decide to clean them)
private parseNickMap(memberList: RoomRawMember[]): Map<string, string> { | ||
const nickMap: Map<string, string> = new Map<string, string>() | ||
|
||
let contact: Contact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move let
to be inside the closure.
private parseRemarkMap(memberList: RoomRawMember[]): Map<string, string> { | ||
const remarkMap: Map<string, string> = new Map<string, string>() | ||
let contact: Contact | ||
let remark: string | null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move let
to be inside the closure.
return remarkMap | ||
} | ||
|
||
private parseDisplayName(memberList: RoomRawMember[]): Map<string, string> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseRemarkMap & parseDisplayName has many duplicated code.
Please consider to be not duplicated that much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseRemarkMap & parseDisplayName has many duplicated code.
/**
* ISSUE #64 emoji need to be striped
* ISSUE #104 never use remark name because sys group message will never use that
*/
Actually, parseRemarkMap & parseDisplayName & parseNickMap has many duplicated code. So should I not duplicated all? Then maybe I cannot keep the original comments in the code...
log.verbose('Room', 'member(%s)', name) | ||
public member(queryArg: MemberQueryFilter | string): Contact | null { | ||
let query: MemberQueryFilter | ||
if (typeof queryArg === 'string') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to support member(name: string)
here, which name could be any of remark/display/nick.
/** | ||
* ISSUE #64 emoji need to be striped | ||
*/ | ||
name = UtilLib.stripEmoji(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notice this.
@zixia done as what you said. function use the order : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are almost done! Please apply the new suggestions.
Please also pay attention to the CI tests: at least you should pass one of them(Circle/Travis/Appveyor).
* ISSUE #104 never use remark name because sys group message will never use that | ||
* @rui: cannot use argument NickName because it mix real nick and remark | ||
*/ | ||
private parseMap(memberList: RoomRawMember[], parseContent: string): Map<string, string> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
type NameType = 'nick' | 'display' | 'remark'
Then change
parseContent: string
to
parseContent: NameType
if (parseContent === 'nick') { | ||
mapList[member.UserName] = UtilLib.stripEmoji(contact.name()) | ||
} else if (parseContent === 'remark') { | ||
mapList[member.UserName] = UtilLib.stripEmoji(contact.remark() || '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this part of code to this way:
let tmpName: string
switch (parseContent) {
case 'nick':
tmpName = contact.name()
break
case 'remark':
tmpName = contact.remark() || ''
break
default:
throw new Error('not found')
}
mapList[member.UserName] = UtilLib.stripEmoji(tmpName)
} | ||
|
||
private parseDisplayName(memberList: RoomRawMember[]): Map<string, string> { | ||
return this.parseMap(memberList, 'display') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get rid of unnessesary functions: parseNickMap / parseRemarkMap / parseDisplayName
use this.parseMap(memberList, 'display')
directly
@@ -190,6 +207,8 @@ export class Room extends EventEmitter implements Sayable { | |||
|
|||
const memberList = this.parseMemberList(rawObj.MemberList) | |||
const nickMap = this.parseNickMap(rawObj.MemberList) | |||
const remarkMap = this.parseRemarkMap(rawObj.MemberList) | |||
const displayMap = this.parseDisplayName(rawObj.MemberList) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of introduce new functions, use this.parseMap(memberList, 'display')
directly at here.
log.verbose('Room', 'member(%s)', name) | ||
public member(queryArg: MemberQueryFilter | string): Contact | null { | ||
if (typeof queryArg === 'string') { | ||
log.error('Room', 'function member should use member(queryArg: MemberQueryFilter)') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not use log.error()
here because it is not a bug/error, it's a feature.
@zixia Thanks for you advice, and I have done what you said. I'm sorry for not passing CI tests, I didn't use function
Could you help me? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your code looks cleaner now!
Please make the last change, and confirm the code is work without problem(also pass at least one CI test).
Then I'm going to merge it to master.
if (typeof queryArg === 'string') { | ||
log.verbose('Room', 'function member should use member(queryArg: MemberQueryFilter)') | ||
return this.member({remark: queryArg}) || this.member({display: queryArg}) || this.member({nick: queryArg}) | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove else
here, and get all the code in this block out.
*/ | ||
public member(name: string): Contact | null { | ||
log.verbose('Room', 'member(%s)', name) | ||
public member(queryArg: MemberQueryFilter | string): Contact | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add function declarations before function implement like this:
+ public member(filter: MemberQueryFilter): Contact | null
+ public member(name: string): Contact | null
+
public member(queryArg: MemberQueryFilter | string): Contact | null {
/** | ||
* ISSUE #64 emoji need to be striped | ||
*/ | ||
name = UtilLib.stripEmoji(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notice this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with contactGetter
is solved by the latest master with commit 279ff97
Now there's another bug with your PR at here: https://ci.appveyor.com/project/Wechaty/wechaty/build/283#L80
1. test » room » Room smoking test
AssertionError: should get nick1 from DisplayName
"" "田美坤"
test/room.spec.ts:104:5
Please fix it, and then check the CI result again.
the following bug is caused by
And I changed as you designed before, function |
After the commit, the error above disappear, but it still has an error:
Actually, I have tested, using function I thought because I changed some structure of the member obj, so the test data maybe outdated... |
After you fixed this, I believe this PR could be ready for merging. |
@zixia Finally, I found the reason for not passing the test.... I added Maybe you should mock some contact data corresponding the room member, then it can get the full contact data, and get the nickMap, then pass the test... |
Great. Could you modify the mock data in the unit test to add support for your new code? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Congratulations, you had your first version PR which passed CI test.
However, your unit test has not set the mock data correctly(some test code also need to be corrected).
Please follow all the reviews, and correct the mock data format.
Tip: Normally, I just use a console.log(JSON.stringify(contact))
to generate the json data, then I use this REAL data to be my mock data.
Looking forward to seeing your new unit test with the correct mock data!
|
||
public member(queryArg: MemberQueryFilter | string): Contact | null { | ||
if (typeof queryArg === 'string') { | ||
log.warn('Room', 'member(%s) DEPRECATED, use member(queryArg: MemberQueryFilter) instead.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be neither warn
nor DEPRECATED
.
@@ -356,26 +392,59 @@ export class Room extends EventEmitter implements Sayable { | |||
} | |||
|
|||
/** | |||
* NickName / DisplayName / RemarkName of member | |||
* find member by `nick`(NickName) / `display`(DisplayName) / `remark`(RemarkName) | |||
* when use member(name:string), find member by nickName by default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should by all
name by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you missed this review.
const RAW_OBJ = JSON.parse(` | ||
{"RemarkPYQuanPin":"","RemarkPYInitial":"","PYInitial":"TZZGQNTSHGFJ","PYQuanPin":"tongzhizhongguoqingniantianshihuiguanfangjia","Uin":0,"UserName":"@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278","NickName":"(通知)中国青年天使会官方家","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgetheadimg?seq=670397504&username=@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278&skey=","ContactFlag":2,"MemberCount":146,"MemberList":[{"Uin":0,"UserName":"@ecff4a7a86f23455dc42317269aa36ab","NickName":"童玮亮","AttrStatus":103423,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"dap","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ecff4a7a86f23455dc42317269aa36ab&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@eac4377ecfd59e4321262f892177169f","NickName":"麦刚","AttrStatus":33674247,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"mai","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@eac4377ecfd59e4321262f892177169f&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad85207730aa94e006ddce28f74e6878","NickName":"田美坤Maggie","AttrStatus":112679,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"田美坤","KeyWord":"tia","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad85207730aa94e006ddce28f74e6878&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":2351423900,"UserName":"@33cc239d22b20d56395bbbd0967b28b9","NickName":"周宏光","AttrStatus":327869,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"周宏光","KeyWord":"acc","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@33cc239d22b20d56395bbbd0967b28b9&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@5e77381e1e3b5641ddcee44670b6e83a","NickName":"牛文文","AttrStatus":100349,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"niu","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@5e77381e1e3b5641ddcee44670b6e83a&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@56941ef97f3e9c70af88667fdd613b44","NickName":"羊东 东方红酒窖","AttrStatus":33675367,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"Yan","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@56941ef97f3e9c70af88667fdd613b44&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@72c4767ce32db488871fdd1c27173b81","NickName":"李竹~英诺天使(此号已满)","AttrStatus":235261,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"liz","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@72c4767ce32db488871fdd1c27173b81&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@0b0e2eb9501ab2d84f9f800f6a0b4216","NickName":"周静彤 杨宁助理","AttrStatus":230885,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zlo","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@0b0e2eb9501ab2d84f9f800f6a0b4216&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@4bfa767be0cd3fb78409b9735d1dcc57","NickName":"周哲 Jeremy","AttrStatus":33791995,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zho","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@4bfa767be0cd3fb78409b9735d1dcc57&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad954bf2159a572b7743a5bc134739f4","NickName":"vicky张","AttrStatus":100477,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"hua","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad954bf2159a572b7743a5bc134739f4&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"}],"RemarkName":"","HideInputBarFlag":0,"Sex":0,"Signature":"","VerifyFlag":0,"OwnerUin":2351423900,"StarFriend":0,"AppAccountFlag":0,"Statues":0,"AttrStatus":0,"Province":"","City":"","Alias":"","SnsFlag":0,"UniFriend":0,"DisplayName":"","ChatRoomId":0,"KeyWord":"","EncryChatRoomId":"@4b8baa99bdfc354443711412126d2aaf","MMFromBatchGet":true,"MMOrderSymbol":"TONGZHIZHONGGUOQINGNIANTIANSHIHUIGUANFANGJIA","MMFromBatchget":true,"MMInChatroom":true} | ||
`) | ||
const RAW_OBJ = JSON.parse(`{"@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278":{"RemarkPYQuanPin":"","RemarkPYInitial":"","PYInitial":"TZZGQNTSHGFJ","PYQuanPin":"tongzhizhongguoqingniantianshihuiguanfangjia","Uin":0,"UserName":"@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278","NickName":"(通知)中国青年天使会官方家","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgetheadimg?seq=670397504&username=@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278&skey=","ContactFlag":2,"MemberCount":146,"MemberList":[{"Uin":0,"UserName":"@ecff4a7a86f23455dc42317269aa36ab","NickName":"童玮亮","AttrStatus":103423,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"dap","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ecff4a7a86f23455dc42317269aa36ab&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@eac4377ecfd59e4321262f892177169f","NickName":"麦刚","AttrStatus":33674247,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"mai","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@eac4377ecfd59e4321262f892177169f&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad85207730aa94e006ddce28f74e6878","NickName":"田美坤Maggie","AttrStatus":112679,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"田美坤","KeyWord":"tia","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad85207730aa94e006ddce28f74e6878&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":2351423900,"UserName":"@33cc239d22b20d56395bbbd0967b28b9","NickName":"周宏光","AttrStatus":327869,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"周宏光","KeyWord":"acc","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@33cc239d22b20d56395bbbd0967b28b9&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@5e77381e1e3b5641ddcee44670b6e83a","NickName":"牛文文","AttrStatus":100349,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"niu","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@5e77381e1e3b5641ddcee44670b6e83a&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@56941ef97f3e9c70af88667fdd613b44","NickName":"羊东 东方红酒窖","AttrStatus":33675367,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"Yan","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@56941ef97f3e9c70af88667fdd613b44&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@72c4767ce32db488871fdd1c27173b81","NickName":"李竹~英诺天使(此号已满)","AttrStatus":235261,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"liz","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@72c4767ce32db488871fdd1c27173b81&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@0b0e2eb9501ab2d84f9f800f6a0b4216","NickName":"周静彤 杨宁助理","AttrStatus":230885,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zlo","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@0b0e2eb9501ab2d84f9f800f6a0b4216&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@4bfa767be0cd3fb78409b9735d1dcc57","NickName":"周哲 Jeremy","AttrStatus":33791995,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zho","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@4bfa767be0cd3fb78409b9735d1dcc57&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad954bf2159a572b7743a5bc134739f4","NickName":"vicky张","AttrStatus":100477,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"hua","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad954bf2159a572b7743a5bc134739f4&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"}],"RemarkName":"","HideInputBarFlag":0,"Sex":0,"Signature":"","VerifyFlag":0,"OwnerUin":2351423900,"StarFriend":0,"AppAccountFlag":0,"Statues":0,"AttrStatus":0,"Province":"","City":"","Alias":"","SnsFlag":0,"UniFriend":0,"DisplayName":"","ChatRoomId":0,"KeyWord":"","EncryChatRoomId":"@4b8baa99bdfc354443711412126d2aaf","MMFromBatchGet":true,"MMOrderSymbol":"TONGZHIZHONGGUOQINGNIANTIANSHIHUIGUANFANGJIA","MMFromBatchget":true,"MMInChatroom":true},"@ad85207730aa94e006ddce28f74e6878":{"UserName": "@ad85207730aa94e006ddce28f74e6878","NickName": "田美坤Maggie","RemarkName": ""},"@72c4767ce32db488871fdd1c27173b81":{"UserName":"@72c4767ce32db488871fdd1c27173b81","NickName": "李竹~英诺天使(此号已满)","RemarkName": ""},"@ecff4a7a86f23455dc42317269aa36ab":{"UserName": "@ecff4a7a86f23455dc42317269aa36ab","NickName": "童玮亮","RemarkName": "童玮亮备注"}}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your modification made RAW_OBJ
data wrong.
RAW_OBJ should be the same structure with the JSON data comes from webwxApp. You can put any data in the struct, as long as your structure is the same as webwxApp.
What you changed here, is just make you happy and make your test code happy.
Please change the RAW_OBJ with a real room data instead.
throw new Error('no a or b') | ||
} | ||
t.is(contactA.id, EXPECTED.memberId1, 'should get the right id from nick 1') | ||
t.is(contactB.id, EXPECTED.memberId2, 'should get the right id from nick 2') | ||
t.is(contactC.id, EXPECTED.memberId3, 'should get the right id from nick 2') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please correct the descript, and let it include more details with your test purpose.
|
||
public member(queryArg: MemberQueryFilter | string): Contact | null { | ||
if (typeof queryArg === 'string') { | ||
log.warn('Room', 'member(%s) DEPRECATED, use member(queryArg: MemberQueryFilter) instead.', queryArg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get rid of this log.
member(string)
should not be DEPRECATED. it is a convenience way to find a contact by match name(display/remark/nick).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, I don't think so, it can confused the user... especially in the real using case....
but I will do as what you said, it's your code...
return this.member({remark: queryArg}) || this.member({display: queryArg}) || this.member({nick: queryArg}) | ||
} | ||
|
||
log.verbose('Room', 'member({ %s })' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use log.silly
instead of verbose
here.
verbose
should be used only once per function, usually at the beginning of the function, to log the function is run and all parameters it has received.
Any other log should be silly
Done as what you said, but I'm a little bit confused by the following code: const mockContactGetter = function (id) {
return new Promise((resolve, reject) => {
// if (id !== EXPECTED.id && !(id in CONTACT_LIST)) return resolve({})
if (id === EXPECTED.id) {
setTimeout(() => {
return resolve(RAW_OBJ)
}, 10)
}
if (id in CONTACT_LIST) {
setTimeout(() => {
return resolve(CONTACT_LIST[id])
}, 10)
}
return resolve({})
})
} it gets the following error: ✖ Room smoking test Error: Cannot read property 'Symbol(Symbol.iterator)' of undefined But when I change the code to the following: const mockContactGetter = function (id) {
return new Promise((resolve, reject) => {
if (id !== EXPECTED.id && !(id in CONTACT_LIST)) return resolve({})
if (id === EXPECTED.id) {
setTimeout(() => {
return resolve(RAW_OBJ)
}, 10)
}
if (id in CONTACT_LIST) {
setTimeout(() => {
return resolve(CONTACT_LIST[id])
}, 10)
}
})
} all works well. What I change is just adjust I googled the error and find this: this
But I still fell confused.. |
Great work! It is not perfect, but I think it mergeable now. BTW:
|
#173
#104