mirror of
https://github.com/CompeyDev/lune-packaging.git
synced 2025-01-09 20:29:10 +00:00
Add unit tests for isa functions
This commit is contained in:
parent
0f4c36219f
commit
cda2d46ed9
3 changed files with 109 additions and 67 deletions
|
@ -2,7 +2,7 @@ use std::path::Path;
|
||||||
|
|
||||||
use rbx_dom_weak::WeakDom;
|
use rbx_dom_weak::WeakDom;
|
||||||
|
|
||||||
use crate::instance::instance_is_a_service;
|
use crate::instance::util::instance_is_a_service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A document kind specifier.
|
A document kind specifier.
|
||||||
|
|
|
@ -1,66 +1 @@
|
||||||
use std::borrow::Borrow;
|
pub mod util;
|
||||||
|
|
||||||
use rbx_reflection::ClassTag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if an instance class matches a given class or superclass, similar to
|
|
||||||
[Instance::IsA](https://create.roblox.com/docs/reference/engine/classes/Instance#IsA)
|
|
||||||
from the Roblox standard library.
|
|
||||||
|
|
||||||
Note that this function may return `None` if it encounters a class or superclass
|
|
||||||
that does not exist in the currently known class reflection database.
|
|
||||||
*/
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn instance_is_a(
|
|
||||||
instance_class_name: impl AsRef<str>,
|
|
||||||
class_name: impl AsRef<str>,
|
|
||||||
) -> Option<bool> {
|
|
||||||
let instance_class_name = instance_class_name.as_ref();
|
|
||||||
let class_name = class_name.as_ref();
|
|
||||||
|
|
||||||
if class_name == "Instance" || instance_class_name == class_name {
|
|
||||||
Some(true)
|
|
||||||
} else {
|
|
||||||
let db = rbx_reflection_database::get();
|
|
||||||
|
|
||||||
let mut super_class_name = instance_class_name;
|
|
||||||
while super_class_name != class_name {
|
|
||||||
let class_descriptor = db.classes.get(super_class_name)?;
|
|
||||||
if let Some(sup) = &class_descriptor.superclass {
|
|
||||||
super_class_name = sup.borrow();
|
|
||||||
} else {
|
|
||||||
return Some(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Checks if an instance class is a service.
|
|
||||||
|
|
||||||
This is separate from [`instance_is_a`] since services do not share a
|
|
||||||
common base class, and are instead determined through reflection tags.
|
|
||||||
|
|
||||||
Note that this function may return `None` if it encounters a class or superclass
|
|
||||||
that does not exist in the currently known class reflection database.
|
|
||||||
*/
|
|
||||||
pub fn instance_is_a_service(class_name: impl AsRef<str>) -> Option<bool> {
|
|
||||||
let mut class_name = class_name.as_ref();
|
|
||||||
|
|
||||||
let db = rbx_reflection_database::get();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let class_descriptor = db.classes.get(class_name)?;
|
|
||||||
if class_descriptor.tags.contains(&ClassTag::Service) {
|
|
||||||
return Some(true);
|
|
||||||
} else if let Some(sup) = &class_descriptor.superclass {
|
|
||||||
class_name = sup.borrow();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(false)
|
|
||||||
}
|
|
||||||
|
|
107
packages/lib-roblox/src/instance/util.rs
Normal file
107
packages/lib-roblox/src/instance/util.rs
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
|
use rbx_reflection::ClassTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if an instance class matches a given class or superclass, similar to
|
||||||
|
[Instance::IsA](https://create.roblox.com/docs/reference/engine/classes/Instance#IsA)
|
||||||
|
from the Roblox standard library.
|
||||||
|
|
||||||
|
Note that this function may return `None` if it encounters a class or superclass
|
||||||
|
that does not exist in the currently known class reflection database.
|
||||||
|
*/
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn instance_is_a(instance_class: impl AsRef<str>, class_name: impl AsRef<str>) -> Option<bool> {
|
||||||
|
let mut instance_class = instance_class.as_ref();
|
||||||
|
let class_name = class_name.as_ref();
|
||||||
|
|
||||||
|
if class_name == "Instance" || instance_class == class_name {
|
||||||
|
Some(true)
|
||||||
|
} else {
|
||||||
|
let db = rbx_reflection_database::get();
|
||||||
|
|
||||||
|
while instance_class != class_name {
|
||||||
|
let class_descriptor = db.classes.get(instance_class)?;
|
||||||
|
if let Some(sup) = &class_descriptor.superclass {
|
||||||
|
instance_class = sup.borrow();
|
||||||
|
} else {
|
||||||
|
return Some(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if an instance class is a service.
|
||||||
|
|
||||||
|
This is separate from [`instance_is_a`] since services do not share a
|
||||||
|
common base class, and are instead determined through reflection tags.
|
||||||
|
|
||||||
|
Note that this function may return `None` if it encounters a class or superclass
|
||||||
|
that does not exist in the currently known class reflection database.
|
||||||
|
*/
|
||||||
|
pub fn instance_is_a_service(instance_class: impl AsRef<str>) -> Option<bool> {
|
||||||
|
let mut instance_class = instance_class.as_ref();
|
||||||
|
|
||||||
|
let db = rbx_reflection_database::get();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let class_descriptor = db.classes.get(instance_class)?;
|
||||||
|
if class_descriptor.tags.contains(&ClassTag::Service) {
|
||||||
|
return Some(true);
|
||||||
|
} else if let Some(sup) = &class_descriptor.superclass {
|
||||||
|
instance_class = sup.borrow();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_a_class_valid() {
|
||||||
|
assert_eq!(instance_is_a("Part", "Part"), Some(true));
|
||||||
|
assert_eq!(instance_is_a("Part", "BasePart"), Some(true));
|
||||||
|
assert_eq!(instance_is_a("Part", "PVInstance"), Some(true));
|
||||||
|
assert_eq!(instance_is_a("Part", "Instance"), Some(true));
|
||||||
|
|
||||||
|
assert_eq!(instance_is_a("Workspace", "Workspace"), Some(true));
|
||||||
|
assert_eq!(instance_is_a("Workspace", "Model"), Some(true));
|
||||||
|
assert_eq!(instance_is_a("Workspace", "Instance"), Some(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_a_class_invalid() {
|
||||||
|
assert_eq!(instance_is_a("Part", "part"), Some(false));
|
||||||
|
assert_eq!(instance_is_a("Part", "Base-Part"), Some(false));
|
||||||
|
assert_eq!(instance_is_a("Part", "Model"), Some(false));
|
||||||
|
assert_eq!(instance_is_a("Part", "Paart"), Some(false));
|
||||||
|
|
||||||
|
assert_eq!(instance_is_a("Workspace", "Service"), Some(false));
|
||||||
|
assert_eq!(instance_is_a("Workspace", "."), Some(false));
|
||||||
|
assert_eq!(instance_is_a("Workspace", ""), Some(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_a_service_valid() {
|
||||||
|
assert_eq!(instance_is_a_service("Workspace"), Some(true));
|
||||||
|
assert_eq!(instance_is_a_service("PhysicsService"), Some(true));
|
||||||
|
assert_eq!(instance_is_a_service("ReplicatedFirst"), Some(true));
|
||||||
|
assert_eq!(instance_is_a_service("CSGDictionaryService"), Some(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_a_service_invalid() {
|
||||||
|
assert_eq!(instance_is_a_service("Camera"), Some(false));
|
||||||
|
assert_eq!(instance_is_a_service("Terrain"), Some(false));
|
||||||
|
assert_eq!(instance_is_a_service("Work-space"), Some(false));
|
||||||
|
assert_eq!(instance_is_a_service("CSG Dictionary Service"), Some(false));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue