/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/
import {async, ComponentFixture, TestBed} from '@angular/core/testing';

import { AppModule } from '../../../../app.module';
import {PrStep4Component} from './step4.component';
import { ProfilingStep1, ProfilingStep2, ProfilingStep3, ProfilingStep4 } from '../pr.component';

describe('PrStep4Component', () => {
  let component: PrStep4Component;
  let fixture: ComponentFixture<PrStep4Component>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ AppModule ],
      declarations: [],
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(PrStep4Component);
    component = fixture.componentInstance;
    component.step1 = new ProfilingStep1();
    component.step2 = new ProfilingStep2();
    component.step3 = new ProfilingStep3();
    component.step4 = new ProfilingStep4();
    fixture.detectChanges();
  });

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