// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed 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.
package com.google.collide.client.codeunderstanding;
import static com.google.collide.client.codeunderstanding.CodeGraphTestUtils.MockApi;
import static com.google.collide.client.codeunderstanding.CodeGraphTestUtils.createCodeBlock;
import static com.google.collide.client.codeunderstanding.CodeGraphTestUtils.createCodeGraph;
import static com.google.collide.client.codeunderstanding.CodeGraphTestUtils.createFreshness;
import com.google.collide.client.codeunderstanding.CodeGraphTestUtils.MockCubeClientDistributor;
import com.google.collide.client.communication.FrontendApi;
import com.google.collide.dto.CodeBlock;
import com.google.collide.dto.CodeGraphResponse;
import com.google.collide.dto.client.DtoClientImpls.CodeGraphResponseImpl;
import com.google.collide.dto.client.DtoClientImpls.MockCodeGraphResponseImpl;
import com.google.collide.json.client.Jso;
import com.google.gwt.junit.client.GWTTestCase;
/**
* A test case for {@link CubeState}.
*/
public class CubeStateTest extends GWTTestCase {
@Override
public String getModuleName() {
return "com.google.collide.client.TestCode";
}
/**
* Tests that {@link CubeState} fires update notification when it receives
* data which is more fresh than stored one.
*/
public void testFreshDataMakesUpdate() {
CodeGraphResponseImpl response = MockCodeGraphResponseImpl.make();
response.setFreshness(createFreshness("1", "0", "0"));
response.setLibsSubgraphJson(Jso.serialize(createCodeGraph(
createCodeBlock("0", "/foo.js", CodeBlock.Type.FILE, 0, 0, 1, 0))));
final MockApi api = new MockApi();
MockCubeClientDistributor distributor = new MockCubeClientDistributor();
CubeState state = new CubeState(api, distributor);
state.setFilePath("");
state.refresh();
assertEquals("no notifications after request", 0, distributor.collectedNotifications.size());
assertEquals("refresh causes one api request", 1, api.collectedCallbacks.size());
FrontendApi.ApiCallback<CodeGraphResponse> callback = api.collectedCallbacks.get(0);
assertNotNull("state pushes non null callback", callback);
callback.onMessageReceived(response);
assertEquals("just one notification on response", 1, distributor.collectedNotifications.size());
CubeDataUpdates freshness = distributor.collectedNotifications.get(0);
assertTrue("updated libs subgraph", freshness.isLibsSubgraph());
assertNotNull("has libs subgraph", state.getData().getLibsSubgraph());
assertFalse("old file tree", freshness.isFileTree());
assertFalse("old full graph", freshness.isFullGraph());
assertFalse("old workspace tree", freshness.isWorkspaceTree());
}
/**
* Tests that consequent refresh requests for the same data are collapsed to
* just one frontend request.
*/
public void testRefreshCollapsing() {
final MockApi api = new MockApi();
MockCubeClientDistributor distributor = new MockCubeClientDistributor();
CubeState state = new CubeState(api, distributor);
state.setFilePath("a.js");
state.refresh();
state.refresh();
assertEquals(1, api.collectedCallbacks.size());
}
/**
* Tests that consequent refresh requests for different data are served
* sequentially.
*/
public void testRefreshSequencing() {
CodeGraphResponseImpl response = MockCodeGraphResponseImpl.make();
response.setFreshness(createFreshness("1", "1", "1"));
final MockApi api = new MockApi();
MockCubeClientDistributor distributor = new MockCubeClientDistributor();
CubeState state = new CubeState(api, distributor);
state.setFilePath("a.js");
state.refresh();
state.setFilePath("b.js");
state.refresh();
assertEquals("one request after two refreshes", 1, api.collectedCallbacks.size());
FrontendApi.ApiCallback<CodeGraphResponse> callback = api.collectedCallbacks.get(0);
callback.onMessageReceived(response);
assertEquals("second request comes after first response", 2, api.collectedCallbacks.size());
}
/**
* Tests that consequent refresh requests for different data do not cause
* frontend request for data that is not required anymore.
*/
public void testRefreshSequencingAndCollapsing() {
CodeGraphResponseImpl response = MockCodeGraphResponseImpl.make();
response.setFreshness(createFreshness("1", "1", "1"));
final MockApi api = new MockApi();
MockCubeClientDistributor distributor = new MockCubeClientDistributor();
CubeState state = new CubeState(api, distributor);
state.setFilePath("a.js");
state.refresh();
state.setFilePath("b.js");
state.refresh();
state.setFilePath("c.js");
state.refresh();
assertEquals("first request is served immediately", 1, api.collectedCallbacks.size());
FrontendApi.ApiCallback<CodeGraphResponse> callback = api.collectedCallbacks.get(0);
callback.onMessageReceived(response);
assertEquals("second request is served after first response", 2, api.collectedCallbacks.size());
callback = api.collectedCallbacks.get(1);
callback.onMessageReceived(response);
assertEquals("no more requests after second response", 2, api.collectedCallbacks.size());
}
/**
* Tests that update notifications bring {@code false} for updates that
* doesn't bring fresh data.
*/
public void testStaleDataMakesNoUpdates() {
CodeGraphResponseImpl response = MockCodeGraphResponseImpl.make();
response.setFreshness(createFreshness("0", "0", "0"));
response.setLibsSubgraphJson(Jso.serialize(createCodeGraph(
createCodeBlock("0", "/foo.js", CodeBlock.Type.FILE, 0, 0, 1, 0))));
final MockApi api = new MockApi();
MockCubeClientDistributor distributor = new MockCubeClientDistributor();
CubeState state = new CubeState(api, distributor);
state.setFilePath("");
state.refresh();
assertEquals("no updates before response", 0, distributor.collectedNotifications.size());
assertEquals("one request for processing", 1, api.collectedCallbacks.size());
FrontendApi.ApiCallback<CodeGraphResponse> callback = api.collectedCallbacks.get(0);
assertNotNull("non null callback", callback);
callback.onMessageReceived(response);
assertEquals("one notification after response", 1, distributor.collectedNotifications.size());
CubeDataUpdates freshness = distributor.collectedNotifications.get(0);
assertFalse("old libs subgraph", freshness.isLibsSubgraph());
assertFalse("old file tree", freshness.isFileTree());
assertFalse("old full graph", freshness.isFullGraph());
assertFalse("old workspace tree", freshness.isWorkspaceTree());
assertNull("no libs subgraph", state.getData().getLibsSubgraph());
}
}