use super::*;
use expect_test::expect;
#[tokio::test]
async fn change_visibility_offers_two_alternatives_for_public_method() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_actions(
r#"<?php
class Greeter {
$0public function hello(string $name): string { return $name; }
}
"#,
)
.await;
assert!(
out.contains("Make protected"),
"expected 'Make protected' in actions, got: {out}"
);
assert!(
out.contains("Make private"),
"expected 'Make private' in actions, got: {out}"
);
assert!(
!out.contains("Make public"),
"should not offer 'Make public' when already public, got: {out}"
);
}
#[tokio::test]
async fn change_visibility_offers_two_alternatives_for_protected_method() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_actions(
r#"<?php
class Base {
$0protected function helper(): void {}
}
"#,
)
.await;
assert!(
out.contains("Make public"),
"expected 'Make public' in actions, got: {out}"
);
assert!(
out.contains("Make private"),
"expected 'Make private' in actions, got: {out}"
);
assert!(
!out.contains("Make protected"),
"should not offer 'Make protected' when already protected, got: {out}"
);
}
#[tokio::test]
async fn change_visibility_offers_two_alternatives_for_private_property() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_actions(
r#"<?php
class User {
$0private string $name = '';
}
"#,
)
.await;
assert!(
out.contains("Make public"),
"expected 'Make public' in actions, got: {out}"
);
assert!(
out.contains("Make protected"),
"expected 'Make protected' in actions, got: {out}"
);
assert!(
!out.contains("Make private"),
"should not offer 'Make private' when already private, got: {out}"
);
}
#[tokio::test]
async fn change_visibility_ignores_keyword_inside_attribute_string() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
class User {
#[Assert\Choice(choices: ["private", "public"])]
$0private string $mode = '';
}
"#,
"Make public",
)
.await;
expect![[r#"
<?php
class User {
#[Assert\Choice(choices: ["private", "public"])]
public string $mode = '';
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_no_action_inside_method_body() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_actions(
r#"<?php
class Foo {
public function bar(): void {
$x$0 = 1;
}
}
"#,
)
.await;
assert!(
!out.contains("Make public"),
"should not offer visibility change inside method body, got: {out}"
);
assert!(
!out.contains("Make protected"),
"should not offer visibility change inside method body, got: {out}"
);
assert!(
!out.contains("Make private"),
"should not offer visibility change inside method body, got: {out}"
);
}
#[tokio::test]
async fn change_visibility_public_to_protected_applies_edit() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
class Greeter {
$0public function hello(string $name): string { return $name; }
}
"#,
"Make protected",
)
.await;
expect![[r#"
<?php
class Greeter {
protected function hello(string $name): string { return $name; }
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_public_to_private_applies_edit() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
class Config {
$0public static function defaults(): array { return []; }
}
"#,
"Make private",
)
.await;
expect![[r#"
<?php
class Config {
private static function defaults(): array { return []; }
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_protected_to_public_applies_edit() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
class Service {
$0protected string $endpoint = 'https://api.example.com';
}
"#,
"Make public",
)
.await;
expect![[r#"
<?php
class Service {
public string $endpoint = 'https://api.example.com';
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_private_const_to_public() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
class Config {
$0private const VERSION = '1.0.0';
}
"#,
"Make public",
)
.await;
expect![[r#"
<?php
class Config {
public const VERSION = '1.0.0';
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_trait_method() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
trait Logger {
$0private function log(string $msg): void {}
}
"#,
"Make protected",
)
.await;
expect![[r#"
<?php
trait Logger {
protected function log(string $msg): void {}
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_abstract_method() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
abstract class Shape {
$0protected abstract function area(): float;
}
"#,
"Make public",
)
.await;
expect![[r#"
<?php
abstract class Shape {
public abstract function area(): float;
}
"#]]
.assert_eq(&out);
}
#[tokio::test]
async fn change_visibility_final_method() {
let mut s = TestServer::new().await;
s.validate_syntax(false);
let out = s
.check_code_action_apply(
r#"<?php
class Base {
$0public final function lock(): void {}
}
"#,
"Make protected",
)
.await;
expect![[r#"
<?php
class Base {
protected final function lock(): void {}
}
"#]]
.assert_eq(&out);
}