久久精品中文字幕av,av.涩涩涩涩涩涩涩涩,亚洲国产日韩欧美精品成人久久久,成人福利电影免费在线观看,日产国产原创av,日韩av午夜激情,bt天堂中文字幕,超级碰人妻在线视频,欧美老熟妇久久一区二区

C層的功能相較于前面的單元較多,我們本次單元測試粒度最小化原則分別就:table列表、選擇班級組件、條件查詢以及分頁展開開發(fā)及單元測試。 # table列表 本組件中table列表將在以下幾種情況下更新:①組件初始化時 ②用戶點擊查詢按鈕時 ③用戶點擊分頁時。因此應該為table列表更新單獨建立一個方法,以滿足多條件下調用。 student/index/index.component.ts ``` export class IndexComponent implements OnInit { ... /** * 加載數據 */ loadData() { const queryParams = { // ① page: this.params.page, size: this.params.size, klassId: this.params.klass.id, ? name: this.params.name.value, sno: this.params.sno.value }; this.studentService.page(queryParams) .subscribe((response: { totalPages: number, content: Array<Student> }) => { this.pageStudent = response; }); } ngOnInit() { this.loadData(); } ``` * ① 構造適用于StudentService.page方法的類型 * ? 此處有錯誤,會觸發(fā)一個IDE的錯語提醒 ![](https://img.kancloud.cn/27/25/2725f88c227f17ce9c074501f88c56fa_668x95.png) ## `:`與`=` 在ts中`:`與`=`均可對變理進行定義。更確切的講`:`用來定義變量的類型;而`=`則是進行賦值,在賦值的過程中按賦的值的類型來確認變量的類型。 比如: ``` let a: number; // ① console.log(a); // ② a = 3; console.log(a); // 3 ``` * ① 定義a的類型為number,值為undefined * ② 打印undefined 以上代碼等價于: ``` let a = 3; // ① ``` * ① 由于3的類型是number,所以TS可以推斷中a的類型為number。 如果使用以下語句則會報錯: ![](https://img.kancloud.cn/5f/59/5f598907bbded2351e323b82792765e5_189x76.png) 將某個變量的賦值或聲明為對象也是同樣的道理。但由于`{}`在ts中的特殊性,在`:`與`=`分別代表不同的含意。比如: `a = {}`中的`{}`代表a的值是一個`空對象`,而`a: {}`中的`{}`代表a的類型是一個`對象類型` 所以當我們使用以下代碼時: ``` /* 查詢參數 */ params = { page: 0, size: 2, klass: Klass, name: new FormControl(), sno: new FormControl() }; ``` 由于使用是`params =`,那么此時`{}`代表一個對象,對`{}`中的值分別代表`屬性名`及`屬性值`。則上述代碼解讀為:params的值是一個對象,這個對象的page屬性的值為0,size屬性的值為2,klass屬性的**值**為Klass。 而這便是發(fā)生錯誤的源泉,我們使用`klass: Klass`的本意是:klass屬性的**類型**為Klass,而此時被ts解讀的含意與我們的本意并不相同。 假設我們使用`:`來替換`=`定義params的類型,則會發(fā)生以下錯誤: ![](https://img.kancloud.cn/63/30/633071fb565a1cbbeda668ce761b5b14_401x241.png) 這是由于當使用`params :`時,`{}`代表一個對象類型,而這個對象類型中的每一個,均代表`屬性名`及`屬性類型`,故上述代碼應該被解讀為:params的類型是一個對象,這個對象中的page屬性的類型是`0`, size的屬性是`2`,klass屬性是`Klass`,**name的屬性是`new FormControl()`**。由于`new FormControl()`并不能做為屬性類型出現,所以便發(fā)生了上圖的錯誤提示。我們可以將其改為: ``` params: { page: 0, size: 2, klass: Klass, name: FormControl, sno: FormControl }; ``` 此時錯誤提示消息。但由于`page: 0`被解讀為**page字段的類型為`0`**,所以當我們對其進行賦值時也會提示錯語: ![](https://img.kancloud.cn/a5/fb/a5fb01ecf74ce5e44ca8435d15ffb52e_645x136.png) 上述代碼將3賦予page屬性,但3的類型為number,而page屬性聲明類型為`0`。由于`number !== 0`,所以類型并不相符,進而發(fā)生了如上錯誤。這也是在初期使用ts進行變量的初始化時常常出現的問題,避免這個問題發(fā)生則需要記往以下規(guī)則:**賦值時使用常用的`=`,聲明類型時使用`:`** 則params初始化的代碼應該修正為: ``` /* 查詢參數 */ params = { page: 0, size: 2, klass: Klass, ? klass: new Klass(null , null, null), ? name: new FormControl(), sno: new FormControl() }; ``` ## 單元測試 在3.4.4小節(jié)中我們已經使用spy及Stub分別進行了組件依賴于服務的單元測試。spy的優(yōu)點在于可以更加輕松的構造測試服務;而Stub在于可以進行復用。所以如果在測試過程中我們的對某個服務僅依賴一次那么應該使用更為簡單的spy,如果我們不確定對該服務的依賴次數,那么推薦使用Stub。在此,我們使用Stub的方法來生成測試用的StudentService。使用終端來到app/service文件夾,并使用`ng g service studentStub --skip-tests`命令來生成一個供測試用的StudentStubService. ``` panjiedeMac-Pro:service panjie$ ng g service studentStub --skip-tests? CREATE src/app/service/student-stub.service.ts (140 bytes) panjiedeMac-Pro:service panjie$ ``` * ? 在生成時忽略生成單元測試文件 該服務僅用于單元測試,所以刪除`Injectable`注解后保留最原始的部分即可: ``` /** * 學生服務測試樁 */ export class StudentStubService { constructor() { } } ``` ### 增加測試方法page ``` /** * 學生服務測試樁 */ import {Observable, of★} from 'rxjs'; import {Student} from '../norm/entity/student'; import {Klass} from '../norm/entity/Klass'; export class StudentStubService { constructor() { } /* 傳入參數緩存 */ pageParamsCache: { sno?: string, name?: string, klassId?: number, page?: number, size?: number }; ① /** * page模擬方法 * @param params 查詢參數 */ page(params: { sno?: string, name?: string, klassId?: number, page?: number, size?: number }) : Observable<{ totalPages: number, content: Array<Student> }> { this.pageParamsCache = params; ① const mockResult = { ② totalPages: 100, content: new Array<Student>( new Student({id: 1, name: 'testStudent', sno: 'testStudentSno', klass: new Klass(1, 'testKlass', null)}), new Student({id: 2, name: 'testStudent1', sno: 'testStudentSno1', klass: new Klass(2, 'testKlass1', null)})) }; return of(mockResult)?; } } ``` * ① 參數緩存,用于斷言調用page方法時的傳入的參數是否符合預期 * ② 構造模擬返回結果 * ? 使用of()方法模擬返回觀察者對象 ### 使用Stub服務 有了模擬的學生服務后,我們在列表組件的測試方法中使用該模擬服務替換真實的服務: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [IndexComponent, KlassSelectComponent], imports: [ ReactiveFormsModule, FormsModule, CoreModule, HttpClientTestingModule], providers: [ {provide: StudentService, useClass: StudentStubService} ? ] }) .compileComponents(); })); ``` * ? 當測試中需要提供StudentService時,使用StudentStubService進行替換 為了確認上述替換服務的代碼是生效的,我們在組件的構造函數中打印該服務: student/index/index.component.spec.ts ``` constructor(private studentService: StudentService) { console.log(studentService); } ``` ![](https://img.kancloud.cn/32/5f/325faa334f0d311e09da5386b5304d6b_357x121.png) ## 測試TABLE初始化 Table初始化成功應該有以下標志:①使用預期的參數請求了StudentService(Stub) ② 正確地渲染了V層。下面我們按測試粒度最小化的原則,分別對上述兩點進行測試。 ### 發(fā)起請求測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('組件初始化發(fā)起請求測試', () => { /* 獲取請求參數 */ const studentService: StudentStubService = TestBed.get(StudentService); const queryParam = studentService.pageParamsCache; /* 斷言傳入的參數值與組件中的參數值相同 */ expect(queryParam.name).toEqual(component.params.name.value); expect(queryParam.sno).toEqual(component.params.sno.value); expect(queryParam.klassId).toEqual(component.params.klass.id); expect(queryParam.page).toEqual(component.params.page); expect(queryParam.size).toEqual(component.params.size); }); }); ``` ### 正確地渲染了V層 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('組件初始化V層渲染', () => { /* 獲取table元素 */ const tableElement = fixture.debugElement.query(By.css('table')); const table: HTMLTableElement = tableElement.nativeElement; /* 斷言總行數及第一行的內容綁定符合預期 */ const row = 1; let col = 0; expect(table.rows.length).toBe(3); expect(table.rows.item(row).cells.length).toBe(6); expect(table.rows.item(row).cells.item(col++).innerText).toBe(''); expect(table.rows.item(row).cells.item(col++).innerText).toBe('1'); expect(table.rows.item(row).cells.item(col++).innerText).toBe('testStudent'); expect(table.rows.item(row).cells.item(col++).innerText).toBe('testStudentSno'); expect(table.rows.item(row).cells.item(col++).innerText).toBe('testKlass'); expect(table.rows.item(row).cells.item(col++).innerText).toBe(''); }); }); ``` # 選擇班級組件 選擇班級組件依賴于core/select中的選擇組件,該組件在初始化時會像特定的URL進行相應的數據請求。所以如果需要在測試時使選擇班級組件生效,則需要對此URL請求設定模似返回值。 > **注意:** 受于篇幅的限制,引處采用了一種非常LOW的測試模式,將到在后面的教程中對其進行修正。 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('選擇班級組件', () => { /* 獲取請求 */ const httpTestingController = TestBed.get(HttpTestingController); const req: TestRequest = httpTestingController.expectOne('http://localhost:8080/Klass?name='); expect(req.request.method).toEqual('GET'); /* 模擬返回值 */ const mockResult = new Array<Klass>( new Klass(1, 'testKlass', null), new Klass(2, 'testKlass2', null) ); req.flush(mockResult); fixture.detectChanges(); ★ /* 獲取select元素 */ const debugElement = fixture.debugElement.query(By.css('select')); const select: HTMLSelectElement = debugElement.nativeElement; /* 選中首個選項 */ select.value = select.options[0].value; select.dispatchEvent(new Event('change')); fixture.detectChanges(); ★ /* 斷言選中的值傳給了C層 */ expect(component.params.klass).toEqual(mockResult[0]); }); }); ``` * ★ 數據發(fā)生變更后調用detectChanges()重新渲染界面 測試結果: ``` Error: Expected $.id = null to equal 1. Expected $.name = null to equal 'testKlass'. ``` 表明當用戶選擇完班級后并未將數據綁定到C層的查詢參數中。 ## 修正列表組件 在組件初始化的過程中并沒有編寫班級選擇組件的功能性代碼,遂導致了單元測試代碼未通過,修正如下: student/index/index.component.html ``` <label>班級:<app-klass-select [klass]="params.klass" (selected)="onSelectKlass($event)"?></app-klass-select></label> ``` student/index/index.component.ts ``` export class IndexComponent implements OnInit { ... /* 選擇班級 */ onSelectKlass(klass: Klass) { this.params.klass = klass; } } ``` 單元測試通過。說明選擇班級后對應將選擇的班級綁定到了C層。 # 條件查詢 在條件查詢的測試中,注意項為:① 姓名、學號兩個input是否成功的綁定到了C層 ② 點擊查詢按鈕后,是否成功地向M層發(fā)起了請求。 ## input綁定測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('姓名、學號input輸入測試', () => { /* 利用前期抽向出的表單測試類,對表單進行測試 */ const formTest = new FormTest(fixture); ① expect(formTest.setInputValue('input[name="name"]', 'studentName')).toBe(true);② expect(formTest.setInputValue('input[name="sno"]', 'studentSno')).toBe(true); fixture.detectChanges(); /* 斷言選中的值傳給了C層 */ expect(component.params.name.value).toEqual('studentName'); ③ expect(component.params.sno.value).toEqual('studentSno'); ③ }); }); ``` * ① 在構造函數中將當前夾具傳入 * ② 成功的對input賦值,將返回true * ③ 斷言對input設置的值,成功的傳遞給了C層 測試結果: ``` Error: Expected false to be true. ``` 顯示的該測試報告并不友好,我們僅知道在執(zhí)行formTest.setInputValue時未如期的返回正確的結果,卻無法直接的得到錯誤提示信息。 我們找到testing/FormTest.ts中對應的代碼段,發(fā)現只所以返回了false,是由于沒有根據css選擇器找到對應的html元素造成的。 testing/FormTest.ts ``` export class FormTest<T> { ... /** * 設置input的值 * @param fixture 夾具 * @param cssSelector CSS選擇器 * @param value 要設置的值 * @return 成功true 失敗false */ static setInputValue(fixture: ComponentFixture<any>, cssSelector: string, value: string): boolean { const selectorElement = this.getSelectorElement(fixture, cssSelector); if (isNull(selectorElement)) { return false; ★ } const htmlInputElement: HTMLInputElement = selectorElement.nativeElement; htmlInputElement.value = value; htmlInputElement.dispatchEvent(new Event('input')); return true; } ``` * ★ 當未找到相關元素時,返回了false。 ### Error 在typescript中,使用`throw new Error(String message)`來拋出異常信息: ``` export class FormTest<T> { ... static setInputValue(fixture: ComponentFixture<any>, cssSelector: string, value: string): boolean { ... if (isNull(selectorElement)) { return false; ? throw new Error(`未找到css選器${cssSelector}對應的html元素`); ? } } ``` 此時當在單元測試中發(fā)生未找到相關元素的情況時,便可以直接在單元測試的界面上查看到上述信息了。 ![](https://img.kancloud.cn/a8/e6/a8e6e649bed4af86c00823d455f70b36_401x82.png) 當然了,此時setInputValue方法描述也可由`執(zhí)行成功返回true,失敗返回false`同步變更為`執(zhí)行成功返回void,不成功拋出異常`了(暫時不變更)。 ### 修正組件 打開V層文件為input表單增加name屬性,這樣更加規(guī)范也更有利于測試。 student/index/index.component.html ``` <label>姓名:<input name="name"★ [formControl]="params.name" type="text" /></label> <label>學號:<input name="sno"★ [formControl]="params.sno" type="text" /></label> ``` * ★ 添加name屬性 ## 查詢按鈕測試 用戶點擊查詢按鈕后,應該測試以下兩點:① 查詢參數是否傳入M層 ② M層的返回值是否被組件接收 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { fit('查詢按鈕點擊測試', () => { /* 組件參數賦值 */ component.params.name.setValue('studentName'); component.params.sno.setValue('sno'); component.params.klass = new Klass(1, null, null); component.params.page = 3; component.params.size = 20; /* 點擊按鈕 */ const formTest = new FormTest(fixture); formTest.clickButton('button'); /* 獲取傳入參數 */ const studentService: StudentStubService = TestBed.get(StudentService); const queryParam = studentService.pageParamsCache; /* ①查詢參數是否傳入M層 */ expect(queryParam.name).toEqual(component.params.name.value); expect(queryParam.sno).toEqual(component.params.sno.value); expect(queryParam.klassId).toEqual(component.params.klass.id); expect(queryParam.page).toEqual(component.params.page); expect(queryParam.size).toEqual(component.params.size); /* ②M層的返回值是否被組件接收 */ }); }); ``` 測試結果: ``` Error: Expected null to equal 'studentName'. ``` ### 完善功能 該結果說明name查詢參數沒有并成功的傳入到StudentService,依此我們對應修正該組件代碼。 student/index/index.component.ts ``` export class IndexComponent implements OnInit { /* 查詢 */ onQuery() { this.loadData(); ① } ``` * ① 直接調用數據加載函數 # spyOn 代碼寫到這突然地發(fā)現如果繼續(xù)這么寫測試代碼的話,則會與組件初始化的代碼高度的相同。原因如下: ``` ngOnInit() { this.loadData(); } /* 查詢 */ onQuery() { this.loadData(); } ``` 在初始化及查詢的代碼中,我們均調用了`this.loadData()`方法。也就是說我們完成可以換一種思路進行測試:① 測試this.loadData()符合預期 ② 測試`ngOnInit()`方法成功的調用了`loadData()`方法 ③ 測試`onQuery()`方法成功的調用了`loadData()`方法。 ① 測試this.loadData()符合預期 我們已經在前面測試組件初始化時測試過了。那么②③這種方法的調用又該如何測試呢?為了解決這個問題,angular為我們提供了spyOn()方法。 ## 在方法上添加間諜 清空測試用例`查詢按鈕點擊測試`的代碼后,重新使用spyOn來進行組織。 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { fit('查詢按鈕點擊測試', () => { spyOn(component, 'onQuery'); ? /* 點擊按鈕 */ const formTest = new FormTest(fixture); formTest.clickButton('button'); expect(component.onQuery).toHaveBeenCalled(); /* 由于原onQuery()已經失效。所以點擊查詢按鈕雖然成功的觸發(fā)了onQuery()方法。但此方法卻是一個間諜,該間諜并沒有進行數據轉發(fā)? */ // expect(component.loadData).toHaveBeenCalled(); // 執(zhí)行此方法將得到一個異常,因為數據已被間諜攔截,該間諜并未調用loadData方法 }); }); ``` * ? 在組件的onQuery方法上設置間諜。當調用組件的onQuery()方法時,將由間諜提供服務。以此同時原onQuery()將失效 * ? 這像極了諜戰(zhàn)片:我們在敵人情報網的關鍵位置安插了一個間諜,此間諜得到情報后,選擇將情報就地銷毀而非向原組織的上級報告 ### 測試onQuery方法 具體onQuery是否調用了loadData,則可以新建另一個測試用例來完成測試。 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('onQuery', () => { spyOn(component, 'loadData'); component.onQuery(); expect(component.loadData).toHaveBeenCalled(); ① }); }); ``` * ① 斷言此loadData間諜被調用了1次 # 分頁 分頁是一款應用的必備功能,一個完善的分頁功能相對復雜,在此我們的目的完成一個**經典**款。和前面的單元測試思想相同,在測試中我們爭取把測試的粒度控制到最小。 ![](https://img.kancloud.cn/35/7e/357e5f986bfa78ccf6c4e273764e8e29_371x33.png) 依原型對①當前頁 ②總頁數 ③每頁大小 ④首頁 ⑤上一頁 ⑥頁碼 ⑦ 下一頁 ⑧尾頁 分別建立測試用例。 ## 引入bootstrap分頁樣式 在本章的第一節(jié)項目已經引入了流行的樣式bootstrap,分頁組件是bootstrap下標準的組件之一。在正式的開發(fā)分頁以前,我們找到bootstrap分頁組件的示例代碼,并嘗試將其引入到當前組件中: ``` </table> <div *ngIf="pageStudent">第{{params.page}}/{{pageStudent.totalPages}}頁 每頁{{params.size}}條 首頁 上一頁 1 2 3 下一頁 尾頁</div>? <div *ngIf="pageStudent" class="row"> ? <div class="col-4"> 第{{params.page}}/{{pageStudent.totalPages}}頁 每頁{{params.size}}條 </div> <div class="col-8"> <nav> <ul class="pagination"> <li class="page-item disabled"> <span class="page-link">Previous</span> </li> <li class="page-item"><a class="page-link" href="#">1</a></li> <li class="page-item active"> <span class="page-link"> 2 <span class="sr-only">(current)</span> </span> </li> <li class="page-item"><a class="page-link" href="#">3</a></li> <li class="page-item"> <a class="page-link" href="#">Next</a> </li> </ul> </nav> </div> </div> ? ``` 效果如下: ![](https://img.kancloud.cn/05/f7/05f7adba4f870c7e23480c8f8ccd6ecf_768x172.png) ## 當前頁、總頁數、每頁大小 在單元測試中如果想到某個元素進行測試并斷言,前提是可能精確的在頁面中的找到該元素。為此,我們?yōu)榉猪撔畔⒃黾觟d屬性: student/index/index.component.html ``` <div class="col-4" id="pageInfo★"> 第{{params.page}}/{{pageStudent.totalPages}}頁 每頁{{params.size}}條 </div> ``` * ★ 定義id ### 單元測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('當前頁、總頁數、每頁大小', () => { /* 獲取分頁信息 */ const debugElement = fixture.debugElement.query(By.css('#pageInfo')); const pageInfoDiv: HTMLDivElement = debugElement.nativeElement; const text = pageInfoDiv.textContent; ? console.log(text); ① /* 斷言綁定了C層的分頁值 */ expect(text).toContain(`第${component.params.page}/${component.pageStudent.totalPages}頁`); ? expect(text).toContain(`每頁${component.params.size}條`); }); }); ``` * ? 獲取div元素中的文本內容 * ① 首次使用在控制臺打印其信息,以更好的掌握該數據值 * ? 斷言獲取的字符串中包含了預期的值 ## 首頁 首頁主要考慮幾個功能點:①當前頁如果就是首頁,則該按鈕應該被禁用 ②當擊首頁按鈕成功設置C導層params.page = 0 ③ 點擊后重新發(fā)起數據請求。首次進行類似功能的開發(fā),開發(fā)步驟為:先開發(fā)功能代碼再按測試代碼進行功能修正。 ### 功能代碼 student/index/index.component.html ``` ... <ul class="pagination"> <li class="page-item" [ngClass]="{'disabled': params.page === 0}"? (click)="onPage(0)"①> <span class="page-link">Previous</span> ? <span class="page-link">首頁</span> ? </li> ... ``` * ? 動態(tài)設置宿主元素(li)的樣式值,當params.page的值為0時,添加disabled樣式 * ① 點擊該元素時,向C層傳值 對應的C層代碼: student/index/index.component.ts ``` export class IndexComponent implements OnInit { ... /** * 點擊分頁按鈕 * @param page 要請求的頁碼 */ onPage(page: number) { this.params.page = page; this.loadData(); } } ``` ### 樣式測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('分頁 -> 首頁樣式測試', () => { /* 獲取首頁按鈕 */ const debugElement = fixture.debugElement.query(By.css('ul.pagination > li:first-child')); const htmlliElement: HTMLLIElement? = debugElement.nativeElement; console.log(htmlliElement);① /* 當前頁為首頁,則添加禁用樣式 */ component.params.page = 0; fixture.detectChanges(); ★ expect(htmlliElement.classList.contains('disabled')).toBe(true); ? /* 當前頁非首頁,則移除禁用樣式 */ component.params.page = 1; fixture.detectChanges(); ★ expect(htmlliElement.classList.contains('disabled')).toBe(false); ? }); }); ``` * ? Li元素 * ① 首次或不太熟悉時,打印元素到控制臺以查看詳情 * ? 斷言樣式中包括disabled * ? 斷言樣式中不包括disabled ### 點擊測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('分頁 -> 點擊首頁測試', () => { spyOn(component, 'onPage'); ① /* 獲取首頁按鈕并點擊 */ const formTest = new FormTest(fixture); formTest.clickButton('ul.pagination > li:first-child'); expect(component.onPage).toHaveBeenCalledWith(0);? }); ``` * ① 建立間諜 * ? 斷言onPage方法被調用,而且被調用時傳入的參數值為0 ### onPage功能測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('onPage 功能測試', () => { spyOn(component, 'loadData'); ① component.params.page = 4; ② component.onPage(3); ③ expect(component.params.page).toEqual(3); ④ expect(component.loadData).toHaveBeenCalled(); ⑤ }); ``` * ① 建立間諜 * ② 初始化page * ③ 調用 * ④ 對結果進行斷言 * ⑤ 對調用loadData方法進行斷言 ## 上一頁 功能點:①當前頁為首頁時,禁用 ②調用onPage方法,傳入值為當前頁 -1 ### 功能開發(fā) student/index/index.component.ts ``` <nav> <ul class="pagination"> <li class="page-item" [ngClass]="{'disabled': params.page === 0}" (click)="onPage(0)"> <span class="page-link">首頁</span> </li> <li class="page-item" [ngClass]="{'disabled': params.page === 0}" (click)="onPage(params - 1)"①> <span class="page-link">上一頁</span> </li> ``` * ① 將當前頁-1后傳入 ### 樣式測試 由于前面已經測試onPage方法是否可能的調用了loadData方法,所以此處我們只需要測試onPage方法的傳入值是否正確即可。 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('上一頁 樣式測試', () => { /* 獲取首頁按鈕 */ const debugElement = fixture.debugElement.query(By.css('ul.pagination > li:nth-child(2)')); ? const htmlliElement: HTMLLIElement = debugElement.nativeElement; console.log(htmlliElement); /* 當前頁為首頁,則添加禁用樣式 */ component.params.page = 0; fixture.detectChanges(); expect(htmlliElement.classList.contains('disabled')).toBe(true); /* 當前頁非首頁,則移除禁用樣式 */ component.params.page = 1; fixture.detectChanges(); expect(htmlliElement.classList.contains('disabled')).toBe(false); }); }); ``` * ? nth-child(n)表示選中第n個元素,但與我們習慣的0基不同,該選擇器是1基的。如果我們選擇第2個li元素則直接輸入2即可,無需進行減1處理。 ### 點擊測試 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('上一頁 點擊測試', () => { spyOn(component, 'onPage'); component.params.page = 3; ① fixture.detectChanges(); /* 獲取上一頁按鈕并點擊 */ const formTest = new FormTest(fixture); formTest.clickButton('ul.pagination > li:nth-child(2)'); ② expect(component.onPage).toHaveBeenCalledWith(2); }); }); ``` * ① 當前頁為3,則上一頁按鈕可點擊 * ② 點擊上一頁 * ③ 斷言傳入的參數值為2(第3頁的上一頁為第2頁) 測試結果我們得到了如下異常: ``` Error: Expected spy onPage to have been called with [ 2 ] but actual calls were [ NaN ]. ``` 通過檢查V層的代碼我們發(fā)現誤把`params.page - 1`寫成了`params`。 修正如下: student/index/index.component.ts ``` <li class="page-item" [ngClass]="{'disabled': params.page === 0}" (click)="onPage(params - 1)"> ? <li class="page-item" [ngClass]="{'disabled': params.page === 0}" (click)="onPage(params.page - 1)"> ? <span class="page-link">上一頁</span> </li> ``` 修正后單元測試通過。 ## 頁碼C層 在實現頁碼的功能時,我們首先想到的是使用類似于`for(let i = 0; i < totalPages; i++)`的形式在前臺來循環(huán)輸出各個頁碼,但angular的ngFor并不支持這樣做,所以我們換一種思路:在C層中生成頁碼的數組,比如我們需要1,2,3,4,5頁,則在C層中生成Array(1,2,3,4,5);然后在前臺使用ngFor來循環(huán)輸出該數組。 頁碼所需要考慮的問題較多,在開始之前需要簡單的想一下我們所需要處理的問題 -- Head First, Coding Second。 * 輸出的頁碼總數最多不超過N(暫時設定為5)個??傢摂挡怀^5頁時,全部輸出,總頁數大于5頁時,則最多輸出5頁。比如共20頁,當前頁為第10頁,則輸出為: 8 9 10 11 12 * 當前頁禁止點擊,其它頁可點擊,比如:[2] [3] 4 [5] [6] * 當前頁起始2頁時,比如當前頁為2,則顯示為:[1] 2 [3] [4] [5] * 當前頁為終了2頁時,比如共10頁,當前頁為最后1頁,則顯示為:[6] [7] [8] [9] 10 為此,擬制流程圖如下: ![](https://img.kancloud.cn/a7/60/a760ae63ae17a053b0dc57a5bcd39962_642x704.png) 該流程圖主要有幾個判斷語句及一個生成X到Y的數組的方法組成,依此接下來按流程分步進行開發(fā)。 ### 生成由X到Y的數組 student/index/index.component.ts ``` export class IndexComponent implements OnInit { ... /** * 生成頁碼 * @param begin 開始頁碼 * @param end 結束頁碼 */ makePages(begin: number, end: number): Array<number> { const result = new Array<number>(); for (; begin <= end; begin++) { result.push(begin); } return result; } } ``` 接下來對此功能進行測試: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('makePages', () => { /* 更好的做法是使用兩個隨機的數字進行測試 */ const result = component.makePages(0, 4); expect(result.length).toEqual(5); /* 斷言起始為0 */ expect(result[0]).toEqual(0); /* 斷言后一個元素比前一個元素大1 */ for (let i = 0; i < 4; i++) { expect(result[i] + 1).toEqual(result[i + 1]); } }); }); ``` ### 按總頁數生成分頁數據 有了按起始值生成分頁數組的方法后,按流程圖繼承新建根據當前頁及總頁數的不同值來生成分頁數組。 student/index/index.component.ts ``` export class IndexComponent implements OnInit { /* 分頁數據 */ pages: Array<number>; ... /** * 生成分頁數據 * @param currentPage 當前頁 * @param totalPages 總頁數 */ makePagesByTotalPages(currentPage: number, totalPages: number): Array<number> { if (totalPages > 0) { /* 總頁數小于5 */ if (totalPages <= 5) { return this.makePages(0, totalPages); } /* 首2頁 */ if (currentPage < 2) { return this.makePages(0, 5); } /* 尾2頁 */ if (currentPage > totalPages - 3) { return this.makePages(totalPages - 5, totalPages - 1); } /* 總頁數大于5,且為中間頁碼*/ return this.makePages(currentPage - 2, currentPage + 2); } return new Array(); } ``` 此方法有多種條件,我們力求在單元測試中使用不同的測試數據調用該方法而使得該方法中所有的IF條件中的代碼均被執(zhí)行一次,達到測試覆蓋率為100%的目標。 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('makePagesByTotalPages', () => { /* 總頁數為0 */ expect(component.makePagesByTotalPages(0, 0).length).toEqual(0); /* 總頁數小于等于5 */ expect(component.makePagesByTotalPages(2, 5).length).toEqual(5); expect(component.makePagesByTotalPages(2, 5)[0]).toEqual(0); /* 總頁數大于5,首2頁 */ expect(component.makePagesByTotalPages(1, 10).length).toEqual(5); expect(component.makePagesByTotalPages(1, 10)[4]).toEqual(4); /* 總頁數大于5,尾2頁 */ expect(component.makePagesByTotalPages(8, 10).length).toEqual(5); expect(component.makePagesByTotalPages(8, 10)[4]).toEqual(9); /* 總頁數大于5, 中間頁 */ expect(component.makePagesByTotalPages(5, 10).length).toEqual(5); expect(component.makePagesByTotalPages(5, 10)[0]).toEqual(3); }); }); ``` 保存文件后單元測試自動運行,同時反饋給了我們的一個錯誤: ![](https://img.kancloud.cn/01/e1/01e1e06dbd40582f5aa120956f8fc2d4_997x105.png) 該錯誤提示:測試代碼中預期的值為5,但實際的返回是6。該錯誤位于:index.component.spec.ts文件夾的第234行(由于你的學習的代碼與教程中的不可能完全一樣,所以你本地提示的行數可能是其它值,這是正常的): student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... ... /* 總頁數小于等于5 */ expect(component.makePagesByTotalPages(2, 5).length).toEqual(5); ★ expect(component.makePagesByTotalPages(2, 5)[0]).toEqual(0); ``` 為了更清晰的得知調用component.makePagesByTotalPages(2, 5)的返回值,在此行上加入console.log來進行數據打?。?student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... ... /* 總頁數小于等于5 */ console.log(component.makePagesByTotalPages(2, 5)); ? expect(component.makePagesByTotalPages(2, 5).length).toEqual(5); ★ expect(component.makePagesByTotalPages(2, 5)[0]).toEqual(0); ``` 打印的值如下: ``` LOG: [0, 1, 2, 3, 4, 5] ``` 當調用`component.makePagesByTotalPages(2, 5)`時表示當前頁為第3頁,總頁數為5頁。則期待打印的數組值應該:`[0,1, 2, 3, 4]`。故此得知在相應的代碼進行數據輸出時,終止的值應該在原值的基礎上做-1處理?;貋砉δ艽a進行修正: student/index/index.component.ts ``` export class IndexComponent implements OnInit { ... /* 總頁數小于5 */ if (totalPages <= 5) { return this.makePages(0, totalPages); ? return this.makePages(0, totalPages - 1); ? } ``` 再次運行單元測試,發(fā)現仍有錯誤報出: ![](https://img.kancloud.cn/c3/bb/c3bb6b6db7a17603bfce5828f01576fa_926x87.png) 依照剛才的方法,再次進行修正: student/index/index.component.ts ``` export class IndexComponent implements OnInit { ... /* 首2頁 */ if (currentPage < 2) { return this.makePages(0, 5); ? return this.makePages(0, 4); ? } ``` 最終測試通過。表明在C層中編寫的功能性代碼是符合預期的,這正是單元測試的魅力所在:在代碼編寫階段發(fā)現并及時的修正錯誤。 ### V層綁定 最后,我們在每次數據加載完成后調用此頁碼生成方法,并將其返回值綁定給V層: student/index/index.component.ts ``` export class IndexComponent implements OnInit { /* 分頁數據 */ pages: Array<number>; ① ... loadData() { ... this.studentService.page(queryParams) .subscribe((response: { totalPages: number, content: Array<Student> }) => { this.pageStudent = response; this.pages = this.makePagesByTotalPages(this.params.page, response.totalPages); ② }); } ``` * ① 使用`:`來定義數據類型 * ② 每次數據重新加載后,重新生成分頁信息 student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('loadData', () => { const mockResult = new Array<number>(); ① spyOn(component, 'makePagesByTotalPages').and.returnValue(mockResult); ② component.loadData(); expect(component.makePagesByTotalPages).toHaveBeenCalled(); expect(component.pages).toBe(mockResult); ③ }); ``` * ① 初始化模擬返回值 * ② 建立間諜并設置該間諜的返回值(當該間諜被調用時,以此值返回給調用者) * ③ `toBe` = `就是`。斷言當前組件的分頁信息就是剛剛間諜設置的返回值 ## 頁碼V層 C層的功能完成后,繼續(xù)來完成V層。V層的主要功能是根據C層的pages值及當前頁進行渲染。功能點主要有:①渲染的個數要與C層的個數相同 ②程序員使用的頁碼雖然為0基,但用戶習慣于1基 ③點擊對頁的應碼時應該觸發(fā)C層onPage方法 ④當前頁的樣式應該區(qū)別于非當前頁。下面,按上述功能點分別開發(fā): ### 渲染個數 TDD測試驅開發(fā),先嘗試寫寫單元測試代碼: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('頁碼渲染個數', () => { component.pages = new Array<number>(3, 4, 5, 6, 7); fixture.detectChanges(); /* 獲取首頁按鈕 */ const debugElement = fixture.debugElement.query(By.css('ul.pagination')); ① const ulElement: HTMLUListElement = debugElement.nativeElement; /* 斷言分頁個數 */ console.log(ulElement.getElementsByTagName('li')); ② expect(ulElement.childNodes.length).toEqual(9); ③ }); }); ``` * ① 通過css選擇器獲取分頁的ul元素 * ② 獲取ul元素下的所有l(wèi)i元素。首次使用控制臺打印信息 * ③ `首頁 上一頁 3 4 5 6 7 下頁 尾頁` 共9個分頁信息。 功能代碼中先補充下一頁及尾頁: student/index/index.component.html ``` <li class="page-item"> <a class="page-link" href="#">Next</a> ? <a class="page-link" href="#">下一頁</a> ? </li> <li class="page-item"> ? <a class="page-link" href="#">尾頁</a> </li> ? </ul> ``` 再進行循環(huán)輸出: student/index/index.component.html ``` <li class="page-item" [ngClass]="{'disabled': params.page === 0}" (click)="onPage(params.page - 1)"> <span class="page-link">上一頁</span> </li> <li *ngFor="let page of pages"> <a class="page-link" href="#">3</a> </li> <li class="page-item"> <a class="page-link" href="#">下一頁</a> </li> ``` ![](https://img.kancloud.cn/bf/92/bf92503c2c81562d2f9491a3674aba22_530x69.png) 單元測試通過,說明生成的頁碼數量符合預期。 ### 頁碼號 C層給V層的頁碼號為0,1,2,3...,在輸出時應該轉換為1,2,3 student/index/index.component.html ``` <li *ngFor="let page of pages"> <a class="page-link" href="#">3</a> ? <a class="page-link" href="#">{{page + 1}}</a> ? </li> ``` ![](https://img.kancloud.cn/f7/b6/f7b696e241def337af764d378cfe21d7_491x53.png) 效果有了,再進行單元測試以保證本功能在以后項目的更新過程中也是可用的。頁碼號與頁碼渲染個數兩個單元測試基于相同的前提:設置C層的頁碼,渲染V層最終獲取UL元素。本著**不造重復的輪子**的原則將其公用的代碼抽離如下: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... /** * V層分頁測試BEFORE */ const viewPageBefore = (): HTMLUListElement => { component.pages = new Array<number>(3, 4, 5, 6, 7); fixture.detectChanges(); /* 獲取分頁 */ const debugElement = fixture.debugElement.query(By.css('ul.pagination')); return HTMLUListElement = debugElement.nativeElement; }; fit('頁碼渲染個數', () => { const ulElement: HTMLUListElement = viewPageBefore(); ① /* 斷言分頁個數 */ console.log(ulElement.getElementsByTagName('li')); expect(ulElement.getElementsByTagName('li').length).toEqual(9); }); ``` * ① 在此處調用抽離的方法 測試頁碼號用例: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('測試頁碼號', () => { const ulElement: HTMLUListElement = viewPageBefore(); const liElements: HTMLCollection = ulElement.getElementsByTagName('li'); ? /* 依次獲取第3 4 5 6 7頁,斷言對應的頁碼為4,5,6,7,8 */ for (let i = 2; i < 7; i++) { console.log(liElements[i].textContent); ① expect(liElements[i].textContent).toContain((i + 2).toString()); ② } }); ``` * ? 通過getElementsByTagName方法獲取到的返回值類型為:HTMLCollection * ① 首次使用在控制臺中進行打印 * ② 使用contains方法適用更為寬泛,比如后面即將使用的當前面`<span class="page-link">2<span class="sr-only">(current)</span></span>`。在不考慮當前頁的情況下此處使用toEqual亦可。 ### 點擊觸發(fā)onPage方法 單元測試中依次點擊幾個頁碼,并依次斷言以頁碼值調用C層的onPage()方法,測試用例如下: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('頁碼點擊測試', () => { const ulElement: HTMLUListElement = viewPageBefore(); const liElements: HTMLCollection = ulElement.getElementsByTagName('li'); spyOn(component, 'onPage'); for (let i = 2; i < 7; i++) { const htmlLiElement = liElements[i] as HTMLLIElement; ? htmlLiElement.click(); expect(component.onPage).toHaveBeenCalledWith(i + 1); ? } }); }); ``` * ? 使用as進行數據類型的強制轉換。與JAVA不同,此處即使是類型不相符也不會報錯(但可能后續(xù)的功能會失效【了解即可】) * ? 依次點擊3,4,5,6,7頁,傳給onPage的值也是3,4,5,6,7 功能代碼相對簡單: student/index/index.component.html ``` <li *ngFor="let page of pages" (click)="onPage(page)"?> <a class="page-link" href="#">{{page + 1}}</a> </li> ``` ### 選中當前頁 第一次完成某效果時,參考官方的文檔是最簡單有效的方式。正式動手寫之前先瀏覽下bootstrap的示例代碼: ![](https://img.kancloud.cn/3c/d9/3cd9c8c1ead2c0a3d3e1c69533cff1f6_769x450.png) 有了示例代碼,功能性的代碼也就不難了。 student/index/index.component.html ``` <li class="page-item"★ [ngClass]="{'active': params.page === page}"① *ngFor="let page of pages" (click)="onPage(page)"> <a class="page-link" href="#" *ngIf="page !== params.page"②>{{page + 1}}</a> <span class="page-link" *ngIf="page === params.page"③>{{page + 1}}<span class="sr-only">(current)</span></span> </li> ``` * ① 頁碼為當前頁時,增加active樣式 * ② 非當前頁時,顯示可點擊的分頁 * ③ 當前頁時,顯示不可點擊的分頁 對應的單元測試代碼如下: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('選中當前頁測試', () => { component.params.page = 4; ① const ulElement: HTMLUListElement = viewPageBefore(); }); }); ``` * ① 模擬第4頁為當前頁,單元測試查看效果: ![](https://img.kancloud.cn/9e/28/9e28289c96dfd40452786a3ff373d617_517x60.png) 確認效果后,繼續(xù)使用單元測試對此效果進行確認: student/index/index.component.spec.ts ``` describe('Student -> IndexComponent', () => { ... fit('選中當前頁測試', () => { component.params.page = 4; const ulElement: HTMLUListElement = viewPageBefore(); const liElements: HTMLCollection = ulElement.getElementsByTagName('li'); /* 斷言只有ul元素下只有一個active子元素,且該子元素的位置符合預期 */ expect(ulElement.getElementsByClassName('active').length).toBe(1); ① const htmlLiElement = liElements[3] as HTMLLIElement; ② expect(htmlLiElement.classList.contains('active')).toBe(true); ② /* 斷言該li元素中存在class為sr-only的元素 */ const elements = htmlLiElement.getElementsByClassName('sr-only'); console.log(elements); expect(elements.length).toEqual(1); expect(elements[0].textContent).toContain('(current)'); ③ }); }); ``` * ① ul下僅有一個class=active的li元素 * ② 該元素對頁的page值為4 * ③ 當前頁中存在sr-only樣式的元素,元素內容為(current) 至此,頁碼開發(fā)基本完畢。 ## 下一頁 此方法與上一頁類似,將params.page替換為pageStudent.totalPages即可,請自行完成。 提示:CSS選擇器 匹配同類型中的倒數第 2 個同級兄弟元素為`:nth-last-child(n)`,`n`同樣為1基。 ## 尾頁 此方法與首頁類似,請自行完成。 提示:CSS選擇器 最后一個元素為`:last-of-type` # 總結 本小節(jié)我們大量的應用了粒度最小的化的測試方法,將每個功能點盡力的拆分一個個獨立可測試的小的功能。在相對復雜的一些功能中,匯制了流程圖來幫助我們梳理功能的邏輯處理。后依流程圖對功能點進行拆分,進而對每個小的功能點獨立進行開發(fā)測試。雖然有些單元測試的語法我們第一次使用,但由于每個測試用例中的代碼量均不大,所以在學習及閱讀過程中并不址分費力。而且更重要的是:單元測試代碼隨時保障了功能代碼的可用性。 # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step4.6.8](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step4.6.8) | - | | bootstrap grid | [https://getbootstrap.net/docs/layout/grid/](https://getbootstrap.net/docs/layout/grid/) | 5 | | bootstrap pagination | [https://getbootstrap.net/docs/components/pagination/](https://getbootstrap.net/docs/components/pagination/) | 5 | | spyOn | [https://jasmine.github.io/api/3.3/global.html#spyOn](https://jasmine.github.io/api/3.3/global.html#spyOn) | 5 | | HTMLDivElement | [https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLDivElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLDivElement) | 5 | | Node.textContent | [https://developer.mozilla.org/zh-CN/docs/Web/API/Node/textContent](https://developer.mozilla.org/zh-CN/docs/Web/API/Node/textContent) | 5 | | HTMLLIElement | [https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLLIElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLLIElement) | 5 | | Element.classList | [https://developer.mozilla.org/zh-CN/docs/Web/API/Element/classList](https://developer.mozilla.org/zh-CN/docs/Web/API/Element/classList) | 5 | | CSS 選擇器 | [https://www.runoob.com/cssref/css-selectors.html](https://www.runoob.com/cssref/css-selectors.html) | - |
99国产在线 精品 视频| 亚洲一区二区三区久久aa| 日韩中文字幕视频在线播放| 99.com精品视频| 污视频在线观看91| 欧美熟女vides| 中文字幕一线一区和二区| 亚洲av电影在线一区二区| av熟妇翔田千里俱乐部| 亚洲久久精品午夜| 日韩免费美女电影| 91亚洲国产成人久久精品app| 丝袜日韩中文字幕| 精品一区二区三区蜜桃臀的优势| 亚洲欧美在线视频播放| 欧美日韩精品综合在线一区二区| 国产99成人自拍视频| 91九色蝌蚪熟妇出轨| 精品激情视频在线免费观看| 另类欧美亚洲中文综合| 91精品久久久久久久久不卡网站| 性欧美另类sex极品free| 青青青高清国产视频| 日韩a毛片视频免费看| 亚洲欧美日韩综合专区| 国产99精品久久久久久圆免看片| 日韩av电影在线观看的| www.视频一区二区三区| 久久久久国产麻豆婷婷| 亚洲精品久久久久久久久蜜桃| 中文字幕av最新在线| 成人黄片av在线播放| 国产91久久精品一区二区老| 国产又粗又黄又大又长视频| 婷婷基地中文字幕| 91在线精品一区二区网站| 麻豆网站在线免费看| 久久精品国产av网| 色图av亚洲综合| 人妻夜夜爽天天爽麻豆| 国产欧美版日韩综合| 日韩欧美不卡一区二区三区五区| 国产剧情高清在线观看| 人妻夜夜爽天天爽麻豆| aaa久久久久久久久久网站| 加勒比精品一区二区三区| wwxxx中文字幕| 国产一区二区三区a级毛片| 亚洲精品蜜桃久久久久| 日日碰狠狠躁久久躁一区二区| 国产精品综合手机在线| 青青91免费视频| 91精品一二三区在线观看| 2020日本中文字幕| av岛国不卡在线观看| 88av亚洲精品日韩一区二区| 日本午夜在线免费观看| 2020中文字幕在线看电影| av国偷自产自拍自在线| 国产一区二区视频大全床| 精品中文久久久久久| 男人的天堂久久久亚洲| 精品国产久久久久99| 制服巨乳人妻在线| 日韩精品免费91aa| 人妻熟 中文字幕| 亚洲 欧美 制服 人妻| 丰满人妻一区二区三区av| 激情五月天狠婷婷| 激情四射五月开心六月婷婷| 97久久视频免费在线播放| 日韩大全毛片免费观看视频| 大香蕉影视日本大香蕉97| 精品国产久久久久蜜臀| 精品99国内中文字幕| 日韩二区不卡视频| 亚洲av网站女性向在线观看| av国产一区二区三区| 久久久成人在线免费视频| 99日本亚洲精品视频| 五月激情爱爱婷婷| 日韩精品午夜免费观看| 国产高潮国产高潮久久久久久91| 日韩精品综合视频在线| 日韩大全毛片免费观看视频| 午夜影院av在线| 91超碰免费在线播放| 亚洲视频另类专区| 久久久久久人妻无码| 久久99久久com| 国产乱人妻精品久久久| 国产一级av国产免费| 精品99国内中文字幕| 蜜臀av 麻豆av| 中文字幕 日本伊人| 50岁老熟女一区二区三区| laoyawo老鸭窝在线视频| 国内精品久久久久久久久久清纯| 国产精品欧美日韩五月香蕉| 国产 欧美 日韩 视频| 久久精品人妻中文字幕一区| 成人国产一区二区免费| 成年美女黄色av网站| 日韩av在线精品观看| 久久视频这里都是精品| 国产精品一区二区三区三级| 国产精品久久久久国产| 成年人晚上免费看的视频| 五月婷久久综合狠狠爱97| 99热这里只有的精品| 青青草成人免费电影| 青青草成人影院在线观看| 在线观看日韩美视频一区| 丰满的人妻一区七区| 成人黄色国产网站在线观看| 亚洲欧美日韩一区二区三区不卡| 久久免费视频观看99| 欧美一区二区三日韩| 麻豆丝袜美女人妻中文| 9久热这里有国产精品| 人妻日韩精品在线观看视频| 日韩欧美综合一区二区在线| 91中日在线中文字幕| 精品aa级中文字幕人妻| 真实玩弄白嫩丰满人妻少妇三级| www.视频一区二区三区| 午夜日韩麻豆福利| 精品国产乱码久久久久久蜜坠欲下| 亚洲av高清不卡| 日本中文字幕一区二区在线视频| 国产日本精品久久久久| 视频一区视频二区三区| 久久久久国产精品夜夜夜| 欧美人妻一区二区三区在线播放| 精品国产麻豆免费成人网| 成人av电影免费版| 福利日韩精品中文字幕专区| 在线不卡日韩视频播放| 国产网址手机上可以看的国产网站 | 亚洲成人日韩丶av| 精品aa级中文字幕人妻| 色播五月激情四射| 国产精品男人的天堂999| 精品久久久久久亚洲国产999| 中文字幕在线视频亚洲| 欧美日韩亚洲国产ay| 国产丝袜香蕉在线观看| japanese 在线中文字幕| 日韩厕所偷拍美女| 亚洲av网站女性向在线观看| 中文字幕亚洲中文字幕| 青青草久久大香蕉| 日韩av在线不卡网站| aaa久久久久久久久久网站| 日韩在线中文字幕不卡| 精品人妻二区中文字幕| 一区二区三区乱码视频| sepapa自拍偷拍| 国产人妻另类综合专区| 久久久久国产精品夜夜夜| 高清中文字幕乱码在线| 在线观看日韩美视频一区| 人人妻人人澡人人爽国产一区 | 欧美日韩精品综合在线一区二区| 99久久老熟妇仑乱一区| 99精品视频在线看17| 国产成人av最新网址| 亚洲一线产区二线产区区| 国产精品男人的天堂999| av成人教育在线播放| 亚洲制服高清中文字幕| 国产91在线播放精品| 99热这里只有的精品| 精品乱码久久久久久蜜臀| huangse网站在线观看| 亚洲欧美日韩一区17c| 精品欧美日韩国产在线| 免费人妻一区二区三区免费视频| 精品久久一区电影亚洲| 日韩精品综合免费视频| 国产+日本+欧美在线观看| 日韩精品免费91aa| 日韩有码在线免费观看视频| 亚洲.欧美.日韩.| 麻豆免费国产福利免费国产福利| 欧美日韩成人精品视频| 国产丝袜香蕉在线观看| 熟女激情一区二区三区| 五月天丁花香婷婷| 精品视频在线观看一区二区97| 91高级会所在线播放| 在线国产小视频麻豆| 久操免费福利在线视频观看视频| 亚洲激情网在线播放| 日韩精品福利性无码专区| 香蕉在线蕉久在线| 国产又粗又黄又大又长视频| 亚洲中文字幕精品高清| 人妻av不卡一区二区三区| 99九九99九九热视频| 欧洲美女黑人粗性暴交视| 欧美日韩亚洲大片在线| 人妻丰满精品一区二区三区| 97精品久久人人爽人人爽| 少妇人妻成人在线| 久久亚洲熟妇中文字幕| 亚洲成年人电影天堂| 蜜桃精品一区二区三区在| 亚洲综合色激情五月| 亚洲日本精彩视频在线观看| 99re6热在线视频免费观看| 青青青青青欧美在线视频观看| 91久久亚洲成人精品| 日本东京热天天日天天干| 精品一区二区国产在线观看| 久久久精品欧美一区二区国产| 蜜臀av久久久久av蜜臀| 少妇人妻一区2区中文字幕| 日韩午夜激情福利免费| 四虎国产精品久久免费精品| 少妇人妻给我内射视频| 中文字幕亚洲资源天堂| 国产91熟女免费视频| 日韩成人免费电影三区| 午夜三级中文字幕视频网址大全| 五月天丁花香婷婷| 久久人搡人人玩人妻精品| 亚洲第一黄色天堂| 亚洲av电影在线一区二区| 三级亚洲天堂亚洲天堂| 97人人人欧美人人妻人人| 国产成人精品久久久女| 亚洲国产精品97久久宅男| 欧美激情欧美情色成人在线| 日韩av一区中文| 国产无av码在线观看| 久久久久久添逼视频| 91在线精品国自产拍| 99精品视频69v精品视频| 国产欧美日韩精品专区黑人| 草裙成人精品一区二区三区| 欧美亚洲av日韩综合一区| 首页国产中文字幕av| 亚洲综合精品久久| 亚洲av不卡码在线看| 99九九99九九热视频| 日韩av一区中文| 国产 欧美 日韩 视频| 欧美老熟妇重口另类xxx| 亚洲久久亚女同性| 久久久久久一欧美国产| 亚洲成人久久久久| 精品日韩偷拍欧美另类| www.亚洲成人色| 91精品久久久久久久久不卡网站| 青青青青青欧美在线视频观看| 人妻人人揉人人澡人人| 91人妻人人做人碰人人| 国产91熟女免费视频| 日本女优中文字幕在线| 狠狠干中文字幕97视频| 999精品插丰满少妇人妻| 91偷伦一区二区三区蜜臀| 四虎网站免费av| 精品激情视频在线免费观看| 亚洲成年人电影天堂| 亚洲成a人片7777| 久久午夜福利电影免费试看| 新版天堂av资源在线| 国产又粗又黄又大又长视频| 久久久久久精品国产成人| 青青草久久大香蕉| 日韩尤物人妻av在线网| av日韩中文字幕人妻| 99热这里只有精品网| 日本二次元少女裸| wwxxx中文字幕| 久久伊人亚洲综合网| 亚州av一区二区三区.| 久久久久国产精品免费| 亚洲国产精品97久久宅男| 北条麻妃裤袜一区二区| 国产欧美日韩精品专区黑人| 亚洲久久久久久久人妻| 麻豆精品一区在线免费观看| 91人妻人人妻人人爽| 日本少妇人妻xxxx| 最新美女激情av| 久久蜜臀精品一区二区| 天天操,天天干,天天| 久久久久久人妻无码| 91精品一二三区在线观看| 91在线精品国自产拍| 日韩高清av一区| 国产天堂avwww| 久久久久久少妇被弄高潮| 亚洲日本韩国欧美一起| 综合 另类 自拍| 日韩色在线视频观看免费| 日本18禁片免费久久| 青青91免费视频| 中文字幕日韩天堂| 亚洲天堂性色综合| 在线免费av大香蕉| 日本女同性恋视频| 九九re精品免费视频| 天天日天天干一道一小| 国产欧美日韩不卡在线观看| 伊人久久婷婷av| 中文字幕一区二区不卡顿| 久久久精品欧美一区二区国产 | 91porny国产九色| av日韩中文字幕人妻| 亚洲av微乳在线| 日韩美女夜夜爽av| 秋霞在线观看色哟哟视频| 亚洲天堂av电影免费在线| 日韩亚洲丝袜系列| 青青草青青操在线播放| 少妇人妻成人在线| 蜜桃精品一区二区三区在| 久久蜜桃视频亚洲精品| 色综合久久久久久久久| 青草青草视频免费2在线观看| 男人亚洲天堂2018| 天天日天天日天天日天天日| 五月婷婷51视频免费| 五月婷婷激情四射综合网| 日本熟妇人妻在线| 国产乱子伦视频免费| 欧美日韩精品综合在线一区二区| 亚洲久久亚女同性| 麻豆在线视频看片免费 | 亚洲情欲大片在线观看| 无码人妻精品一区二区三区久久| av久久伊人精品中文字幕| 久久久亚洲精品久久仙| 婷婷丁香花五月天| 欧美日韩精品一区电影| 色婷婷一区二区三区四区五| 中文字幕亚洲欧美国产| 四虎网站免费av| 视频免费在线观看91| 免费精品国产日韩热久久| 日本女同性恋视频| 美女差点操死在线观看| 日韩av在线天堂| 天天日天天日天天日天天日| 久久免费视频观看99| 亚洲精品熟女中文字幕| 久久久亚洲精品久久仙| 天美麻豆成人av精品小说| 91亚洲精品成人在线| 久久久96精品久久久| 久久久精品99国产国产精| 久久精品琪琪男人的天堂| 久久精品熟女人妻一区二区三区| 久久婷婷激情综合色综合俺也去| av青青草原在线观看| 日韩在线观看免费全集网站| 国产69tv精品久久| 久久最近最新中文字幕大全| 五月婷婷激情狠狠| 一区二区三区精品乱子伦……| 国产欧美日韩精品专区黑人| 亚洲成年人电影天堂| 精品99国内中文字幕| 国产无av码在线观看| 日韩av在线专区| 日本美女大学生一区二区三区| 日韩av一区中文| 91国产手机视频在线观看| 2020日本中文字幕| 人妻丰满精品一区二区三区| 99热这里只有精品网| 欧洲美女黑人粗性暴交视| 亚洲 自拍偷拍 欧美| 日韩精品少妇人妻熟女| 欧美激情欧美情色成人在线| 99国产在线 精品 视频| 麻豆网站在线免费看| 中文字幕熟女人妻在线观看| 久热中文字幕在线精品| 日韩av午夜精品| 欧美中文字幕在线一区| 亚洲精品久久第一页| 国产中文字幕在线91| 久久精品香蕉绿巨人| 亚洲成人日韩丶av| 人妻啪啪视频免费看| 亚洲乱精品中文字字幕| 国产一区二区高清在线播放| 美女差点操死在线观看| 国产黄色主播网址大全在线播放| 91欧美亚洲综合网| 五月黄色激情视频| 日韩av网址在线播放| 99爱99久久久久久久久久| 亚洲国产aⅴ精品一区二区欧美| 亚洲视频另类专区| 免费a级电影在线观看| 亚洲天堂网av中文字幕| 91制片在线观看视频| 日本黄页在线播放日本网站| 高清一区二区日韩视频精品| 狠狠久久综合丁香777米奇| av激情网站在线观看| 日本a级2020在线观看| 91精品乱码久久久久久| 国产一区二区视频大全床| 久久这里只有欧美精品| 久久久久久人妻无码| 国产精品99久久电影| 国产欧美精品久久无广告| 色婷婷中文字幕基地| 亚洲欧美日韩一区二区三区不卡| 天天色天天干天天舔| 人妻日韩精品在线观看视频| 日韩二区不卡视频| 国产91极品身材白皙| 日韩精品福利性无码专区| 久久精品国产av网| 日韩午夜精品啪啪啪| 91制片在线观看视频| 亚洲成a人片,77777| 国产+日本+欧美在线观看| 免费色婷婷在线视频| 天天干天天天天射天天操| 欧美日韩亚洲国产ay| 日韩av在线精品观看| 成人黄视频在线播放| 国产剧情高清在线观看| 国产亚洲精久久久久久无码色戒 | 亚洲男人五月天堂| 亚洲男人天堂久久| 91在线观看视频,| 亚洲 欧美 自拍 中文| 欧美一区二区理论片在线观看| 久久蜜臀精品一区二区| 精品一区二区国产在线观看| 俺去鲁婷婷六月色综合| 丰满熟女一区二区三区在线| 婷婷亚洲免费基地| 999热精品在线观看| 欧美一区二区精品人妻免费视频| 国产日本精品久久久久| 日韩成视频在线播放| 91中文字幕制服诱惑| 丰满大屁股熟妇猛交xxx| 国产又粗又硬又长又爽视频| 精品国产精品视频免费在线观看| 一级久久久久久久18| 日韩av在线专区| 麻豆丝袜美女人妻中文| 精品一区二区三区四区人妻69| www日本不卡一二三区| 日韩欧美三级一区二区在线观看| 日韩av中文网址| 青娱乐国产视频盛| 久久国产精品久久伊人麻豆| 国产精品久久久久久久久久69| 免费中文字幕在线播放| 亚洲欧美日韩偷拍综合| 中文字幕日韩久久精品tv| 日韩大全毛片免费观看视频| 久久久久久久久人妻精品| 欧美日韩综合国产精品| 久久精品国产亚洲av不卡性色| 一区二区三区精品乱子伦……| 美女免费一二三区视频| 久久国产经典三级av| 色婷婷国产熟妇人妻露脸| 成人黄视频在线播放| 亚洲天堂黄色免费| 91porny国产九色| 中文字幕日韩天堂| 9久久国产精品一区二区| 亚洲av激情小说| 天天干天天插天天操天天日| 精品乱码久久久久久蜜臀| 亚洲欧美在线视频播放| 日韩二区不卡视频| 亚洲中文字幕成人久久| 青青草成人影院在线观看| 国产欧美一二三区视频| 日韩在线免费视频精品| 日本精品久久久久中人妻| 日韩中文字幕一区二区三区四区| 日韩美女在线视频一区| 热香蕉和冷香蕉功效一样吗| 国产熟女高潮av77777| 牛牛成人手机视频在线| 精品日韩偷拍欧美另类| 亚洲欧美日韩偷拍综合| 国产欧美一二三区视频| 中文字幕熟女人妻在线观看 | 97国产免费电影网| 先锋男人资源中文字幕| huangse网站在线观看| 日本黄色成年视频| av传媒高清影院免费| 成年人在线免费观看黄色片| 日韩精品综合视频在线| 亚洲天堂av电影免费在线| 欧美人妻系列,中文字幕| 日韩精品少妇人妻熟女| 国产精品成人av麻豆| 国产精品成人av麻豆| 午夜在线观看高清完整版| 精品国产乱码久久久久久蜜坠欲下| 日本少妇人妻xxxx| 68国产成人综合久久精品| 五月天丁香婷婷国产| 日本久久久大片中文字幕 | 亚洲一区二区三区久久aa| 七十路熟女俱乐部| aaaaa亚洲电影| 久久久97精品国产| 99久久窝窝午夜影视| 新版天堂av资源在线| 天天日天天干一道一小| 亚洲激情熟女色图| 久热中文字幕在线精品| 亚洲熟妇av熟妇在线| 亚洲av亚洲av亚洲| 日本精品久久久久中人妻| 欧洲美女黑人粗性暴交视| 视频在线观看黄页| 91中日在线中文字幕| 亚洲激情有码一区二区| 亚洲女人中文字幕在线| 88在线观看91蜜桃国自产| 熟女少妇一区二区精品| 日韩精品免费91aa| 久久九特黄的免费大片| 久久婷婷激情综合色综合俺也去| 亚洲制服欧美丝袜| 久久久久中文字幕免费久久久久久| 成人午夜激情福利片| 色男人天堂东京热| 久久蜜桃视频亚洲精品| 五月爱婷婷六月丁香性| 老鸭子在线观看免费播放| 在线中文字幕第二页| 素人阁久久久久精品人妻| 激情五月天狠婷婷| 自拍偷拍 亚洲 在线| 欧美日韩精品在线观看免费 | 国产熟女高潮av77777| 久久五月婷婷综合视频| 亚洲情欲大片在线观看| 久久爱免费视频16| 青青青高清国产视频| 亚洲天堂网av中文字幕| 国产日本精品久久久久| 成年人在线免费观看黄色片| 大尺度av一区二区三区| 久久久久久久夜精品精品| 婷婷激情五月天图片| 国产精品一区二区三区三级| 日韩av黄片在线观看| 亚洲综合在线伊人| 日本亚洲天堂久久| 综合激情伊人久久| 中文字幕亚洲专区欧美| 久久视频一区二区三| 中文在线字幕a在线| 天天日天天干一道一小| 国产精品久久久久一区二区| 久久久久久久久久久最新| 日韩av在线点播| 色综合久久999| 久久视频一区二区三| 色综合久久久久久久久| 日韩亚洲丝袜系列| 久久久久国产精品夜夜夜| 国产精品久久久久久久网站门| 成人av电影免费版| www.199麻豆在线视频| 亚洲国产精品久久久久婷婷av| 亚洲熟妇免费在线视频| 欧美区 日韩区 国产区| 一区二区 熟女人妻| 亚洲 自拍偷拍 欧美| 中文字幕精品久久伊人| 亚洲综合精品久久| 91亚洲国产成人久久精品app| 午夜日韩麻豆福利| 日本加勒比中文字幕久久| japanese 在线中文字幕| 99热这里只有的精品| 久久99永久免费看| 日韩三级伦理片免费看| 日日日日日夜夜夜夜| 欧美高清在线视频99| 中文字幕亚洲资源天堂| 我要看一级国产黄色绿像| 精品成人1区2区3区在线看片| 天天干天天插天天操天天日| 亚洲一线产区二线产区区| 欧美aⅴ一区二区三区| 亚洲熟妇av熟妇在线| 偷偷夜夜精品一区二区三区蜜桃| 日韩在线观看免费全集网站| 午夜精品久久久久久久久二区三区 | 天天操天天干天天妻| 高清一区二区三区日本4| 福利一福利二福利三| 日韩中文字幕有码人妻在线| 国产麻豆剧传媒精品视频| 99.com精品视频| 亚洲最大成人网一区二区三区| 日韩美女在线视频一区| 2020日韩中文字幕| av色香蕉一区二区三区| 99国产在线拍91揄自揄视| 色哟哟视频在线观看国产 | 久久99国产综合精品无码免费| 美女在线观看亚洲一区| 久久免费视频精彩视频| 91在线精品国自产拍| 久久久久999久久日| 日韩欧美国产成人一区| 欧美激情电影在线观看不卡| 久久久久久久久人妻精品| 草裙成人精品一区二区三区| 国产丝袜香蕉在线观看| 九九re精品免费视频| 日本熟妇乱子伦a片在线观看| 亚洲最大成人网一区二区三区| 91人妻九色大屁股| 欧美日韩国产一级一顶级| 国产又大又长又粗又硬免费视频| 久久亚洲熟妇中文字幕| 污视频在线观看91| 国产 欧美 日韩 视频| 亚洲欧美日韩国产另类专区| 热久久免费频精品18| 欧美激情 另类视频 亚洲| 素人阁久久久久精品人妻| 国产视频av一区二区| 四虎国产精品久久免费精品| 日本午夜在线免费观看| 亚洲欧美日韩一二三四五六七区| 欧美日韩精品欧美日韩| 国产 欧美 日韩 视频| 草裙成人精品一区二区三区| av青青草原在线观看| 久草青青草原在线视频| 国产一区二区三区a级毛片| 亚洲视频另类专区| 七十路熟女俱乐部| 99国产在线拍91揄自揄视| 少妇人妻给我内射视频| 午夜精品久久婷婷蜜桃| 久久久精品欧美一区二区国产| www.亚洲成人色| 在线免费av大香蕉| 91人妻精品久久久久久久久| 亚洲欧洲色图动图| 天天色天天干天天舔| av久久伊人精品中文字幕| 日本最新中文字幕| 五月综合婷婷婷婷婷婷| 久久在线人妻熟女高清完整版| 精品人妻一区二区三区线国色天香| 日本中文字幕一区二区在线视频| 亚洲制服高清中文字幕| 亚洲成人日韩丶av| 久久人妻少妇嫩草av蜜桃动态图| 亚洲激情熟女色图| 国产熟女高潮av77777| 人妻精品少妇嫩草麻豆| 精品aa级中文字幕人妻| 亚洲中文字幕福利视频| 欧美老熟妇重口另类xxx| 久久久久久久久久无吗| 天天干天天插天天操天天日| 真实玩弄白嫩丰满人妻少妇三级| 日韩欧美颜色渔网| 色婷婷久久久swag精品| 中文字幕婷婷网站| 激情婷婷综合久久五月天| 一区二区 熟女人妻| 日本av都有哪些系列| 丰满少妇精品一区二区| av熟妇翔田千里俱乐部| 9久久国产精品一区二区| 欧美爱情动作片在线一区| 精品一区二区三区四区日产| 亚洲国产精品五月天久久久| 亚洲熟妇在线观看一区二区| 日韩欧美三级一区二区在线观看| 精品乱码一区二区三区四区| 亚洲av亚洲av亚洲| 91精品人妻一区二区三区四区| 人妻有码中文字幕中文| 97精品国产自在在线观看蜜臀| 搡老熟女一区二区三区老熟女| 国产精品久久久久久久久久网站| 久久久久久久久久无吗| 久久免费视频观看99| 亚洲成a人片7777| av成人教育在线播放| 日韩人妻插舔激情午夜| 亚洲精品蜜桃久久久久| 亚洲国模私拍视频| 亚洲精品久久久久久久久蜜桃| 中文字幕亚洲欧美国产| 欧美日韩久久久久久精品| 五月婷久久综合狠狠爱97| 久久蜜臀精品一区二区| 亚洲伊人网在线播放| 国产又粗又硬又长又爽视频| 久久久久久久夜精品精品| 高清中文字幕乱码在线| 色熟女蜜臀又伦av| 人人妻人人爱碰千| 久久人妻少妇嫩草av蜜桃动态图| 精品无人区一区二区三区竹菊| 久久久国产精品尤物av| 68国产成人综合久久精品| 欧美亚洲av日韩综合一区| 精品久久久久久999| 久久精品 中文字幕| 国产精品男人的天堂999| 亚洲国产欧美日本视频| 亚洲少妇黄色一级片| 亚洲天堂av电影免费在线| 成人在线观看黄色片| 五月婷婷51视频免费| 久久五月天天婷婷激情综合| 在线观看色有小视频| 午夜国产福利电影| 欧美一区二区三区激情无套| 日韩不卡高清视频| 午夜无人影视在线| 日韩视频在线播放一区二区| 婷婷 少妇 av| 激情亚洲一区蜜桃在线| 厕所偷拍视频一区二区三区| 久久99免费成人在线| 久久爱免费视频16| 欧美成人黄色一区二区三区| av在线免费在线观看av| a级黄片在线免费观看| av激情网站在线观看| 日本二次元少女裸| 日本黄页在线播放日本网站| 99精品中文字幕在线视频| 国产欧美一区二区二区精品| 丰满少妇精品一区二区| 欧美激情欧美情色成人在线| 色哟哟视频在线观看国产| 欧美一区二区性久久久| 欧美日韩精品成人在线| 激情黄色开心五月天| 视频免费在线观看91| 久久久久在线免费看| 日韩中文字幕理伦| 欧美熟女人妻一区二区三区 | 五月综合缴情婷婷六月| 日韩美女主播人体视频自拍首页| 青青青手机版视频在线看| 韩国女团午夜大尺度福利| 久久久久久久黄色午夜精品| 亚洲久久亚女同性| 人妻中出视频一区二区| 一级片一级片久久精品电影网电影| 色婷婷中文字幕基地| 人妻丰满精品一区二区三区| 精品久久中文字幕系列| 亚洲成年人电影天堂| 日韩欧美颜色渔网| 91在线观看视频,| 99爱99久久久久久久久久| 激情亚洲一区蜜桃在线 | 99精品中文字幕在线视频| 国产中文字幕在线91| 国产a级片免费在线观看| 狠狠久久综合丁香777米奇| 日韩视频在线观看一区二区| 亚洲熟妇av日韩熟妇在线| 日本高清不卡视频在线播放| 麻豆精品一区在线免费观看| av在线免费播放成人| 免费色婷婷在线视频| 91插插插操美女视频| 日本久久久大片中文字幕| www日本不卡一二三区| 久久久九九九九九精品6| 久久精品美国亚洲av伦理| 免费人妻一区二区三区免费视频 | 亚洲精品熟女中文字幕| 久久视频在线免费播放| 秋霞在线观看色哟哟视频| 思思久久国产精品视频| 99热在线精品免费观看| 99re热在线精品视频9| 亚洲国产精品国自产拍av麻豆| 亚洲男人天堂久久| 高潮久久久久久久av免费| 久久久久久久黄色午夜精品| 少妇人妻成人在线| 又爽又黄的免费视频91| 日韩精品综合免费视频| 日韩不卡一级成人免费视频| 久久久久久网站精品免费| 久久久九九九九九精品6| 色男人天堂东京热| 欧美一区二区三区成人免费看| 久久蜜臀精品一区二区| 精品国产一区二区三区无码蜜桃 | 亚洲综合色激情五月| 日韩欧美综合一区二区在线| 亚洲一区视频大全| 玖玖资源站中文字幕一区二区| 人妻丰满一区二区三区| 色综合色综合色综合久久| 91九色porny国产视频| 午夜影院av在线| 中文字幕+人妻熟女| 亚洲国产欧美激情图区| 欧美区 日韩区 国产区| 久久五月天天婷婷激情综合| 91熟女视频在线观看| 国产一区二区高清在线播放| 亚洲精品久久第一页| 日本中文字幕久久免费精品| 91沈先生探花极品在线| 91国偷自产一区二区三区偷拍| 伊人久久热青青草| 福利一福利二福利三| 日本18禁片免费久久| 999热精品在线观看| www日本不卡一二三区| 99久久久99久久91熟女| 日韩av 自拍偷拍| 亚洲狠狠久久综合一区| 欧美aⅴ一区二区三区| 夜夜撸日日撸夜夜爽日日干| 蜜桃黄色av网站免费播放| 日韩不卡高清视频| 日韩 美女 在线观看| 精品国产乱码久久久久夜深| 亚洲欧美丝袜精品久久直播| 蜜桃久久久一区二区三区| 日韩欧美爱爱视频免费观看| 久久国产经典三级av| 亚洲成人av久久久久| 国产av在线观看麻豆| 成人精品1024欧美日韩| 精品国产乱码久久久久久蜜坠欲下| 国产日韩欧美春色另类小说| 999热这里只有精品在线 | 久久亚洲 欧美 综合aⅴ| 久久精品香蕉绿巨人| 久久99永久免费看| youwu视频在线| 狠狠久久综合丁香777米奇| 久久久亚洲熟妇熟女ⅹx| 亚洲熟妇av日韩熟妇在线| 初撮日本五十路人妻| 亚洲综合在线伊人| 欧美日韩国产色图视频| 人人妻人人爱碰千| 亚洲熟妇在线观看一区二区| 欧美日韩精品成人在线| 少妇人妻给我内射视频| 丰满的人妻一区七区| 国产亚洲av免费一区二区| 91人妻露出精品在线| 日本女同性恋视频| 欧美一二三区在线观看| 嫩草一区二区三区四区中文| 最美人妻一区二区三区| 亚洲欧洲久久精品| 色婷婷精品午夜在线播放| 欧美日本一道本一区二区| 亚洲天堂av电影免费在线| 少妇高潮一区二区三区99欧美| 国产精品久久久久久xxx| 亚洲激情国产一区| 国产熟女高潮av77777| 日韩国产91综合精品| 亚洲欧美日韩一二三四五六七区| 麻豆在线视频看片免费| 久久久久999久久日| 日韩中文字幕视频在线播放| 91人妻人人澡.人人精品| 高清不卡av在线网| 人人妻人人爱碰千| 日韩大全毛片免费观看视频| 精品人妻熟女在线视频| 日韩欧美国产成人一区| 色哟哟视频在线观看国产| 丰满人妻一区二区三区av| 91高级会所在线播放| 日韩中文字幕在线网站| 中文字幕一区二区三区中文字幕 | 亚洲情欲大片在线观看| 亚洲午夜电影久久久| 97cao瑟瑟在线观看| 人妻熟女视频免费观看| 91在线播放视频免费| av熟妇翔田千里俱乐部| 久久久久在线免费看| 国产成人精品久久久女| 青青草成人影院在线观看| 日韩a视频在线播放视频| 人人妻人人澡人人爽国产一区| 亚洲国产精品综合久久2007| 久久综合久久综合大香蕉| 亚洲熟妇在线观看一区二区| 国产三级三级三级三级av精品| 人人妻人人澡人人爽dv| 亚洲一区二区三二区厕所偷拍| 在线观看色有小视频| 亚洲欧美av在线观看| 午夜精品久久久久久久久二区三区| 99re6热在线视频免费观看| 天美麻豆成人av精品小说| 欧美最猛性亚洲精品推荐| 精品97人妻无码中文永久| 日韩成人免费电影三区| 亚洲.欧美.日韩.| 亚洲综合色激情五月| 高清不卡av在线网| 国产精品久久欠久久al换脸综合| 蜜桃久久久一区二区三区| 香蕉在线蕉久在线| 国产一区二区高清在线播放| 亚洲欧美日韩国产精品综合| 亚洲另类色区欧美日韩| 日韩福利视频在线看| 久久精品国产91久久麻豆自制| 日韩av一区中文| 天天干天天草天天日天天天射伊人| 大香蕉久草网一区二区三区| 国产精品首页在线播放| 青青青手机版视频在线看| 精品国产精品视频免费在线观看| 十八禁久久久久久久久久久久久久 | 玖玖资源站中文字幕一区二区 | 99久久国语露脸精彩对白| 新版天堂av资源在线| 日韩a视频在线播放视频| 久久久久久久久久久久久熟女a∨ 精品99国内中文字幕 | 日韩久久久三级电影| 国产欧美精品久久无广告| 久久精品一区二区三区人妻蜜桃| 久久 99 精品视频| 日韩美女在线视频一区| 999精品插丰满少妇人妻| 在线观看色有小视频| 思思久久国产精品视频| 久久久97精品国产| 精品久久中文字幕系列| 天天做天天舔天天射| av在线免费在线观看av| 日韩美女主播人体视频自拍首页 | 日韩精品在线播放第三页| 亚洲国模私拍视频| 久久精品一区二区三区人妻蜜桃 | 欧美激情 另类视频 亚洲| 精品蜜臀久久久久抄底| 亚洲国产精品成人精品软件| 婷婷亚洲免费基地| 久久久久久久久人妻精品 | 国产精品久久久久久久久粉嫩av| 国语黄色淫秽录像带| 精品国产一区二区三区无码蜜桃| 国产欧美一区二区二区精品| 99re6热在线视频免费观看| 色视频在线观看123| 免费人妻一区二区三区免费视频 | 久久亚洲精品无码系列客服 | 日韩美女影院免费在线观看| 中文字幕理伦福利片| 五月爱婷婷六月丁香性| 91国偷自产一区二区三区老熟女| 国产一区二区久久久久久| 亚洲日本韩国欧美一起| 久久免费视频精彩视频| 亚洲av网站女性向在线观看| 亚洲 欧美 自拍 中文| 一级片一级片久久精品电影网电影| 中文字幕亚洲欧美国产| 91天仙tv国产福利精品| 欧美人妻一区二区三区在线播放| 婷婷丁香花五月天| 国产成人av最新网址| 999精品插丰满少妇人妻| 熟女人妻之中文字幕| 99热这里只有的精品| 五月婷婷久久久久久久久| 五月激情爱爱婷婷| 欧美日韩成人三级在线| 97人妻中文字幕精品视频| 在线不卡日韩视频播放| 欧美精品人妻丝袜一区| 中文字幕av久久爽爽| 欧美老熟妇重口另类xxx| 成人黄色国产网站在线观看| 日本vs欧美一区二区三区| av久久伊人精品中文字幕| av福利网站在线观看| 人妻丰满一区二区三区| 久久亚洲精品无码系列客服| 亚洲香蕉av电影| 日韩av福利大片在线观看 | 久久精品香蕉绿巨人| 日韩av在线观看卡一卡| 一区,二区,三区视频| 免费av网站在线浏览| 日韩视频在线观看一区二区| 中文字幕一区二区三区中文字幕| 日韩二区不卡视频| 国产精品久久久久久吹吹潮| 四虎国产精品久久免费精品| 国产a级片免费在线观看| 久久蜜桃视频亚洲精品| 一级久久久久久久18| 成年人在线免费观看黄色片| 国产又粗又黄又大又长视频| 精品国产乱码久久久人妻| 欧美一区二区理论片在线观看| 久久久成人在线免费视频| 国产剧情高清在线观看| 色亚洲天堂色派对欧美色| 久久伊人精品青青草原| 十八禁久久久久久久久久久久久久| 日韩中文字幕在线综合网| 久热中文字幕在线精品| 91国产手机视频在线观看| 国产精品久久久久久xxx| 91九色蝌蚪熟妇出轨| 欧美成人黄色一区二区三区| 99精品中文字幕在线视频| 久久国产经典三级av| 中文字幕一区二区三区中文字幕| 成人av激情网一区二区三区| 91九色蝌蚪熟妇出轨| 清纯唯美激情五月| 欧美成人黄色一区二区三区| 成人av电影免费版| 久久精品人人看人人爽| 国产亚洲av免费一区二区| 精品乱码一区二区三区四区| 91国产手机视频在线观看| 蜜桃av 1区二区| 国产精品99久久电影| 亚洲欧洲色图动图| 国产成人精品视频免费网站| 日本最新中文字幕| 激情婷婷综合久久五月天| 免费观看a级在线视频| 视频一区视频二区三区| 午夜日韩麻豆福利| 亚洲成a人片,77777| 五月天丁花香婷婷| 久久五月婷婷综合视频| 蜜臀久久久久精品一区二区三区| 成人免费观看av毛片| 一区,二区,三区视频| 天天操天天干天天色| 国产一级av国产免费| 日韩成人免费电影三区| 天天操天天干天天妻| 国产成人精品久久综合| 久久亚洲熟妇中文字幕| 自拍偷拍亚洲欧美另类| 2020日本中文字幕| 精品乱码一区二区三区四区| 91免费版下载成人| 性欧美另类sex极品free| 高清一区二区三区日本4| 中文字幕人妻一区二区在线看| 欧美中文字幕视频网| 国产青青91av在线视频| 日韩草比网站在线免费观看| 大香蕉大香蕉大香蕉大香蕉大| 久久这里只有欧美精品| 国产精品99久久电影| 少妇惨叫久久久久久久| 国产亚洲av免费一区二区| 国产又大又长又粗又硬免费视频 | 香蕉久久a v一区二区三区| 欧美熟女vides| 日韩国产91综合精品| 91九色蝌蚪熟妇出轨| 人妻夜夜爽天天爽麻豆| 大香蕉大香蕉大香蕉大香蕉大| www.色av成人| 男人的天堂久久精平| 综合激情伊人久久| 亚洲精选黄色在线观看| av日韩在线有码a区| 日韩a v日日夜夜| 精品国产精品视频免费在线观看| 久久视频一区二区三| 久久久久久网站精品免费| 香蕉在线蕉久在线| 精品国产乱码久久久久久蜜坠欲下| 福利精品视频免费观看| 日韩美女夜夜爽av| 亚洲欧美日韩中出| 91天仙tv国产福利精品| 天天色综合天天射综合| 18在线观看久久久麻豆| 亚洲中文字幕成人久久| 日韩国产91综合精品| 欧美熟女vides| 欧美日韩国产色图视频| 亚洲国产精品成人精品软件| 欧美 国产 日韩 一区二区| 国产成人一区二区三区在线视频| 先锋男人资源中文字幕| 亚洲制服欧美丝袜| 国产欧美精品久久无广告| 国产一区二区久久久久久 | 青娱乐国产视频盛| 久久行黑国产露脸精品| 欧美人妻系列,中文字幕| 日韩毛片亚洲av| 又爽又黄的免费视频91| 国产人妻另类综合专区| 亚洲男人天堂久久| 欧美激情欧美情色成人在线| 99国产在线 精品 视频| 婷婷亚洲天堂中文字幕| 国产精品久久久久久吹吹潮| 少妇高潮一区二区三区99欧美| 久久人妻少妇嫩草av蜜桃动态图 | 少妇人妻成人在线| 日韩有码在线免费观看视频| 亚洲情色av网站| 日韩美女主播人体视频自拍首页 | 一级久久久久久久18| 午夜精品久久婷婷蜜桃| 亚洲精品乱码97久久久久久| 日韩在线啊啊啊的视频| 精品97人妻无码中文永久| 蜜臀av一区二区三区人妻少妇| 亚洲综合成人久久av| 国产精品久久久久久久久久网站 | 久久爱免费视频16| 亚洲尺码和欧洲尺码av| 99久久999久久久精品综合| 国产亚洲精久久久久久无码色戒| 中文字幕av最新在线| 国产五月天在线观看视频| www.亚洲成人色| 日韩精品综合免费视频| 香蕉在线蕉久在线| 成人黄视频在线播放| 亚洲狠狠久久综合一区| 久久久九九九九九精品6| 色男人天堂东京热| 国产丝袜香蕉在线观看| 国产成人免费精品视频大全| 国产一区二区视频大全床| 91麻豆精品91久久久久同性| 人妻丰满一区二区三区| 激情四射五月开心六月婷婷| 日本午夜在线免费观看| 国产亚洲av免费一区二区| 日韩亚洲图色在线| 自拍偷拍 亚洲 在线| 玖玖资源站中文字幕一区二区| 久久久久久久黄色午夜精品| 亚洲视频欧美视频另类| 中文字幕理伦福利片| 久久久精品99国产国产精 | 五月激情爱爱婷婷| 大香蕉久草网一区二区三区| 1024 国产高清の最新合集| 91精品一二三区在线观看 | 国产网址手机上可以看的国产网站 | 国产欧美一二三区视频| 另类h小视频在线观看| 午夜无人影视在线| 麻豆免费国产福利免费国产福利| 日本vs欧美一区二区三区| 国产成人av吴梦梦视频| 国产五月天在线观看视频| 99久久国语露脸精彩对白| 久久99免费成人在线| 在线观看视频 你懂得| 成人午夜激情福利片| 欧美又色又爽又黄又粗暴| 97国产免费电影网| 亚洲欧美日韩在线中文字幕小| 日韩欧美 国产精品| 2001年亚洲区十强赛| 亚洲综合成人久久av| 亚洲精选黄色在线观看| 日韩av一区二区三区久久久| 91九色porny国产视频| 国产精品福利久久久久久久| 高清一区二区三区日本4| huangse网站在线观看| 97cao瑟瑟在线观看| 国产中文字幕在线91| www.色av成人| 亚洲av网站女性向在线观看| 久久传奇网站一区三区视频| 欧美熟妇精品在线观看| 中文字幕久久91| 人妻精品一区二区在线播放|