@ngrx/store#MemoizedSelector TypeScript Examples

The following examples show how to use @ngrx/store#MemoizedSelector. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: auth-guard.service.spec.ts    From router with MIT License 6 votes vote down vote up
describe('Auth Guard', () => {
  let guard: AuthGuard;
  let store: MockStore;
  let loggedIn: MemoizedSelector<fromAuth.State, boolean>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [AuthGuard, provideMockStore()],
    });

    store = TestBed.inject(MockStore);
    guard = TestBed.inject(AuthGuard);

    loggedIn = store.overrideSelector(fromAuth.selectLoggedIn, false);
  });

  it('should return false if the user state is not logged in', () => {
    const expected = cold('(a|)', { a: false });

    expect(guard.canActivate()).toBeObservable(expected);
  });

  it('should return true if the user state is logged in', () => {
    const expected = cold('(a|)', { a: true });

    loggedIn.setResult(true);

    expect(guard.canActivate()).toBeObservable(expected);
  });
});
Example #2
Source File: stock-market-container.component.spec.ts    From enterprise-ng-2020-workshop with MIT License 4 votes vote down vote up
describe('StockMarketContainerComponent', () => {
  let retrieveStockSpy: jasmine.Spy;

  let component: StockMarketContainerComponent;
  let fixture: ComponentFixture<StockMarketContainerComponent>;
  let store: MockStore;
  let mockSelectStockMarket: MemoizedSelector<any, StockMarketState>;

  const getSpinner = () => fixture.debugElement.query(By.css('mat-spinner'));

  const getError = () => fixture.debugElement.query(By.css('.error-state'));

  const getStocks = () =>
    fixture.debugElement.query(By.css('mat-card mat-card-title'));

  const getInput = () => fixture.debugElement.query(By.css('input'));

  const getExchange = () =>
    fixture.debugElement.query(By.css('mat-card mat-card-content'));

  const getChange = () =>
    fixture.debugElement.query(By.css('mat-card mat-card-subtitle'));

  const getCaretUpDownItem = () =>
    fixture.debugElement.query(By.css('mat-card fa-icon[icon="caret-down"]'));

  describe('given component booted', () => {
    beforeEach(async(() => {
      TestBed.configureTestingModule({
        imports: [
          SharedModule,
          NoopAnimationsModule,
          TranslateModule.forRoot()
        ],
        providers: [StockMarketService, provideMockStore()],
        declarations: [StockMarketContainerComponent]
      }).compileComponents();

      const stockMarketService = TestBed.inject<StockMarketService>(
        StockMarketService
      );
      retrieveStockSpy = spyOn(
        stockMarketService,
        'retrieveStock'
      ).and.returnValue(EMPTY);

      store = TestBed.inject(MockStore);
      mockSelectStockMarket = store.overrideSelector(selectStockMarket, {
        symbol: 'AAPL',
        loading: false
      });
      fixture = TestBed.createComponent(StockMarketContainerComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    }));

    it('should be created', () => {
      expect(component).toBeTruthy();
    });

    describe('and input changed', () => {
      let dispatchSpy: jasmine.Spy;

      beforeEach(() => {
        dispatchSpy = spyOn(store, 'dispatch');
        getInput().triggerEventHandler('keyup', { target: { value: 'A' } });
        fixture.detectChanges();
      });

      it('should trigger dispatch with correct input', () => {
        expect(dispatchSpy).toHaveBeenCalledTimes(1);
        expect(dispatchSpy).toHaveBeenCalledWith(
          actionStockMarketRetrieve({ symbol: 'A' })
        );
        expect(true).toBeTruthy();
      });
    });

    describe('and stocks are loading', () => {
      beforeEach(() => {
        mockSelectStockMarket.setResult({ symbol: 'TDD', loading: true });
        store.refreshState();
        fixture.detectChanges();
      });

      it('should show spinner', () => {
        expect(getSpinner()).toBeTruthy();
      });
    });

    describe('and stocks are not loading', () => {
      beforeEach(() => {
        mockSelectStockMarket.setResult({ symbol: 'TDD', loading: false });
        store.refreshState();
        fixture.detectChanges();
      });

      it('should not show spinner', () => {
        expect(getSpinner()).toBeFalsy();
      });
    });

    describe('and the error happened on stock retrieval', () => {
      beforeEach(() => {
        mockSelectStockMarket.setResult({
          symbol: 'TDD',
          loading: false,
          error: new HttpErrorResponse({})
        });
        store.refreshState();
        fixture.detectChanges();
      });

      it('should show error', () => {
        expect(getError()).toBeTruthy();
      });
    });

    describe('and stock details are loaded', () => {
      const symbol = 'TDD';
      const exchange = 'TESTAQ';
      const last = '123';
      const ccy = 'USD';
      const change = '100';
      const changePercent = '11';

      beforeEach(() => {
        mockSelectStockMarket.setResult({
          symbol,
          loading: false,
          stock: {
            symbol,
            exchange,
            last,
            ccy,
            change,
            changePercent,
            changeNegative: true,
            changePositive: false
          }
        });
        store.refreshState();
        fixture.detectChanges();
      });

      it('should display the relevant caret item', () => {
        expect(getCaretUpDownItem()).toBeTruthy();
      });

      it('should display correct stock name, price, currency', () => {
        expect(getStocks().nativeElement.textContent.trim()).toEqual(
          `${symbol} ${last} ${ccy}`
        );
      });

      it('should display correct exchange', () => {
        expect(getExchange().nativeElement.textContent.trim()).toEqual(
          exchange
        );
      });

      it('should display correct change', () => {
        expect(getChange().nativeElement.textContent.trim()).toEqual(
          `${change} (${changePercent}%)`
        );
      });
    });
  });
});
Example #3
Source File: todos-container.component.spec.ts    From enterprise-ng-2020-workshop with MIT License 4 votes vote down vote up
describe('TodosComponent', () => {
  let store: MockStore;
  let component: TodosContainerComponent;
  let fixture: ComponentFixture<TodosContainerComponent>;
  let dispatchSpy: jasmine.Spy;
  let mockSelectTodos: MemoizedSelector<any, Todo[]>;
  let mockSelectRemoveDoneTodosDisabled: MemoizedSelector<any, boolean>;
  let loader: HarnessLoader;

  const getOpenFilterButton = () =>
    loader.getHarness(MatButtonHarness.with({ selector: '.todos-filter' }));

  const getFilterActiveButton = async () => {
    const menu = await loader.getHarness(MatMenuHarness);
    const items = await menu.getItems();
    return items[2];
  };

  const getTodoInput = () =>
    fixture.debugElement.query(By.css('mfework-big-input input'));

  const getTodoItems = () => fixture.debugElement.queryAll(By.css('.todo'));

  const getTodoItem = () => fixture.debugElement.query(By.css('.todo-label'));

  const getAddTodoButton = async () => {
    const buttons = await loader.getAllHarnesses(
      MatButtonHarness.with({ selector: 'mfework-big-input-action button' })
    );
    return buttons[0];
  };

  const getRemoveDoneTodosButton = async () => {
    const buttons = await loader.getAllHarnesses(
      MatButtonHarness.with({ selector: 'mfework-big-input-action button' })
    );
    return buttons[1];
  };

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [SharedModule, NoopAnimationsModule, TranslateModule.forRoot()],
      declarations: [TodosContainerComponent],
      providers: [provideMockStore()]
    });

    store = TestBed.inject(MockStore);
    mockSelectTodos = store.overrideSelector(selectTodos, []);
    mockSelectRemoveDoneTodosDisabled = store.overrideSelector(
      selectRemoveDoneTodosDisabled,
      true
    );
    fixture = TestBed.createComponent(TodosContainerComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    loader = TestbedHarnessEnvironment.loader(fixture);

    dispatchSpy = spyOn(store, 'dispatch');
  });

  it('should be created with 0 todos', () => {
    fixture.detectChanges();

    expect(component).toBeTruthy();
    expect(getTodoItems().length).toBe(0);
  });

  it('should display todos', () => {
    mockSelectTodos.setResult([{ id: '1', name: 'test', done: false }]);
    store.refreshState();
    fixture.detectChanges();

    expect(getTodoItems().length).toBe(1);
    expect(getTodoItems()[0].nativeElement.textContent.trim()).toBe('test');
  });

  it('should dispatch remove "DONE" todos action', async () => {
    mockSelectTodos.setResult([
      { id: '1', name: 'test 1', done: true },
      { id: '2', name: 'test 2', done: false }
    ]);
    mockSelectRemoveDoneTodosDisabled.setResult(false);
    store.refreshState();
    fixture.detectChanges();
    dispatchSpy.calls.reset();

    const removeDoneTodosButton = await getRemoveDoneTodosButton();
    await removeDoneTodosButton.click();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      todoActions.actionTodosRemoveDone()
    );
  });

  it('should dispatch add todo action', async () => {
    fixture.detectChanges();
    dispatchSpy.calls.reset();

    const keyUpEvent = new KeyboardEvent('keyup', {
      bubbles: true,
      cancelable: true,
      shiftKey: false
    });

    getTodoInput().nativeElement.value = 'hello world';
    getTodoInput().nativeElement.dispatchEvent(keyUpEvent);
    fixture.detectChanges();

    const addTodoButton = await getAddTodoButton();
    await addTodoButton.click();

    expect(getTodoInput().nativeElement.value).toBe('');
    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    console.log(dispatchSpy.calls.mostRecent().args[0]);
    expect(dispatchSpy.calls.mostRecent().args[0].name).toBe('hello world');
  });

  it('should dispatch filter todo action', async () => {
    dispatchSpy.calls.reset();

    const openFilterButton = await getOpenFilterButton();
    await openFilterButton.click();

    const filterActiveButton = await getFilterActiveButton();
    await filterActiveButton.click();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      todoActions.actionTodosFilter({ filter: 'ACTIVE' })
    );
  });

  it('should dispatch toggle todo action', () => {
    mockSelectTodos.setResult([{ id: '1', name: 'test 1', done: true }]);
    store.refreshState();
    fixture.detectChanges();
    dispatchSpy.calls.reset();

    getTodoItem().nativeElement.click();
    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      todoActions.actionTodosToggle({ id: '1' })
    );
  });

  it('should disable remove done todos button if no todo is done', async () => {
    fixture.detectChanges();

    const removeDoneTodosButton = await getRemoveDoneTodosButton();
    const removeDoneTodosButtonIsDisabled = await removeDoneTodosButton.isDisabled();

    expect(removeDoneTodosButtonIsDisabled).toBe(true);
  });

  it('should disable add new todo button if input length is less than 4', async () => {
    fixture.detectChanges();

    const keyUpEvent = new KeyboardEvent('keyup', {
      bubbles: true,
      cancelable: true,
      shiftKey: false
    });

    getTodoInput().nativeElement.value = 'add';
    getTodoInput().nativeElement.dispatchEvent(keyUpEvent);
    fixture.detectChanges();
    const addTodoButton = await getAddTodoButton();
    let addTodoButtonIsDisabled = await addTodoButton.isDisabled();

    expect(addTodoButtonIsDisabled).toBe(true);

    getTodoInput().nativeElement.value = 'long enough';
    getTodoInput().nativeElement.dispatchEvent(keyUpEvent);
    fixture.detectChanges();

    addTodoButtonIsDisabled = await addTodoButton.isDisabled();
    expect(addTodoButtonIsDisabled).toBe(false);
  });

  it('should clear new todo input value on ESC key press', () => {
    fixture.detectChanges();

    const keyUpEvent = new KeyboardEvent('keyup', {
      bubbles: true,
      cancelable: true,
      shiftKey: false
    });

    getTodoInput().nativeElement.value = 'hello world';
    getTodoInput().nativeElement.dispatchEvent(keyUpEvent);
    fixture.detectChanges();

    const escKeypUp = new KeyboardEvent('keyup', {
      key: 'Escape',
      bubbles: true,
      cancelable: true,
      shiftKey: false
    });
    getTodoInput().nativeElement.dispatchEvent(escKeypUp);
    fixture.detectChanges();

    expect(getTodoInput().nativeElement.value).toBe('');
  });
});
Example #4
Source File: settings-container.component.spec.ts    From enterprise-ng-2020-workshop with MIT License 4 votes vote down vote up
describe('SettingsComponent', () => {
  let component: SettingsContainerComponent;
  let fixture: ComponentFixture<SettingsContainerComponent>;
  let store: MockStore;
  let dispatchSpy;
  let mockSelectSettings: MemoizedSelector<{}, SettingsState>;

  const getThemeSelectArrow = () =>
    fixture.debugElement.queryAll(By.css('.mat-select-trigger'))[1];
  const getSelectOptions = () =>
    fixture.debugElement.queryAll(By.css('mat-option'));

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        FontAwesomeModule,
        SharedModule,
        NoopAnimationsModule,
        TranslateModule.forRoot()
      ],
      providers: [provideMockStore()],
      declarations: [SettingsContainerComponent]
    }).compileComponents();

    TestBed.inject(FaIconLibrary).addIcons(faBars);

    store = TestBed.inject(MockStore);
    mockSelectSettings = store.overrideSelector(
      selectSettings,
      {} as SettingsState
    );
    fixture = TestBed.createComponent(SettingsContainerComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should dispatch change sticky header on sticky header toggle', () => {
    dispatchSpy = spyOn(store, 'dispatch');
    const componentDebug = fixture.debugElement;
    const slider = componentDebug.queryAll(By.directive(MatSlideToggle))[0];

    slider.triggerEventHandler('change', { checked: false });
    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      actionSettingsChangeStickyHeader({ stickyHeader: false })
    );
  });

  it('should dispatch change theme action on theme selection', () => {
    dispatchSpy = spyOn(store, 'dispatch');
    getThemeSelectArrow().triggerEventHandler('click', {});

    fixture.detectChanges();

    getSelectOptions()[1].triggerEventHandler('click', {});

    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      actionSettingsChangeTheme({ theme: 'LIGHT-THEME' })
    );
  });

  it('should dispatch change auto night mode on night mode toggle', () => {
    dispatchSpy = spyOn(store, 'dispatch');
    const componentDebug = fixture.debugElement;
    const slider = componentDebug.queryAll(By.directive(MatSlideToggle))[1];

    slider.triggerEventHandler('change', { checked: false });
    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      actionSettingsChangeAutoNightMode({ autoNightMode: false })
    );
  });

  it('should dispatch change animations page', () => {
    dispatchSpy = spyOn(store, 'dispatch');
    const componentDebug = fixture.debugElement;
    const slider = componentDebug.queryAll(By.directive(MatSlideToggle))[2];

    slider.triggerEventHandler('change', { checked: false });
    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      actionSettingsChangeAnimationsPage({ pageAnimations: false })
    );
  });

  it('should dispatch change animations elements', () => {
    dispatchSpy = spyOn(store, 'dispatch');
    const componentDebug = fixture.debugElement;
    const slider = componentDebug.queryAll(By.directive(MatSlideToggle))[3];

    slider.triggerEventHandler('change', { checked: false });
    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(1);
    expect(dispatchSpy).toHaveBeenCalledWith(
      actionSettingsChangeAnimationsElements({ elementsAnimations: false })
    );
  });

  it('should disable change animations page when disabled is set in state', () => {
    mockSelectSettings.setResult({
      pageAnimationsDisabled: true
    } as SettingsState);
    store.refreshState();
    fixture.detectChanges();

    dispatchSpy = spyOn(store, 'dispatch');
    const componentDebug = fixture.debugElement;
    const slider = componentDebug.queryAll(By.directive(MatSlideToggle))[2];

    console.log(slider);
    slider.triggerEventHandler('change', { checked: false });
    fixture.detectChanges();

    expect(dispatchSpy).toHaveBeenCalledTimes(0);
  });
});