mirror of
https://github.com/google/gn-language-server.git
synced 2025-12-23 12:26:43 +00:00
Add some tests
This commit is contained in:
parent
087a41e264
commit
8767ee811d
13 changed files with 325 additions and 6 deletions
|
|
@ -1371,3 +1371,33 @@ impl Analyzer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::testutil::testdata;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_analyze_smoke() {
|
||||
let storage = Arc::new(Mutex::new(DocumentStorage::new()));
|
||||
let mut analyzer = Analyzer::new(&storage);
|
||||
|
||||
let file = analyzer
|
||||
.analyze(&testdata("workspaces/smoke/BUILD.gn"))
|
||||
.unwrap();
|
||||
|
||||
// No parse error.
|
||||
assert!(file
|
||||
.ast_root
|
||||
.statements
|
||||
.iter()
|
||||
.all(|s| !matches!(s, Statement::Unknown(_) | Statement::UnmatchedBrace(_))));
|
||||
|
||||
// Inspect the top-level scope.
|
||||
let scope = file.scope_at(0);
|
||||
assert!(scope.get("enable_opt").is_some());
|
||||
assert!(scope.get("_lib").is_some());
|
||||
assert!(scope.get("is_linux").is_some());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
52
src/client.rs
Normal file
52
src/client.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// 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.
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use serde_json::Value;
|
||||
use tower_lsp::lsp_types::{ConfigurationItem, MessageType};
|
||||
|
||||
use crate::providers::RpcResult;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TestableClient {
|
||||
client: Option<tower_lsp::Client>,
|
||||
}
|
||||
|
||||
impl TestableClient {
|
||||
pub fn new(client: tower_lsp::Client) -> Self {
|
||||
Self {
|
||||
client: Some(client),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn new_for_testing() -> Self {
|
||||
Self { client: None }
|
||||
}
|
||||
|
||||
pub async fn log_message<M: Display>(&self, typ: MessageType, message: M) {
|
||||
if let Some(client) = &self.client {
|
||||
client.log_message(typ, message).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn configuration(&self, items: Vec<ConfigurationItem>) -> RpcResult<Vec<Value>> {
|
||||
if let Some(client) = &self.client {
|
||||
client.configuration(items).await
|
||||
} else {
|
||||
Ok(Vec::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,10 +15,12 @@
|
|||
mod analyze;
|
||||
mod ast;
|
||||
mod builtins;
|
||||
mod client;
|
||||
mod config;
|
||||
mod providers;
|
||||
mod server;
|
||||
mod storage;
|
||||
mod testutil;
|
||||
mod util;
|
||||
|
||||
#[tokio::main]
|
||||
|
|
|
|||
|
|
@ -172,3 +172,57 @@ pub async fn hover(context: &ProviderContext, params: HoverParams) -> RpcResult<
|
|||
range: Some(current_file.document.line_index.range(ident.span)),
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tower_lsp::lsp_types::{
|
||||
Position, Range, TextDocumentIdentifier, TextDocumentPositionParams, WorkDoneProgressParams,
|
||||
};
|
||||
|
||||
use crate::testutil::testdata;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_hover() {
|
||||
let uri = Url::from_file_path(testdata("workspaces/hover/BUILD.gn")).unwrap();
|
||||
let params = HoverParams {
|
||||
text_document_position_params: TextDocumentPositionParams {
|
||||
text_document: TextDocumentIdentifier { uri: uri.clone() },
|
||||
position: Position {
|
||||
line: 17,
|
||||
character: 0,
|
||||
},
|
||||
},
|
||||
work_done_progress_params: WorkDoneProgressParams::default(),
|
||||
};
|
||||
|
||||
let response = hover(&ProviderContext::new_for_testing(), params)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
response,
|
||||
Some(Hover {
|
||||
contents: HoverContents::Array(vec",
|
||||
uri
|
||||
)),
|
||||
]),
|
||||
range: Some(Range {
|
||||
start: Position {
|
||||
line: 17,
|
||||
character: 0,
|
||||
},
|
||||
end: Position {
|
||||
line: 17,
|
||||
character: 1,
|
||||
},
|
||||
}),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@ use std::{
|
|||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use tower_lsp::{lsp_types::Position, Client};
|
||||
use tower_lsp::lsp_types::Position;
|
||||
|
||||
use crate::{
|
||||
analyze::{AnalyzedFile, Analyzer},
|
||||
ast::{Identifier, Node},
|
||||
client::TestableClient,
|
||||
storage::DocumentStorage,
|
||||
};
|
||||
|
||||
|
|
@ -39,7 +40,20 @@ pub type RpcResult<T> = tower_lsp::jsonrpc::Result<T>;
|
|||
pub struct ProviderContext {
|
||||
pub storage: Arc<Mutex<DocumentStorage>>,
|
||||
pub analyzer: Arc<Mutex<Analyzer>>,
|
||||
pub client: Client,
|
||||
pub client: TestableClient,
|
||||
}
|
||||
|
||||
impl ProviderContext {
|
||||
#[cfg(test)]
|
||||
pub fn new_for_testing() -> Self {
|
||||
let storage = Arc::new(Mutex::new(DocumentStorage::new()));
|
||||
let analyzer = Arc::new(Mutex::new(Analyzer::new(&storage)));
|
||||
Self {
|
||||
storage,
|
||||
analyzer,
|
||||
client: TestableClient::new_for_testing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_rpc_error(err: std::io::Error) -> tower_lsp::jsonrpc::Error {
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@ use tower_lsp::{
|
|||
HoverProviderCapability, InitializeParams, InitializeResult, InitializedParams,
|
||||
MessageType, OneOf, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind,
|
||||
},
|
||||
Client, LanguageServer, LspService, Server,
|
||||
LanguageServer, LspService, Server,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
analyze::{find_workspace_root, Analyzer},
|
||||
client::TestableClient,
|
||||
config::Configurations,
|
||||
providers::{ProviderContext, RpcResult},
|
||||
storage::DocumentStorage,
|
||||
|
|
@ -48,7 +49,7 @@ impl Backend {
|
|||
pub fn new(
|
||||
storage: &Arc<Mutex<DocumentStorage>>,
|
||||
analyzer: &Arc<Mutex<Analyzer>>,
|
||||
client: Client,
|
||||
client: TestableClient,
|
||||
) -> Self {
|
||||
Self {
|
||||
context: ProviderContext {
|
||||
|
|
@ -180,8 +181,9 @@ impl LanguageServer for Backend {
|
|||
pub async fn run() {
|
||||
let storage = Arc::new(Mutex::new(DocumentStorage::new()));
|
||||
let analyzer = Arc::new(Mutex::new(Analyzer::new(&storage)));
|
||||
let (service, socket) =
|
||||
LspService::new(move |client| Backend::new(&storage, &analyzer, client));
|
||||
let (service, socket) = LspService::new(move |client| {
|
||||
Backend::new(&storage, &analyzer, TestableClient::new(client))
|
||||
});
|
||||
|
||||
let stdin = tokio::io::stdin();
|
||||
let stdout = tokio::io::stdout();
|
||||
|
|
|
|||
24
src/testutil.rs
Normal file
24
src/testutil.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// 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.
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn testdata(name: impl AsRef<Path>) -> PathBuf {
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
path.push("testdata");
|
||||
path.push(name.as_ref());
|
||||
path
|
||||
}
|
||||
15
testdata/workspaces/hover/.gn
vendored
Normal file
15
testdata/workspaces/hover/.gn
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
buildconfig = "//BUILDCONFIG.gn"
|
||||
36
testdata/workspaces/hover/BUILD.gn
vendored
Normal file
36
testdata/workspaces/hover/BUILD.gn
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Avoid attaching the copyright comment to the first assignment.
|
||||
start = true
|
||||
|
||||
a = 1
|
||||
|
||||
b = 1
|
||||
b = 2
|
||||
b = 3
|
||||
|
||||
template("foo") {
|
||||
}
|
||||
|
||||
if (true) {
|
||||
template("bar") {
|
||||
}
|
||||
} else {
|
||||
template("bar") {
|
||||
}
|
||||
}
|
||||
|
||||
foo("foo")
|
||||
bar("bar")
|
||||
13
testdata/workspaces/hover/BUILDCONFIG.gn
vendored
Normal file
13
testdata/workspaces/hover/BUILDCONFIG.gn
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
15
testdata/workspaces/smoke/.gn
vendored
Normal file
15
testdata/workspaces/smoke/.gn
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
buildconfig = "//BUILDCONFIG.gn"
|
||||
47
testdata/workspaces/smoke/BUILD.gn
vendored
Normal file
47
testdata/workspaces/smoke/BUILD.gn
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
declare_args() {
|
||||
enable_opt = false
|
||||
}
|
||||
|
||||
static_library("lib") {
|
||||
sources = [ "lib.cc" ]
|
||||
opt = enable_opt
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
static_library("lib_linux") {
|
||||
sources = [ "lib_linux.cc" ]
|
||||
opt = enable_opt
|
||||
}
|
||||
_lib = ":lib_linux"
|
||||
} else if (is_win) {
|
||||
static_library("lib_win") {
|
||||
sources = [ "lib_win.cc" ]
|
||||
opt = enable_opt
|
||||
}
|
||||
_lib = ":lib_win"
|
||||
} else {
|
||||
assert(false, "Unsupported platform")
|
||||
}
|
||||
|
||||
executable("main") {
|
||||
sources = [ "main.cc" ]
|
||||
deps = [
|
||||
":lib",
|
||||
_lib,
|
||||
]
|
||||
opt = enable_opt
|
||||
}
|
||||
15
testdata/workspaces/smoke/BUILDCONFIG.gn
vendored
Normal file
15
testdata/workspaces/smoke/BUILDCONFIG.gn
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
is_linux = current_os == "linux"
|
||||
Loading…
Add table
Add a link
Reference in a new issue